For MarketersFor DevelopersFor Product
7 min read

iOS Universal Links

Universal Links are Apple's way of connecting websites to apps. When configured correctly, tapping a link opens your app directly — no browser, no redirect, no "Open in App?" prompt.

What you'll learn

  • How iOS Universal Links work under the hood
  • Configuring your apple-app-site-association file
  • Troubleshooting common Universal Links issues

How Universal Links work

When a user taps a Universal Link:

  1. iOS checks the domain — Has this domain been associated with an app?
  2. AASA file verified — iOS cached the apple-app-site-association file when the app was installed
  3. App opens directly — No Safari, no interstitial, just your app
  4. Deep link data passed — Your app receives the full URL to handle
Key Concept

Universal Links are the gold standard for iOS deep linking. Unlike custom URL schemes (yourapp://), they work even if the app isn't installed (falling back to your website) and can't be hijacked by other apps.

The apple-app-site-association file

The AASA file tells iOS which URLs your app can handle. It lives at:

https://yourdomain.com/.well-known/apple-app-site-association

Example AASA file:

{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appID": "TEAMID.com.yourcompany.app",
        "paths": ["*"]
      }
    ]
  }
}

Key fields

FieldDescription
appIDYour Team ID + Bundle ID (e.g., ABC123.com.example.app)
pathsURL paths your app handles (* for all, or specific patterns)
Gotcha

The AASA file must be served over HTTPS with no redirects. iOS fetches it when your app is installed and periodically afterward. Changes can take 24-48 hours to propagate to all devices.

ULink handles AASA for you

When you configure your iOS app in ULink:

  1. Enter your Bundle ID and Team ID
  2. ULink automatically generates and serves the AASA file
  3. Your custom domain (or ulink.to) is ready for Universal Links

No need to host the file yourself — ULink manages it.

App-side configuration

In your Xcode project:

1. Enable Associated Domains

Go to your target → Signing & Capabilities → Add "Associated Domains"

2. Add your domain

Add an entry for each domain:

applinks:yourdomain.com
applinks:links.yourdomain.com

For ULink's shared domain, add:

applinks:ulink.to

3. Handle incoming links

Implement the delegate method:

func application(_ application: UIApplication,
                 continue userActivity: NSUserActivity,
                 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
          let url = userActivity.webpageURL else {
        return false
    }

    // Handle the URL
    return handleDeepLink(url)
}
SwiftUI apps: Use the onOpenURL modifier on your root view to handle incoming links. Works seamlessly with UIKit delegate methods.

Testing Universal Links

On device (required)

Universal Links only work on physical devices, not simulators.

  1. Long-press a link in Notes or Safari
  2. You should see "Open in [Your App]" option
  3. Tapping the link directly should open your app

Debug with Apple's tools

Use the Associated Domains Diagnostics profile:

  1. Install from Apple's developer site
  2. Go to Settings → Developer → Associated Domains Diagnostics
  3. Enter your domain to see AASA fetch status

Verify AASA is correct

curl -I https://yourdomain.com/.well-known/apple-app-site-association

Should return 200 OK with Content-Type: application/json.

Troubleshooting

"Open in Safari" instead of app

  • AASA file may not be cached yet — wait 24 hours after app install
  • Check that Associated Domains entitlement matches your domain exactly
  • Ensure AASA has no redirects and is served over HTTPS

Works in some places, not others

  • Universal Links don't work when pasting into Safari's address bar
  • They work from: Mail, Messages, Notes, social apps, other apps
  • Safari has special behavior — it respects the user's choice to open in browser

Links stopped working

  • Apple's CDN caches AASA files. Changes take time to propagate
  • Check that your AASA file is still valid JSON
  • Ensure your Team ID and Bundle ID haven't changed
Gotcha

If a user taps the breadcrumb to open a link in Safari, iOS remembers this preference. Future taps will open Safari until the user long-presses and chooses "Open in App" again.

Quick recap

  • Universal Links provide seamless app opening without browser interstitials
  • ULink automatically generates and serves your AASA file
  • Add Associated Domains entitlement in Xcode
  • Test on physical devices only — simulators don't support Universal Links
  • Changes to AASA can take 24-48 hours to propagate