How to use Universal Links on iOS

When reading apple documents about universal links everything looks just straight-forward. However, I stumbled over some issues that were easy to solve, but difficult to find out.

What is a Universal Link and how does it work?

The idea about universal links is to have regular links to your web-site, but if the user has installed your app, the links should work as deep links into your app. Hence instead of opening the website your app should be opened. For example, let assume there is your favourite social network called LinkMe. They probably have a website where you can login online and also they probably have an app for your mobile device. Now we assume you get an email from LinkMe that your friend has send you an invitation. When clicking that “accept invitation” link on your PC you probably expect that the web browser will open the LinkMe website. However, on your mobile device you would probably want the link to open your LinkMe app instead of the web browser. That is what universal links are for.

When the user clicks on a link, the systems first checks, if there is an app registered for that URL. Secondly the app tries to open a secure connection to the domain, and requests a confirmation for this URL to be opened inside the app instead of opening the browser. Finally the app will be opened and the requested URL will be handled by the app instead.

So at the end, universal links are just regular links. However if your server is configured in a specific way (see below how to configure your server) and if you have an app installed that is associated to the domain, the regular link will act as deep link into your app.

In short steps here is what to do in order to get universal links working:

  1. Prepare your application for the use of deep links
  2. Prepare your server to handle universal links and serve deep links

Preparing your app

  1. In apples developer portal create an app-id  and enable ‘Associated Domains’ for it. You could use an existing app-id and just make sure Associated Domains is enabled.
  2. In your Xcode-project go to the Capabilities section of your projects build-target. and make sure Associated Domain is enabled. Add your domains that will be used to serve universal links as
    applinks:www.your-domain.com
  3. A new entitlements file should be created, if not already existed. However, make sure this file is available to your build-target. Select the file and open up the property inspector on the right and make sure that this entitlement is actually included for your app in the section Target Membershipxcode_universallink_target
  4. In order to react to the deep links you have to add a new function to your application delegate.
    Objective-C

    Swift

Prepare your server

  1. appid_configFor the next step you’ll need to find out the full application bundle identifier. It consists of two parts. The first part is a application prefix. And the latter is the bundle-identifier. The prefix is usually the team-id, however for older applications this might be a different one. To make sure you get the correct prefix you could open up the detail view of your app-id and look for the keyword prefix. The bundle-identifier usually starts with a reverse domain name followed by the application identifier such as . Also this information can be found on the detail page of your app-id within apples developer portal. You get the complete full bundle identifier by connecting both parts with a dot. The resulting string should look like this: ABC123DE4.com.company.YourApplicationName
  2. The easy way is to let your server respond with deep links for all universal link requests. How ever, if you don’t want this you could read more about how to configure paths in apples documentation about Universal Links. Create a text file with the following content and replace ABC123DE4.com.company.YourApplicationName with your actual full bundle identifier from step 1:
  3. Save the file and name it
    apple-app-site-association (Make sure you have not accidentally added a file extension such as .json or .txt) and upload it to your root directory of your domain. Apple says you could also use a .well-known directory, however I haven’t checked that out.
  4. You have to configure your server to return the content-type application/json for this file. You could do that by adding a .htaccess file with the following content:

Testing

Testing was indeed the most difficult part for me. I started testing my setup with the simulator as apple stated that testing universal links in simulator should work just fine. However, it does not. Meanwhile I found a website to test your servers universal links setup, so I was able to ensure that everything on server side was ok before continuing testing the deep links. The only app that seems to work fine with universal links is the iOS email client app, but that app is actually missing in the simulator.

That said testing is easy on your real hardware. Install your test-app on your iOS device. And then just send your self an email with some links to your website. Once you open the email on your iOS email client, just hit the links and your app should open automatically.

UPDATE:

Safari always opens links in the same tab, and the app wont get launched if you clicked on a universal link from a webpage that has the same domain. However, you can tap and hold the link to show the context menu, it should contain an entry “Open In [App name]”. Links to other domains however should launch the app without issues.

Unfortunately while this is not documented, it does seem to be the desired behaviour. Once a user is on your website, you can’t make attempts to take them into your app.

 


Links

Apple Developer Portal
https://developer.apple.com

Apple Documentation about Universal Links
https://developer.apple.com/library/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html

Website to test your server setup for the use with Universal Links
https://branch.io/resources/universal-links

Leave a Reply

Your email address will not be published. Required fields are marked *

*