iOS – Universal Link

by Hiran Stephan

on February 28, 2018

What Is A Deep Link?

A deep link is any link that directs a user past the home page of a website or app to content inside of it. e.g. linking directly to a product instead of the home page. For example the URL fb:// may open the Facebook app, but fb://profile/33138223345 opens Wikipedia’s profile in the Facebook app.

If you want to share a pair of shoes from the with a friend, you can send a deep link that brings your friend directly to those shoes in the app. Without a deep link, your friend would have to find the amazon app on the App Store or Play Store, open the app to the homepage, locate the Search function, and then try to find the same pair of shoes you did.

Custom URI schemes were the original form of deep linking for mobile apps. They are like creating a “private internet” for your app, with links that look like myapp://path/to/content. The advantage of custom URI schemes is they are easy to set up and most apps already have one. The disadvantage is a user’s device only knows about this “private internet” if the corresponding app is already installed, and there is no graceful fallback option by default.

The workaround approach to deep linking with URI schemes involves using a traditional http:// link to launch a web browser. This link contains a JavaScript redirect to a custom URI scheme, which is executed by the web browser to launch the app. If the redirect attempt fails because the app is not installed, the JavaScript then takes the user to the App Store or Play Store.

This is still the primary approach to deep linking on Android, but Apple began blocking this approach on iOS in 2015 with the release of Universal Links.

What is Apple iOS Universal Links?

