'registerForDraggedTypes:' Audio Only

I am trying to write a small Cocoa application. It involves an NSView in which I want the user to be able to drag audio files (from, for example, the Finder). However, I do not know how to allow only audio files to be dropped into the NSView.

I managed to get this far, thinking this would work:

- (id)initWithCoder:(NSCoder *)coder
{
    self=[super initWithCoder:coder];
    if ( self ) {
        NSString *myType = (__bridge NSString *)(UTTypeCreatePreferredIdentifierForTag(kUTTagClassNSPboardType, kUTTypeAudio, NULL));
        [self registerForDraggedTypes: [NSArray arrayWithObject:myType]];
    }
    return self;
}

The above code seems to not allow any files to be dropped into the NSView. I assume this is because myType is not valid for use with registerForDraggedTypes.

Any help you can provide would be much appreciated. Thanks in advance.

Answers


Registering for a type such as kUTTypeAudio does not register for dragged files; it registers for dragged audio. It might work for accepting audio of any type* dragged in from another application, but will not work for accepting files.

You will need to register for type kUTTypeFileURL. Once you do that, any file that the user drags in will light up your drag-destination methods. There is no way to say at this stage “I want files, but only some kinds of files”.

As a drag destination, you need to validate the drag (in draggingEntered:). This is where you test whether any of the files are or are not an audio file. You have your choice of three approaches:

  • Use the Metadata framework to get each file's content type. Expect this to fail for any file on a volume that doesn't have a Spotlight index.
  • Use Launch Services to determine what content type corresponds to a given filename extension. Will fail for any file that doesn't have a filename extension; should work as long as no filename extensions are ambiguous (not a problem for audio, AFAIK, but can be a problem for certain extensions such as “dat”).
  • Attempt to interpret each file using your underlying audio API/library, and see whether it succeeds.

If you obtain a content type (UTI) for one of the files, you'll then have to see whether it's one of the types you can handle.

  • If you're just playing the audio using NSSound, use [NSSound soundUnfilteredTypes]. This returns an array of UTIs, so you're done; you can simply compare incoming UTIs to the ones in this array (using UTTypeEqual).
  • If you're using Audio File Services (or the next higher-level API, ExtAudioFile) to read each file, use AudioFileGetGlobalInfo to get the list of type codes, then use UTTypeCreatePreferredIdentifierForTag to convert each one from an OSType to a UTI.
  • If you're using some other library, you'll just have to see what that offers for assessing what types it supports.

*If and only if incoming types are checked for conformance to any of your registered types rather than equality. If they are strictly tested for equality to your registered types, you will need to register for the specific audio types you can handle.


Need Your Help

Number of threads in a block

cuda

I used x & y for calculating cells of a matrix in device.

C# execute code on other thread

c# wpf multithreading unity3d

I have some trouble with threading in my application. I have a multi-threaded client/server application. I'm also using C# MonoDevelop for Unity3d. Not sure if it makes any difference for the answer.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.