Understanding document packages (Xcode/iOS)

Open Finder on OS X, navigate to a Pages file and right-click. You'll be given the option to 'Show Package Contents' and clicking this will allow you to navigate the contents as if it were a folder.   

Now go to a folder, it doesn't matter which one. Change its name to add the extension .pages and instantly you'll see that it gains the Pages file icon. Pages won't be able to open this file, but it thinks it will.

Next change the extension from .pages to .numbers and again you'll see the same behaviour but with a different icon. Right-click and as in the original example you'll be given the option to 'Show Package Contents'. Do this and all works as expected.

Uniform type identifier (UTI)

The above example works because document packages are simply folders. It is just that the apps that use document packages as their format register something called a uniform type identifier (UTI) in order for the system to recognise them and make them appear like single files.

Matt Neuburg shows the process of registering a custom UTI in Figure 23-6 of his book, Programming iOS 7, but there is an additional step if you are using a package rather than a single file with a custom UTI.

Difference between a single file and a package

Returning to the example of changing a random folder's name. If you change the folder name to give it the extension .xml,  it remains a folder in appearance. But if you change a random file extension to .xml its icon's appearance will change to conform to the .xml standard icon for your system (depending on which is your default app for opening XML files).

Approaching it the other way, though, you can change a single file's extension to .numbers or .pages and see it transform. The reason for this is because you specifically need to let the system know through the UTI that the custom format accepts a file package.

Enabling the system to see you folder as a document package

The additional step to enable the system to see your folder as a document package is outlined in Apple's guide for creating document packages. This is done by including the LSTypeIsPackage key and setting it to yes in your application's Info.plist file.

This is a rather disconcerting step because there is no auto-complete for this option when you try and add it to the 'Additional document type properties' under Info > Document Types. So either you need to be brave, or go to the Supporting Files folder and open <App Name>-info.plist and look under Document types. Here you will see your UTI and you can add the key 'Document is a package or bundle' item by right-clicking. After which you'll need to fill the value as YES.

Once you've added the key in the Supporting Files plist, you'll then see the more cryptic LSTypeIsPackage key appear automatically in 'Additional document type properties'  under the main application Info>Document Types for your UTI.

Next step in working with document packages

Once you've set up your UTI, the next step is to get to grips with NSFileWrapper. This is something that Neuburg unfortunately only mentions in passing but which is of major importance to a document-based app. Examples of NSFileWrapper can be found in Apple's Document-based App Programming Guide.

The trick being when you use UIDocument (which you are most likely to do with a file wrapper) you initWithFileURL: by pointing to a folder path inside the main Documents folder rather than pointing to a file path (as you would with a flat file).

Further reading

Uniform Type Identifiers Overview (Apple)

File System Programming Guide (Apple)

Information Property List Key Reference (Apple)

URL Loading System Programming Guide (Apple)

Endorse on Coderwall