This article originally appeared in TidBITS on 2010-07-15 at 10:31 a.m.
The permanent URL for this article is: http://tidbits.com/article/11430
Include images: Off

Apps and Docs in iOS

by Matt Neuburg

The Macintosh has always had a notion of documents associated with an application. Double-click a document's icon in the Finder and the associated application launches and opens that document. This mechanism has had its ups and downs over the years, becoming sometimes more sophisticated, sometimes more crude (see "Snow Leopard Snubs Document Creator Codes [1]," 6 September 2009). But at least it's easy and it generally works.

Starting with iOS 3.2, the iPad (and now, with iOS 4.0, the iPhone and iPod touch) has had a mechanism for associating document types with apps. But the two are scarcely comparable: the Macintosh mechanism is like a rocket ship, and the iPhone mechanism is like one of those jalopies that flaps its wings and crashes into a barn in the silent movies.

Under iOS, there is no Finder, and there's no file system visible to the user (the normal user, at least, who hasn't jailbroken the device). So it's up to individual apps that handle documents to offer the user the option of opening a document in some other app. Most iOS apps don't deal with specific document types, or if they do, they don't choose to offer this option; so that's the end of that.

If an app does want to offer the user such an option (as does, for example, Safari or Mail), it calls the system to perform a limited range of actions. The system can present a preview of the document; it can present an Options dialog; or it can present an Open In dialog. These amount to pretty much the same thing, ultimately. For example, the Options dialog is likely to offer one choice of app in which to open the document, along with an option to present the Open In dialog. In the end, therefore, it comes down to the Open In dialog, which is a list of apps that can open the document in question. The user either taps a name in the list or taps Cancel to dismiss the dialog without doing anything.

[image link] [2]

Note that the app is not presenting the Open In dialog and knows nothing of its contents. The dialog belongs to the system. The app has no way of querying the system to learn what other apps can open a document of a certain type. This would appear to be an instance of the iOS's "sandboxing" policy: apps run in a strictly delimited space, and are not allowed to tread on, or even know about, one another's territory.

(As usual, though, Apple's own apps can be privy to system information that other apps can't obtain. This must be the case with Mobile Safari, because it doesn't present the Open In dialog; it uses its own interface, and that wouldn't be possible if it didn't have some way to query the system as to what apps can open a given file.)

[image link] [3]

For the same sandboxing reason, there isn't any central document repository in which an app can look to find a document. You won't find an iOS app with a standard Open dialog, because there are no standard Open dialogs in the iOS; there is no built-in provision for perusing the file system as a whole. An app can keep documents within its own sandboxed file system, and can present its own custom interface for perusing that file system; but it can't see outside its sandbox.

That being so, how can one app open a document that currently lives in another app's sandbox, in response to the Open In dialog? It's all up to the system. Just as apps can't see which other apps can open a document of a certain type, but the system can, so too an app can't move a document from its own sandbox into another app's sandbox, but the system can. If, in the system's Open In dialog, the user elects to open the document with a second app, the system takes charge. It places the document in the second app's Inbox folder, which is inside the second app's sandbox. Then it launches or foregrounds the second app and sends it a message asking it to open that document in its new location.

How does the system know which apps can open a certain type of document? That, at least, is similar to Mac OS X. An app's bundle contains an XML resource called Info.plist, which the system reads to learn various important things about the app, such as where its icon file is and which of its nib files contains its startup interface. The Info.plist can also list document types the app is willing to open; it specifies those types by their uniform type identifier, or UTI. (The UTI is the modern equivalent of the old four-letter creator code and also enables mappings between file extensions and MIME types; for more gory details, see that creator code article cited earlier.)

I've omitted two pieces of the puzzle, because they're not really pieces of this puzzle. First, you're probably aware that you can copy documents into some apps via the File Sharing interface in iTunes when the iOS device is hooked to your computer. That's a separate mechanism. It's a simple on-off switch: either the user can or can't copy files to and from a certain directory in this app's sandbox using iTunes.

(To further muddy the issue, iBooks, of course, has a special relationship with iTunes, because it's Apple's own app. There's no accounting for how iBooks acquires files in the iTunes Books category.)

Second, there are also custom URLs. An app can define a URL scheme, such as "myScheme://something/or/other", and may be contacted when such a URL is tapped in a Web view or otherwise sent to the system. But this has nothing to do with document types. It's more like a secret code for sending a message, defined by an app and usable only if the user or another app knows the secret. And how an app responds when it receives such a message is entirely up to that app.

To summarize: You can't arbitrarily pick a document and ask for some app to open it. You can't even arbitrarily pick a document; you see the Open In dialog only if some app that encounters a document feels like showing it to you. You can't easily find out what apps are prepared to open a given type of file, for the same reason that an app can't. There's no easy way to look inside an app bundle to view its Info.plist, and there's no system call that an app (other than one of Apple's own apps) can use to perform such an inquiry. The entire process of getting iOS to work with documents is like trying to tell someone how to knit, while they're wearing mittens and earmuffs, and you're blindfolded.

[1]: http://db.tidbits.com/article/10537
[2]: http://db.tidbits.com/resources/2010-07/openIn.png
[3]: http://db.tidbits.com/resources/2010-07/safariOpenIn.png