Apple introduced Universal Links in iOS 9 as a solution to the lack of graceful fallback functionality in custom URI scheme deep links. Universal Links are standard web links ( that point to both a web page and a piece of content inside an app. When a Universal Link is opened, iOS checks to see if any installed app is registered for that domain. If so, the app is launched immediately without ever loading the web page. If not, the web URL (which can be a simple redirect to the App Store) is loaded in Safari.

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 (registered in the app’s PLIST like so) 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.

iOS 9 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 (an AASA (apple-app-site-association) file should be there in the domain which contains the bundle id of the app and the paths the app should open) 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.

How to Set Up Universal Links in iOS?

1. Configure your app to register approved domains

  • Register your app at
  • Enable ‘Associated Domains’ on your app identifier.

Enable ‘Associated Domain’ on in your Xcode project

The error “Add the associated Domains feature to your App ID” will go away once you enable the Associated Domains in your APP ID in as in the previous step. If it doesn’t go away, quit and relaunch the xcode few times and it will work.

Add the proper domain entitlement and make sure the entitlements file is included at build: Xcode will do it automatically by itself.

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

What Is An AASA (apple-app-site-association) File?

The AASA (short for apple-app-site-association) is a file that lives on your website and associates your website domain with your native app. In other words, it’s a safe way to prove domain ownership to iOS. With URI schemes, which were the standard way for opening apps on iOS until iOS 9, app developers could register any URI scheme of their linking and iOS, without any verification, would respond to those URI schemes by opening apps. For example, if an indie developer registers the fb:// URI scheme for a test app, there was nothing to stop that, even thoughfb:// is used by the Facebook native app. The AASA file makes Universal Links unique and secure because there is no way for an indie developer to host an AASA file on the domain.

Let’s look at some basics of the apple-app-site-association file that will help you in building and hosting one on your domain.

The AASA file contains a JSON object with a list of apps and the URL paths on the domain that should be included or excluded as Universal Links. Here is a sample AASA file


  • appID: Built by combining your app’s Team ID (goto to get the teamID) and the Bundle Identifier. In the example above, JHGFJHHYX is the Team ID and com.facebook.ios is the Bundle ID.

paths: Array of strings that specify which paths are included or excluded from association. You can use NOT (before the path — as in the example JSON above) to disable paths. In this case, all the links on this path will go to the web instead of opening the app. You can use * as a wildcard to enable all paths in a directory (apple doc says: Use * to specify your entire website) and ? to match a single character (/archives/201?/example in the sample JSON). Please note that these strings are case sensitive and that query strings and fragment identifiers are ignored.

Hosting the AASA File on Your Domain

Have a look at apple docs link below:

Once you are ready with your AASA file, you can now host it on your domain either at https://<<yourdomain>>/apple-app-site-association or at https://<<yourdomain>>/.well-known/apple-app-site-association.

Upload the apple-app-site-association file to your HTTPS web server. You can place the file at the root of your server or in the .well-known subdirectory.

Important: iOS will only attempt to fetch the AASA file over a secure connection (HTTPS).

So, while hosting the AASA file, please ensure that the AASA file:

  • Is served over HTTPS.
  • Uses application/json MIME type.
  • Don’t append .json to the apple-app-site-association filename.
  • Has a size not exceeding 128 Kb (a requirement in iOS 9.3.1 onwards).

 Supporting Multiple Apps on the Same Domain

You can support multiple apps on the same domain. To do that, you’d need to add a new appID, path dictionary to the details array in the AASA file to look something like this:

If two or more apps associate with the same content path on the website then the order of the appID, paths dictionary in the details array will determine which app will get precedence.

Preparing Your App to Handle Universal Links

When a user taps a universal link, iOS launches your app and sends it an NSUserActivity object that you can query to find out how your app was launched.

To support universal links in your app, take the following steps:

  • Add an entitlement that specifies the domains your app supports.
  • Update your app delegate to respond appropriately when it receives the NSUserActivity object.

As mentioned above, in Xcode, open the Associated Domains section in the Capabilities tab and add an entry for each domain that your app supports, prefixed with applinks:


Apple doc says to limit this list to no more than about 20 to 30 domains.

To match all subdomains of an associated domain, you can specify a wildcard by prefixing *. before the beginning of a specific domain (the period is required). Domain matching is based on the longest substring in the applinks entries. For example, if you specify the entries applinks:* and applinks:*, matching for the domain is performed against the longer * entry.

Note that an entry for * does not match because of the period after the asterisk. To enable matching for both * and, you need to provide a separate applinks entry for each.

After you do all these steps perfectly, when you click a universal link, the app will open up and the method application:continueUserActivity:restorationHandler will get called in Appdelegate.

When iOS launches your app after a user taps a universal link, you receive an NSUserActivity object with an activityType value of NSUserActivityTypeBrowsingWeb.

The activity object’s webpageURL property contains the URL that the user is accessing. The webpage URL property always contains an HTTP or HTTPS URL, and you can use NSURLComponents APIs to manipulate the components of the URL.

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {

print(“Continue User Activity called: “)

if userActivity.activityType == NSUserActivityTypeBrowsingWeb {

let url = userActivity.webpageURL!


//handle url and open whatever page you want to open.


return true


For getting the url parameters, use the following function:

//playground code..

var str = “″

let url = URL(string: str)

func queryParameters(from url: URL) -> [String: String] {

let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false)

var queryParams = [String: String]()

for queryItem: URLQueryItem in (urlComponents?.queryItems)! {

if queryItem.value == nil {



queryParams[] = queryItem.value


return queryParams


// print the url parameters dictionary

print(queryParameters(from: url!))

It will print:

[“category”: “series”, “contentid”: “1562167825”]

Also if you want to check if the app had opened by clicking a universal link or not in the didFinishLaunchingWithOptions method:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

var isUniversalLinkClick: Bool = false

if launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] {

let activityDictionary = launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey] as? [AnyHashable: Any] ?? [AnyHashable: Any]()

let activity = activityDictionary[“UIApplicationLaunchOptionsUserActivityKey”] as? NSUserActivity ?? NSUserActivity()

if activity != nil {

isUniversalLinkClick = true



if isUniversalLinkClick {

// app opened via clicking a universal link.

} else {

// set the initial viewcontroller


return true



Keep in mind:

  • When a user taps a universal link that you handle, iOS also examines the user’s recent choices to determine whether to open your app or your website. For example, a user who has tapped a universal link to open your app can later choose to open your website in Safari by tapping a breadcrumb button in the status bar. After the user makes this choice, iOS continues to open your website in Safari until the user chooses to open your app by tapping OPEN in the Smart App Banner on the webpage.
  • If you instantiate a SFSafariViewController, WKWebView, or UIWebViewobject to handle a universal link, iOS opens your website in Safari instead of opening your app. However, if the user taps a universal link from within an embedded SFSafariViewController, WKWebView, or UIWebView object, iOS opens your app.

It’s important to understand that if your app uses openURL: to open a universal link to your website, the link does not open in your app. In this scenario, iOS recognizes that the call originates from your app and therefore should not be handled as a universal link by your app.

  • Share this Article


  • We can initiate development process at the hour of your convenience
  • Discussion on the projects can be held for a stipulated duration
  • We will sign NDA and the talks will be secured
  • We’ll show you around our cherished designs
  • Briefing on technology
  • Guaranteed source code delivery
  • Option to re-start a closed venture

See how we can unwrap your app idea and proceed towards success