Dropping files on apps (Mac)

When you write an application, sometimes you want the application to open with one or more files. There’s the ubiquitous double-click to open with the default application, there’s the right-click and use the open with a specific application option.

So on the Mac, to support dragging-and-dropping onto the application icon, you need to declare that the app supports having that file type dropped upon it. So you go to the application file types, and add support for your file type. This will add something like the following to your application plist:

<key>CFBundleDocumentTypes</key>
<array>
	<dict>
		<key>CFBundleTypeName</key>
		<string>All Items</string>
		<key>CFBundleTypeRole</key>
		<string>Viewer</string>
		<key>LSHandlerRank</key>
		<string>Alternate</string>
		<key>LSItemContentTypes</key>
		<array>
			<string>public.content</string>
		</array>
		<key>NSDocumentClass</key>
		<string>NSDocument</string>
	</dict>
</array>

With this, when you drag-and-drop a file onto your application, the application will receive a message saying the file has been dropped on your application. We limit this to files, by specifying the content type as public.content. If you wanted to accept any file-system based things, you would specify public.item. There is an inventory of the publicly declared types on the apple website.

To handle this, in objective C, you would add an openFile AppDelegate method, which would receive the name of the file, and allow you to process it – for example:

- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
    NSLog(@"%@", filename);
    return YES;
}

In this case, all the code does is display the name of the file in the log, and state that the event has been handled.

This code can be seen on GitHub – this is tag v1.0 of the program. I’ll be adding more functionality in later posts.