Thursday, April 28, 2011

Integrating Applications in iOS and X-Callback-URL

When you’re using an iOS app, it fills the screen and becomes the whole experience of using the device. You’re not using the iPhone or the iPad, you’re using Twitter, Reeder or Instapaper. John Gruber has used the phrase 'app console' to aptly describe the way this feels.

It’s a very immersive experience, which works well when a single application lets you accomplish an entire task from start to end, but it breaks down somewhat when you need to use multiple applications to accomplish a single task. There’s no overlapping windows, no multi-display systems and even real multitasking is a recent addition. While you can certainly switch between applications and use copy-and-paste to share some data, getting applications to work together in iOS isn’t always a piece of cake.

Imagine writing a typical blog post: you need to browse a few web sites, link to them, upload an image and embed it, write the copy and push that up somewhere. An iOS application that allows you to post pictures and text to your blog using blogging APIs and has an embedded web browser could go a long way to making that fairly painless. But try and do that using separate tools, and you’ll need to switch tabs in Safari, cut-and-paste the URLs into an editor, upload an image to flickr, copy its link and switch back to the editor, then transfer the whole thing up to your blog. When each application switch is a double-tap, swipe, tap and when copy-and-paste is a somewhat time-consuming affair, you can imagine that you quickly reach the point where you decide to hold off until you’re back at your laptop.

As a result, many of the best iOS application experiences are applications that help you do all the things you need to do to accomplish a task. Rather than having a text editor, a web browser and an FTP client, you use a blogging client. These all-in-one applications are not unique to iOS but they’re more important in iOS than they would be in a desktop environment, where using a collection of tools or a single tool is a tradeoff that each person might make differently.

Integrating iOS Applications

Even before multi-tasking, but particularly after iOS 4.0 brought multi-tasking to iOS devices, iOS apps have increasingly been integrating with each other. Reeder allows me to send links to Instapaper, Twitter, bookmark them on delicious and open links an embedded web view. Instapaper lets you look up word definitions using Terminology.

When you want to integrate iOS applications, there are a few ways to go about it, including: integrate with a server (e.g. Instapaper, DropBox), custom urls with protocol handlers, and documents.

Integrating through Servers

Applications running on iOS can communicate with servers, and in so doing, indirectly interact with one another. For instance, when I use Reeder to save a link to Instapaper, it does so by telling Instapaper’s servers, using an API, that I’d like to save a new link to my Instapaper account. When I then load up Instapaper, it downloads updates from the server, including new documents that I’ve saved from Reeder.


In this case, neither iOS application is explicitly aware of the other one, but they both integrate with the same server, leading to a sort of indirect integration. This works fairly well for queue-style interactions, where you’re not expecting necessarily to switch back and forth between the applications, but rather dispatch some information that you’ll look at in the other application later.

Integrating through a server can be fairly simple, but it has lots of hidden complexities if you want your integration to be robust. If the iOS device is offline, or can’t reach the server, you may need to build a queueing mechanism to store data locally and send it up to the server once your connection to the server is available again.

Dropbox

Dropbox is a special case of server-based integration. It’s not fundamentally different from a technology perspective than integrating with any other server, but it is an increasingly common integration point across multiple platforms and has been expanding strongly in iOS applications. Dropbox provides a mobile API and makes integration through dropbox as easy as it can be. As a result, many apps for iOS have built-in Dropbox support, acting as a sort of shared filesystem, albeit a remote filesystem.

For instance, you could save a file from the Atomic web browser to Dropbox, then edit that file using something like Elements:



Again, neither Atomic nor Elements knows about the other, and the apps themselves don’t integrate at all, but they do both work with a common server: Dropbox.

Documents

Unlike most desktop operating systems, user applications in iOS do not share areas of the filesystem with other applications. Users can’t save a file to a location that’s accessible to both applications and then switch applications and load the file. It is possible, however, for each application to register the kinds of files they’re capable of handling, and to ask iOS to open a file on your behalf. UIDocumentInteractionController will then offer the user a choice of applications known to handle files of that type, resulting in another application being asked to open that file.

