Sandboxing and Declaring Related File Types

When I researched what caused TableFlip to lose permissions to write out files, I learned about “related items” in the Sandbox.

A good example from the docs is to open a movie file plus its subtitle captions together. The user would select the movie in an NSOpenPanel. This usually grants access to the movie file directly per Sandboxing restrictions. You can declare the subtitles file to be a related item so that the Sandbox allows you to read both. That’s clever.

The implementation of item-relatedness is to add NSIsRelatedItemType with the value YES to the related file (e.g. the subtitles) movie document type and caption document type in your app’s Info.plist.

  • You can add it in the app target’s “Info” tab under the document type’s “Additional document type properties” list, or manually.
  • To add it manually, you have to go to the app’s Info.plist, expand the CFBundleDocumentTypes (“Document Types”) array, expand your items (each is a dictionary), and add the key right there. As of Xcode 11.3, I had to close and re-open the project to have the document type changes be reflected in the app target’s “Info” tab.

This didn’t help in my situation with TableFlip, though, where plain text (.txt) and Markdown (.md) were confused. Marking them as “related” is not a proper way to address this problem, because one does not supplement the other. Of course I tried, and the underlying error, “could not get a sandbox extension”, went away once I added NSIsRelatedItemType to the “Markdown” document type and left the plain text one as-is. That doesn’t make much sense in terms of related-ness, though, and the result were appropriately confusing: while the error went away, the app would now have permission to change the file extension from .txt to .md. But I don’t want the extension to change, so this didn’t address the real problem.

The App Sandbox Design Guide documentation talks about two scenarios where related items make sense. One is the movie + subtitles scenario I already mentioned. The other is when the app needs to “save a file with a different extension than that of the original file.” Their example is when you start with an RTF, insert an image, and now need an RTFD. To handle this case, you both need to specify the relation so you have write access to .rtfd as well, and rename the file properly. This is similar to the result in TableFlip after I added the NSIsRelatedItemType flag, and the rename action is addresses in a proper way, but remember I don’t want the rename to happen in the first place.

I didn’t find a lot of info on the web about this, so there you go, I documented the process for you.