Calling Google apps on iOS & X-Callback-Url

· October 9, 2013

I previously mentioned how easy it is to deep link straight into the Google+ app on iOS, to view a user’s profile or similar, using the gplus:// scheme and UIApplication openURL. This sort of integration is pretty much the only way to do general inter-app communication in iOS (bar the new audio APIs), and several other Google apps offer their own URL schemes which let you make very straightforward integrations.

Mostly these are ways of giving users a slightly smoother experience when entering the app, but one allows you to do a little bit more!

Google Maps

With Google Maps, you can specify coordinates to focus on, a search to perform, or two locations to ask for directions between. All the parameters are documented on the maps site. As a simple example, searching for pizza near me looks like this:

Gmail

With Gmail you can go straight to the compose screen and specify the to and the subject line, just like with web mailto:// addresses. This can be good for email options in case users don’t have mail.app set up on their phone.

Open In Chrome

Chrome on iOS has a different option though. It allows you to not only open a page within Chrome, but also to have a return button in the Chrome nav bar so users can come back to your app afterwards. Why would you do this instead of popping up a UIWebView? Mainly because sending the user to their regular browser means they’re much more likely to be signed in to any services on the page - for example for social share or endorsement buttons (like the +1 button). It’s also a great addition to a UIActivityView, where users can bookmark easily. The fact that the user gets a button pointing back to you app makes it a lot less risky that they’ll go off and do something rather than continuing their experience with you.

This is all implemented via a custom URL scheme of googlechrome-x-callback://, which you can test for with canOpenURL, and call with openURL. However, there is a controller on Github which handles everything for you - for Google+ developers: this is actually included in the GoogleOpenSource.framework. Opening a link in Chrome just requires that you have defined a custom URL type for your own app, and can pass it to the OpenInChromeController. In this example my custom URL type is myuri:// and I am asking Chrome to open this site:

When I tap the GoogleMe nav item, I’m returned straight to my app. This happens because Chrome, along with other popular apps like Instapaper, implements an open scheme called x-callback-url, and can invoke my custom URL when the user presses the button.

That’s pretty much all you need for Open In Chrome, but the x-callback-url scheme is something you could support in your own application. It just needs a custom URL type in your app, and to be able to handle URLs of the format: yourscheme://x-callback-url/[action]?param=val&param2=val2. There are some pre-defined parameters, such as:

x-source: the name of the calling app. In the Chrome example above, my app was called GoogleMe.
x-success: the callback URL. In the example above was myuri://home.
x-error and x-cancel: for indicating other results

On top of that can be other parameters, such as Chrome’s url parameter that takes the site you would like to show to the user.

Lets say that we had an app which allowed us to subscribe to an RSS feed. The x-callback-url format we define might look like this:

myreader://x-callback-url/subscribe?x-source=myapp&x-success=myuri%3a%2f%2f&feed=foo

To parse that in iOS we’d need to implement the application:openURL:sourceAppliction:annotation: method on our app delegate, and parse the incoming structure. There are some libraries already built to do this, but for educational purposes the steps are fairly simple: take the URL, check the parameters are as you expect, and parse out the ones you need. At the end, callback to the proper URL with openURL.

This type of inter-app communication really opens up new possibilities for building richer iOS experiences - and can be a nice way of adding the functionality from an existing service into your own app.