URL schemes for iOS and Android (2/2)

Last month I wrote a blog on how to set up your app to be opened by using an URL. Now let’s look at how do that from an email or webpage.

NOTE: This post is outdated. There have been lots of issues and changes related to opening apps via intents and responding to URL schemes. See TIMOB-20490 for more information.

Via email

Yes, you can use your app’s new URL in an email. But no, you shouldn’t. Why? Email is a static thing. Even though the URLs for both Android and iOS can be the same, you can’t tell if the email is read on one of those devices and if the app is installed. Let’s look at what happens when you click on a URL for which no app is installed on Android, iOS, Apple (desktop) Mail and webmail using Chrome:

URL schemes in email

On iOS7 mail nothing happens, on both Android and Apple (desktop) mail you get an ugly error and in webmail an blank page. Not the seamless experience we’re after. My suggestion is to only use a custom URL scheme in an email if you’re certain the receiver has the app installed, e.g. for a password reset.

Always link to a website

For sharing or inviting it’s much better to have the email point to a webpage. Even more so for sending URLs via SMS, WhatsApp, Twitter, Facebook and other media where you don’t have much space to explain what can be found on the URL and why people should click on it. Yes, it’s an extra step, but one for the better.

On the website

A website is dynamic. You can use information on the user’s device and browser to provide information and actions that closely match the users environment. Let’s take a look a the steps involved.

Platform detection

You can tell iOS, iPhone, iPad and Android from the userAgent:

Open with fallback

Using the platform detection we can now open the app. Even if the Android and iOS app share the same URL (scheme) we use a different approach. This is because we want to provide a seamless fallback in case the user doesn’t have the app installed.

For Android we don’t use the actual scheme directly, but an Intent Anchor instead. If the app is not installed, this automatically searches for the app Google Play. And by setting the FLAG_ACTIVITY_NEW_TASK flag we don’t need to use the buggy singleTask launchMode we discussed in the previous blog anymore!

For iOS, we use a trick to see if the user is still in the browser after 25ms and then open the App Store. Unfortunately we can’t stop Mobile Safari from showing an alert telling it can’t open the first URL, but it will only be visible to the user for a very short time.

Open automatically

If you want you can of course call the open-method automatically when the page loads, but I don’t like the user experience of that. I’d rather have the page explain what the users our going to get and leave it up to them. But if you really need to, be sure to call it after the page has fully rendered because most browser will stop rendering when it executes.

Smart banner

Another nice feature we can use are iOS’s Smart App Banners. By inserting a one-line META tag we can tell Mobile Safari to show a banner on top of the webpage. If the app is installed, it will shown an open-button to open the app. If it’s not, an install-button will lead the user to the App Store, but only if the app can be installed on the device. And best of all, we can include our custom URL scheme so that the app will open as if it was opened using that URL directly, receiving all data we include in it:

Smart App Banner


Finally, we can take all this into one solution. I’ve used PHP to do most of the logic server-side to keep the page clean.

HTTP Scheme

On Android, instead of using a custom scheme, you can also set up your app to react on standard http:// links for specific domains and even paths. This allows use to make the experience on Android even smoother. Just add another intent-filter to our Android Manifest specifiying the URL of the webpage we’ve set up above. Now if the user clicks this link in the email, he will be asked if he wants to open it using the browser or directly in the app. Awesome, but you will have to deal with the singleTask issue!