David Yang
Tips and posts for iOS developers from an iOS developer.
Implementing and testing Universal Links
Universal Links is a feature allowing redirection to your mobile app. Its main goal is to offer the end user the ability to display your content either on your mobile app (if it is installed) or your website.
What is Universal Link about?
To illustrate the benefits, let’s have a look on the Google Maps app.
With the app installed, the first time you’ll try to open a Google Maps link, the system will prompt you by asking if you would like to open it with the app. By accepting, the system will save that preference and open all future and similar links with the app, offering a richer experience.
But the user can always chose to open the link with the default behavior, opening Safari, by a long-tap gesture on the link. Doing so will also save that new preference in the system.
By definition, Universal Link also offers a similar feature as URL schemes: it can open a mobile app and provide parameters to it in the form of a URL link. Universal Link is safer than URL schemes though, making it the preferred way to invoke an app nowadays.
Unfortunately, safety comes with a price: a website.
Implementation
On the website
In order to implement Universal Links, a secure website is mandatory (https).
The following content have to be served and available at this path: https://[Your_Domain]/.well-known/apple-app-site-association
.
{
"applinks": {
"apps": [],
"details": [
{
"appID": "YOUR_TEAM_ID.fr.y4ng.sampleApp",
"paths": [
"/profile/settings/",
"/articles/*"
]
},
{
"appID": "ABCD1234.fr.y4ng.movieBang",
"paths": [ "NOT /profile/*", "*" ]
}
]
}
}
Under the paths
array, you can provide the list of paths you want (or explicitly not) to be handled by your app.
On your app
First, make sure you enabled the Associated Domain entitlements on your App ID configuration.
Then, add the following in your com.apple.developer.associated-domains
entitlement: applinks:myapp.y4ng.fr
.
Finally, implement the following method in your AppDelegate:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL {
// Handle the URL here
print(url.absoluteString)
}
return true
}
Validation
In order to check your website configuration, you can use some of the following online tools:
Note: From my experience, for Universal Link only implementation, some of the checks are not mandatory to make it work, espacially the content-type header. But please note that Associated Domains is not limited to Universal Links. It also enables services such as App Clips and Web Credentials, for which those specific checks may be required.
How does it work?
Once everything is setup, here’s how it will work on your devices running iOS 14+.
- After your app installation, the device will request through Apple managed content delivery network (CDN) the
apple-app-site-association
for the domain provided by your Associated Domain entitlement.- If the CDN has anything about your Associated Domain, the content will be provided to your device.
- If not, the CDN will request the
apple-app-site-association
hosted on your website and cache it.
- Any URL matching the paths and domains provided in your
apple-app-site-association
will be opened by the app its matching App ID.
Note:
With the CDN in the middle, be aware that any changes on your
apple-app-site-association
file may require 48h until it is updated on the CDN.For devices running iOS versions prior to 14, no CDN are used. Instead, the device will directly require the
apple-app-site-association
hosted on your website and cache it locally.
Development tips
The 48 hours delay for the update of your apple-app-site-association
file on the Apple managed CDN is not suitable for development purposes.
This behavior can be overriden in order to bypass the CDN. To do so:
- Enable
Associated Domain Development
on your device (go to Settings > Developer) - Use the developer mode in your Associated Domain entitlements by setting the mode parameter:
applinks:myapp.y4ng.fr?mode=developer
Still running issues?
Debugging a Universal Link setup is challenging…
As an additional tip, you can try using the Console app available on macOS in order to view your device’s logs. You can then filter the logs: the ones you will be interested in are from the swcd process.
Here for example, I ran into issues due to a 403 error response sent from my website to the Apple managed CDN dedicated to Associated Domain.
You can also have a look at what’s on the apple-app-site-association
cached by Apple’s CDN by requesting the following file:
https://app-site-association.cdn-apple.com/a/v1/[Your-Domain]
// example: https://app-site-association.cdn-apple.com/a/v1/google.com