Universal Links

Before iOS 9 — the mechanism to open apps which were installed was to open Safari, try to open a deeplink and use a timer fallback to the App Store.


On iOS 9 Apple announced “Universal Links” where instead of opening Safari first, the iOS checks if the Universal Link is registered in the domain associated with the link, then checks if the corresponding app is installed. The app is opened if installed, and if not, Safari will load an http(s) link. This functionality allows one link for both website and app.
The idea behind Universal Links is to use the same link for both your app and website while seamlessly being redirected to your installed app without going through the Safari browser. In order to support Universal Links, you need to setup both your app and your website so that iOS can establish a trust between them.

Deeplinking – How it Works:

When the app is installed or updated, iOS will check which websites are acceptable by this app as Universal Links. Then it will check each of these websites to verify whether the app is registered there. This is done by placing a file with the app IDs on the website and a list of domains in the app.

Preparing Your Website:

  1. Create a apple-app-site-association file. Note that there’s no .json file type
  2. Place the apple-app-site-association file and identify app IDs and paths on your website. You can define several apps in this file and iOS will follow the app order while looking for a match so that you can specify different apps to handle different paths on your website.

Here’s an example of the apple-app-site-association file:

{
    “applinks”: {
        “apps”: [],
        “details”: [
            {
                “appID”: “9JA89QQLNQ.com.my.bundle.id“,
                “paths”: [ “/myPath1”, “/myPath2/*” ]
            },
            {
                “appID”: “TeamID.BundleID2”,
                “paths”: [ “*” ]
            }
        ]
    }
}

The “apps” key in the apple-app-site-association file must be present and its value must be an empty array.

The value of the “appID” key is the team ID and the bundle ID joined with a period. The team ID appears on Organization Profile > Account Summary on Apple’s Developer Portal. When you enter the Member Center on http://developer.apple.com, click your name on the top right and select “View Account”:

ViewAccount

The Team ID appears on the Developer Account Summary section:

teamid

3. Upload the apple-app-site-association file in the root of your HTTPS web server. The file should be accessible without redirects at http://<domain>/apple-app-site-association

Preparing your App

Creating provisioning profile
1. Assuming your app has been already registered on Apple’s Developer Center, you will need to enable “Associated Domains” on your app’s Identifier. Go to Identifier->App IDs, select your app and enable “Associate Domains”:

AppID

2. Next, you need to generate your provisioning files for your app, download them and double click to install them on Xcode.

Configuring your app

3. Go to Xcode and select your app target. On the Capabilities section enable “Associate Domains” and add each of the domains supported by your app.

You have to prefix each domain with “applinks:” (for example: applinks:domain.com) and also add any sub domain that you want to use with Universal Links.

xcode

Handling when app is opened by Universal Link

To be able to subscribe for a native IOS App events you need to enable App Events API.

  1. Open IOS Native Editor Settings.  Window -> Stan's Assets -> IOS Native -> Edit Settings
  2. Enable App Events API as showed on a screenshot bellow

Since IOS APP controllers (App Delegate) are started before Unity player, you need to check if an app was launched by a Universal Link. See the code snippet below:

namespace SA.IOSNative.UIKit 
...
string url = ISN_UIApplication.ApplicationDelegate.GetLaunchUniversalLink();
if(!string.IsNullOrEmpty(url)) {
    Debug.Log("ALaunch Universal Link Detecetd: " + url);
}

 To handle app restored from a background with Universal Link you need to subscribe to  OnContinueUserActivity action.

namespace SA.IOSNative.UIKit 
...
ISN_UIApplication.ApplicationDelegate.ContinueUserActivity.AddListener((string url) => {
    Debug.Log("Universal Link Detecetd: " + url);
});

Testing

Now that your app and website are set up, all you have left is to test it. Load an HTTPS link which is configured as described above. If your app is installed it should open the app, otherwise, it should open the website.

Troubleshooting

  1. Note that Gmail and Google Inbox apps do not handle Universal Links properly (they will not open the apps). It’s not possible to open any app by any universal link in there apps.
  2. When the app is installed and an associate domain defined in the app does not response, iOS will show an error on the device log. However, it will not show anything in case of success.
  3. If the provisioning file is not updated from the Apple developer center, the associate domain will not be processed and the Universal Links setting of the app will be ignored. This applies both to the development & App Store provisioning files.