AppleDeep LinkingHow TosiOS 10iOS 11iOS 9Mobile MarketingTechnicalUniversal Links

How to Set Up Universal Links to Deep Link on Apple iOS

By July 20, 2015 97 Comments

This was originally posted on July 20th, 2015 but has since been updated with the latest information. Now that Apple no longer supports URI schemes for deep linking, developers must implement Universal Links in order to deep link properly on iOS. If you are already using URI schemes, check out our blog on transitioning to Universal Links

At Branch, we eat, breathe and sleep mobile deep linking. We created a single link that you can use everywhere: every platform, every device and every app store to drive users to your app. It’s a single link, fully configured to link to your app off of every channel (Facebook, Twitter, Gmail, etc) and be listed in every search portal (Firebase App Indexing, Bing search, Apple Spotlight).

It just works. In fact, we’ve already written blog posts about How to Set Up Google App Indexing and How to Deep Link on Facebook, check them out.

Image result for apple ios 12

When Apple announced “Universal Links” in its WWDC pitch back in 2015, we were excited to incorporate it into the Branch deep linking platform. Little did we know how complicated it would be to get it working. After spending far too much time on it and given how poor the documentation is, we thought we’d share a guide on how to do it in order to save everyone else.

How Do Universal Links Work in iOS?

Before Universal Links, the primary mechanism to open up an app when it was installed was by trying to redirect to an app’s URI scheme in Safari. This put the routing logic in Safari, but there was no way to check if the app was installed or not. This meant that developers would try to call the URI scheme 100% of the time, in the off chance that the app was installed, then fallback gracefully to the App Store when not by using a timer.

Universal Links were intended to fix this. Instead of opening up Safari first when a link is clicked, iOS will check if a Universal Link has been registered for the domain associated with the link, then check if the corresponding app is installed. If the app is currently installed, it will be opened. If it’s not, Safari will open and the http(s):// link will load.

Functionally, it allows you have a single link that will either open your app or open your mobile site.

Universal Link Integration Guide

Here are the high-level steps to get Universal Links working for your app:

1. Configure your app to register approved domains

  1. Register your app at developer.apple.com.
  2. Enable Associated Domains on your app identifier.
  3. Enable Associated Domains on in your Xcode project.
  4. Add the proper domain entitlement.
  5. Make sure the entitlements file is included at build.

If you use Branch, you can stop here. Otherwise, continue to section two.

2. Configure your website to host the apple-app-site-association file

  1. Buy a domain name or pick from your existing.
  2. Acquire SSL certification for the domain name.
  3. Create structured apple-app-site-association JSON file.
  4. Sign the JSON file with the SSL certification.
  5. Configure the file server.

If you use the Branch hosted deep links, we’ll save you all of the complexity of creating SSL certs and signing and hosting your server’s JSON file, so you only need to modify your app’s code to leverage it. We’ll introduce this at the bottom of the post.

Note: We’ve also built a tool to check if your apple-app-site-association file is configured properly.

Section 1: Configuring your app entitlements

Note: newer versions of Xcode can typically handle entitlement provisioning for you automatically. You can most likely skip to the Enable Associated Domains in your Xcode project section below, and refer back to these instructions only if you encounter problems.

In order to register your Xcode project for Universal Links, you need to create an App ID in the Apple developer portal and enable the proper entitlements. This is very similar to the configuration required for in-app purchases.

You cannot use a wildcard app identifier for Universal Links.

Register your app on developers.apple.com

First, head to developer.apple.com and log in. Then click on Certificates, Identifiers & Profiles, and then click on Identifiers.

Apple Developer Portal for Universal LinksApple Dev Portal for Universal Links

If you don’t have a registered App Identifier already, you’ll need to create one by clicking the + sign. If you do have one, skip ahead to the next section.

You need to fill out two fields here: name and bundle ID. For name, you basically enter whatever you want. For bundle ID, you’ll fill in the value of the bundle

Explicit App ID for Universal Links

You can retrieve this by looking at the General tab of your Xcode project for the proper build target.

Setting up Universal Links in xcode

Enable Associated Domains in your app identifier on developers.apple.com

For your pre-existing or work-in-progress App Identifier, scroll down to the last section and check the Associated Domains services.

 Setting up App ID for Universal Links

Scroll down and click Save.

Enable Associated Domains in your Xcode project

Now, you’ll want to enable the Associated Domains entitlement within your Xcode project. First, make sure that your Xcode project has the same Team selected as where you just registered your App Identifier. Then go to the Capabilities tab of your project file.

Universal Links in xcode

Scroll down and enable Associated Domains so that the accordion expands.

Setting Up Associated Domain for Universal Links

If you see an error like this, check:

  1. That you have the right team selected.
  2. Your Bundle Identifier of your Xcode project matches the one used to register the App Identifier.

Add the domain entitlement

In the domains section, add the appropriate domain tag. You must prefix it with applinks:. In this case, you can see we added applinks:yourdomain.com.

