objective-cmacossandboxnsfilecoordinator

OSX related file creation


I'm trying to build an application that easily converts from one file format to another. The idea is you drag the source file onto the dock tile and the output file is created alongside the source file (in the same directory.)

After reading the documentation, I have everything setup correctly -- I think... but it doesn't work.

My Info.plist contains the following:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeExtensions</key>
        <array>
            my_src_type
        </array>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        [...]
    </dict>
    <dict>
        <key>CFBundleTypeExtensions</key>
        <array>
            my_dest_type
        </array>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>NSIsRelatedItemType</key>
        <true/>
        [...]
    </dict>
</array>

If I'm reading the documentation correctly, this should allow my app to accept files of my_src_type via drag and drop and output files of my_dest_type in the same directory as the input file, provided of course that I let the sandbox know about it.

To that end, I have a SimpleFilePresenter that looks like this:

 @interface SimpleFilePresenter : NSObject<NSFilePresenter>
 @property (atomic, strong) NSURL *presentedItemURL;
 @property (atomic, strong) NSURL *primaryPresentedItemURL;
 @end

 @implementation SimpleFilePresenter
 - (NSOperationQueue *)presentedItemOperationQueue {
         return [NSOperationQueue mainQueue];
 }
 @end

As soon as I use addFilePresenter: to request permission to create my output file, I get the following error in the Console.

2013-04-26 6:33:52.741 PM my_app[27639]: NSFileSandboxingRequestRelatedItemExtension: an error was received from pboxd instead of a token. Domain: NSPOSIXErrorDomain, code: 1
2013-04-26 6:33:52.741 PM my_app[27639]: +[NSFileCoordinator addFilePresenter:] could not get a sandbox extension. primaryPresentedItemURL: file://[...]/file.my_src_type, presentedItemURL: file://[...]/file.my_dest_type

Solution

  • Turns out addFilePresenter: is not synchronous or instantaneous. All I had to do was call [NSFileCoordinator filePresenters] after addFilePresenter: which seems to have the effect of blocking until all file presenters are ready to go.

    Also, I'm using Qt, so I was pleasantly surprised that this all works without needing to get specially created NSURL objects from the more scary looking NSFileCoordinator methods.