For instance, if you open a PDF in Dropbox and click the ‘Action’ icon, iOS will give you the option of opening the file in one or more of the applications that support PDFs. On my phone, that’s iBooks and Evernote:
Opening a File in Another Application


Strictly speaking, the Dropbox and iBooks applications aren’t integrated. They know nothing about one another, and the Dropbox app cannot explicitly invoke iBooks. However, because iOS knows about both applications, it provides a mechanism that allows them to feel as if they’re integrated. Even in this scenario, iOS doesn’t actually share a file between applications. If you open a file in another application, iOS makes a copy of that file in the Inbox folder of the destination app. Each app retains its own copy of the file and decides what to do with it.

This form of interaction is useful for transferring a file from one application to another, but it’s an awkward approach for most other kinds of integration between applications in iOS.

Protocol Handlers and Custom URL Schemes

In addition to files, iOS allows applications to indicate that it is able to open URLs of particular schemes, and to ask iOS to open URLs on your behalf. This turns out to be a handy way to integrate two applications that don’t need to pass files around. This is the most commonly-used1 way to integrate two iOS applications that don’t integrate with a common server.

For instance, if I open Reeder and decide that I want to share an article I’m reading on Twitter, I can press the action button, select ‘Twitter’, compose a tweet in Reeder, and then it will send the contents of that tweet to the Twitter application using a custom URL scheme (twitter://post?message=Message%20Text):

Sending to Twitter from Reeder

Once again, Reeder doesn’t explicitly know that I have the Twitter application installed. All it knows (if it cares to check) is that iOS can open a URL with the “twitter:” scheme. There’s nothing that prevents another application from registering the same scheme, although unfortunately, iOS does not have a mechanism for selecting one of several applications that can handle the same URL scheme2.

This works reasonably well, but it’s a one-way ticket. If you want to return to Reeder after posting a Tweet, you’ll have to do it yourself (from the home screen or the recent-application tray). This isn’t terribly hard, and iOS users are used to it, but it’s not a seamless experience.

Where it gets worse is if you want some kind of two-way integration. What if you want to do a thesaurus lookup where another application can offer you alternative words? With a one-way integration, you’re left to copy the word from the destination app, return to the source app and then replace the original word using a paste. It’s plausible, but very clumsy, and require a lot of tapping and holding.

X-Callback-URL

The x-callback-url spec proposes a means of allowing a more seamless two-way integration, still using custom URL schemes. Essentially, applications using x-callback-url structure their custom urls in a particular way so that the called application knows the name of the calling application and how to indicate success and failure to the calling application, potentially carrying additional ‘return’ data.

The thesaurus lookup example is pulled directly from Terminology, the first iOS application to offer support for x-callback-url. If your application supports x-callback-url, you can request a replacement word from Terminology, tell it the word you’d like to replace, and let it know which URLs to invoke in your application the case of success and failure. iOS will switch to terminology, let you choose a replacement word, then if you touch the return button, Terminology will ask iOS to open the success url, causing your application to launch, and giving you enough information to replace the original word:



The Terminology API documentation has example interactions and even a short video allowing you to see x-callback-url in action. Instapaper now supports x-callback-url for adding pages to your Instapaper account. This gives you offline queuing for free, although it does require a round-trip to the instapaper application.

X-callback-url offers the potential for iOS application integration to be bi-directional, reducing the friction that makes using multiple applications to get a job done somewhat painful.

Small Pieces, Loosely Joined


Although the sweet spot for iOS applications will likely remain all-in-one applications, I’m happy to see movement towards applications that can work together in a more seamless manner, bringing us closer where iOS software can form an ecosystem of related and connected apps, not a market of isolated all-in-one apps. I’m looking forward to the future where iOS apps form a loosely connected network where getting a job done with three applications doesn’t feel like juggling.

Footnotes and References

  1. This is so common that there is an index of viable integration url schemes at HandleOpenURL.
  2. The documentation says, “Note: If more than one third-party application registers to handle the same URL scheme, there is currently no process for determining which application will be given that scheme.”

No comments:

Post a Comment