Apple has just announced at WWDC that iOS 8 (and OS X Yosemite) will be equipped with app-to-app communication capabilities that can extend system functionality through a set of well-defined extension points. This is, without doubt, the major iOS 8 feature from my perspective, with the rest of the developer- and consumer-related features fading to the background. (Well, there’s also Swift, a new programming language for iOS and OS X, to learn.)
Pre-release documentation for app extensions is available here, and shows that there are several new extension points where apps can now integrate. Prior to iOS 8, the only supported way of extending the system and providing app-to-app communication was through file type associations (e.g. a PDF reader could associate itself with PDF files) and custom URL protocols (e.g. an eBook store could associate itself with ebook:// URLs). In iOS 8, apps can integrate widgets in the user’s Today screen, provide custom sharing targets for other apps, offer documents for consumption by other apps, and even replace the built-in iOS keyboard.
Comparing iOS App Extensions to Android Intents and Windows Phone Contracts
How powerful are these extensibility features compared to Android and Windows Phone? Android has the reputation for being as open as possible in terms of extensibility points and replacing built-in OS functionality through the intent system. Windows Phone has always had some means of app-to-app communication, and with the advent of the Windows Runtime it now enjoys the familiar contract support to which Windows 8 users have become accustomed. I will use the term extension interchangeably from now on to mean either iOS app extensions or the general concept of extending the platform’s functionality with custom apps.
Let’s now consider a few scenarios and see how they can be handled by the various platforms. But first, how do users gain access to code that provides these extension points? On all three platforms, extensions ship as part of an app, which can provide share targets, a document source, a home screen widget, and so on. After installing an app, the setup steps for enabling the extension depend on the extension kind — for example, sharing to a new app doesn’t require explicit configuration, but putting a new widget on your home screen typically requires explicit user consent.
Sending Data to Another App
The first scenario we shall consider is simply sending data to another app, a.k.a. sharing. The purpose of sharing might be to post the data to social network, save it to a cloud service, distribute it to friends via email, or any other action that requires data from a source app to be delivered to a target app.
On Android, sharing is achieved through a set of common intent actions such as ACTION_VIEW or ACTION_SEND. The source app can attach arbitrary serializable content to the intent and the target app can read that content and act accordingly. By using additional intent properties such as custom actions, MIME types, URL schemes, and categories, the source app can filter the list of target apps that can process the provided data.
On Windows Phone, sharing is achieved through the Share contract. When using the Share contract, the source app uses a system-provided API to initiate a sharing session with a set of input data. When the user picks a target app, the system marshals the data to the target app, which can process it as necessary. To filter the list of target apps, the source app can specify the type of data that’s being shared (plain text, a URL, a photo, and so on).
On iOS, sharing is achieved through share app extensions. The source app initiates a sharing session and the extension (that runs in its own context) reads the source-provided data and acts accordingly. There are also action app extensions that can transform the provided data and return it to the source app (and there’s a further specialized model for photo editing extensions that integrate specifically with the iOS Photos app). Again, the source app specifies what kind of data is being passed in, and the extension specifies what types of data it can handle. The system filters out the available extensions based on that information.
One interesting difference between iOS app extensions and the Android/Windows Phone counterparts is that iOS app extensions do not run in the context of their containing app. If the extension wants to share data with or launch the containing app for further processing, it must do so explicitly.
Displaying Information on the Home Screen
The three platforms have fairly different views on how to give users at-a-glance information on their home screen and how to make that information interactive. Windows Phone prides itself on live tiles, Android has the widget system, and iOS 8 introduces Today app extensions, also called widgets.
On Android, apps can create app widgets, which are slightly restricted in terms of what UI they can display. Widgets can be updated in the background at any update period the author requires, and because Android has no restrictions on running code in the background — they can be kept as up-to-date as necessary. As of Android 4.2, app widgets can also be added to the user’s lock screen.
On Windows Phone, apps can publish live tiles to the Start screen. An app can publish multiple live tiles (one of which is the primary and the rest are secondary), and update them while it’s running. When the app isn’t running, live tiles can be updated using push notifications. Windows Phone also offers a very restricted option for adding information to the phone’s lock screen — you can’t publish complex views, but a few lines of information such as calendar appointments or weather alerts will work.
On iOS, Today widgets are a special kind of app extension that shows up on the user’s lock screen and on the Today area of the notification center. These widgets can host arbitrary views but they cannot accept keyboard input and are discouraged from requiring scrolling. iOS requests updates to the widget when the user pulls down the Today screen, while taking a snapshot of the widget’s previous contents to render something on screen until the updated version arrives.
Retrieving a Document from Another App
The third and final scenario we will look at is retrieving a document from another app. Note that this is different than sharing data with another app — the source app here is not pushing data to the target, but rather asking the target to provide data. Think of a contact picker, photo picker, ringtone picker — these components can (and should) integrate with 3rd party apps that can provide your app with content.
On Android, the ACTION_GET_CONTENT or ACTION_PICK intent actions provide the necessary support for one app to act as a source of data for another app. The specific kind of data to pick can be controlled by setting the MIME type of the intent. The user gets a chance to choose between the apps that can provide the content (through an intent chooser UI), picks content within that app’s purview, and the system returns that content (usually as a URI) to the calling app. A more complex scheme for exposing content from an Android app is through a content provider, which is a special component that provides CRUD operations on data URIs with a SQL-like API. For example, the contacts database on an Android phone is exposed through a content provider to the rest of the system.
On Windows Phone, the file open picker contract helps users pick files from another app. Again, the calling app specifies what kind of file it is looking for, and other apps may register to provide files of that particular type. Picking a contact is a specific exception that’s handled through the contact picker extension, which means your app can be a source for picking a contact.
On iOS, the Storage Provider app extension is the gateway an app uses to talk to other apps that can provide specific files. Again, the calling app can specify the file type it’s looking for, and the system presents the user with a list of apps that can be used to pick a file of that particular type. Specific integration points for cloud storage, file placeholders, and remote file retrieval are provided by the framework.
In closing, the iOS app extensions API will make many users’ lives much easier, and many developers much happier. Your app can now ask other apps for files and can provide files to other apps. Your app can now be a share target the user can pick for simple text or complex media in other apps. Your app can show up on the Today screen, providing the user with at-a-glance information that goes beyond the boring text displayed by a push notification. This gives iOS users — and developers — more control over how the lego-shaped ecosystem of third party apps interacts on a specific device.