App Links and Your Domain

Make sure the entitlements file is included at build

Lastly, for some reason, Xcode 7 did not include my entitlements file in my build. In the project browser, make sure that your new entitlements file is selected for membership to the right targets so that it’s built.

Configuring xcode for Universal Links

If you use Branch links, you can stop here! If not, keep reading to learn more, or request a Branch demo.

If you want to save yourself hours of headache, you can avoid all the JSON hosting and SSL cert work and just use Branch links to host it for you. However, if you’re a control freak and glutton for punishment, by all means continue.

Section 2: Configuring your apple-app-site-association file

Universal Links turn your website URL into an app link, so you need be running a web server in order to leverage them. To help with this process, use our Universal Links Validator to check if your apple-app-site-association file is configured properly.

Pick a domain

First, identify the domain that you’d like to use for your Universal Links. You can register a new one or use an existing. If registering a new one, we prefer to use a clean, non-spammy registrar like gandi.net.

Acquire SSL certification

You need to acquire SSL certification files for the domain you’ll use to host the Universal Links. In order to do this, you’ll need to use a third party service to register your domain for SSL, and create the files you need. After looking around, we’ve chosen Digicert to handle branch.io and associated subdomains.

Here are the steps to create your SSL certification:

  1. Visit https://www.digicert.com/easy-csr/openssl.htm and fill out the form at the top to generate an openSSL command. Keep this window open.
  2. Log into your remote server.
  3. Execute the openSSL command to generate a certificate signing request (.csr) and certification file (.cert).
  4. Pay for your SSL certification at https://www.digicert.com/welcome/ssl-plus.htm.
  5. Wait for Digicert to approve and send you the final files.
  6. In the end, move yourdomain.com.cert, yourdomain.com.key and digicertintermediate.cert into the same directory on your remote server.

Create your apple-app-site-association JSON

There is a pretty standard structure of this JSON file, so you can basically just copy this version and edit it to fit your needs. I’ll break down where to get the correct values below.

{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "T5TQ36Q2SQ.com.branch.sdk.TestBed",
        "paths": ["*"]
      }
    ]
  }
}

The only fields you need to change are associated with: T5TQ36Q2SQ.com.branch.sdk.TestBed. This is actually two values joined together with a period. Both values are found on developers.apple.com in the Identifiers -> App IDs section. Just click on the corresponding registered App ID as shown below.

Configuring Apple ID for Universal Links

In this example, connect the Prefix and the ID together with a period so that it looks like so: T5TQ36Q2SQ.com.branch.sdk.TestBed.

Save this JSON file as apple-app-site-association-unsigned.

Sign the JSON file with your SSL certificates

Note: if you have certified your domain as HTTPS, you can skip this step and send the JSON in plaintext, as explained in Apple’s updated requirements:

If your app runs in iOS 9 or later and you use HTTPS to serve the apple-app-site-association file, you can create a plain text file that uses the application/json MIME type and you don’t need to sign it. If you support Handoff and Shared Web Credentials in iOS 8, you still need to sign the file as described in Shared Web Credentials Reference.

All apple-app-site-association files on the Branch platform are now served as unsigned application/json.

Upload the apple-app-site-association-unsigned file to your server into the same directory as the certification and key files from the previous steps. Using the command line, change directory into that folder and issue the following command:

cat apple-app-site-association-unsigned | openssl smime -sign -inkey yourdomain.com.key -signer yourdomain.com.cert -certfile digicertintermediate.cert -noattr -nodetach -outform DER > apple-app-site-association

This will generate the file apple-app-site-association.

Configure your file server

Alright! So you have your signed apple-app-site-association file. Now you just need to configure your file server to host this for you. There are a few caveats:

  1. It must be sent with the header application/pkcs7-mime (or application/json, as noted above).
  2. It must be sent from the endpoint youdomain.com/apple-app-site-association, and/or youdomain.com/.well-known/apple-app-site-association (iOS 9.3+ only).
  3. It must return a 200 http code.

We set up the one for all Branch integrated apps using our Node+Express link servers. Here’s the code we used, in case that’s helpful:

var aasa = fs.readFileSync(__dirname + '/static/apple-app-site-association');
app.get('/apple-app-site-association', function(req, res, next) {
     res.set('Content-Type', 'application/json');
     res.status(200).send(aasa);
});

Branch and Universal Links Integration Guide

Again, as a reminder, you can avoid all the JSON hosting and SSL cert work and just use Branch. Happy Linking!

Branch is a mobile linking platform providing unified mobile experiences and measurement for more than 50,000 mobile apps, including Airbnb, Pinterest, BuzzFeed, Tinder, Foursquare, Yelp, and Sephora. Branch’s linking platform can help you grow your mobile app through features like deep linking, sharing, referrals, mobile banners and interstitials, custom app onboarding, and unified attribution across platforms and channels. Learn more about Branch or contact sales today.
Request Demo Create Links