Implement Universal Links on iOS, iPadOS, and macOS
Universal Links let you deep-link into your app from anywhere a URL can be tapped: Safari, Messages, Notes, other apps.
If your app is installed, iOS/iPadOS/macOS opens it and passes in the URL to your app. If not, the link loads in Safari.
Step 1. Get Identifiers
First, you need to get the identifiers for your app that will be used in later steps.
-
Click your app, then grab App ID Prefix and Bundle ID. You’ll use these in your Apple-App-Site-Association file.
Step 2. Create Apple-App-Site-Association (AASA) file
Create a file named apple-app-site-association
(no .json extension). Use this structure:
{
"applinks": {
"details": [
{
"appID": "ABCDE12345.com.example.app",
"components": [
{
"/": "/*",
"comment": "Matches all urls in the domain."
}
]
}
]
}
}
Replace ABCDE12345.com.example.app with your <App ID Prefix>.<Bundle ID>
from Step 1.
Step 3. Register a Domain
Register a domain and point it to a host that supports:
- HTTPS (with valid SSL cert)
- Serving static files without redirects
Step 4. Host the AASA file
Upload the AASA file to: https://example.com/.well-known/apple-app-site-association
It must be:
- Accessible via HTTPS
- No redirects
- No .json extension
Step 5. Configure your app
In Xcode, under Signing & Capabilities:
- Add Associated Domains
- Add
applinks:example.com
, but with the domain you got in Step 3.
Optional: repeat for any additional domains.
Step 6. Handle universal links in your app
If your app uses Scenes
In your SceneDelegate:
/// This is called if your your app needs to launch when a universal link is delivered.
func scene(_ scene: UIScene, willConnectTo
session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
// Get URL components from the incoming user activity.
guard let userActivity = connectionOptions.userActivities.first,
userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else {
return
}
// Route to the correct screen in your app
handleUniversalLink(url: incomingURL)
}
/// This is called if your app is in memory when a universal link is delivered.
func scene(
_ scene: UIScene,
continue userActivity: NSUserActivity
) {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else {
return false
}
// Route to the correct screen in your app
handleUniversalLink(url: incomingURL)
}
If your app doesn’t use Scenes
In your AppDelegate:
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else {
return false
}
// Route to the correct screen in your app
handleUniversalLink(url: incomingURL)
return true
}
If you have a macOS app
In your AppDelegate:
func application(_ application: NSApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([NSUserActivityRestoring]) -> Void) -> Bool
{
// Get URL components from the incoming user activity.
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else {
return false
}
// Route to the correct screen in your app
handleUniversalLink(url: incomingURL)
return true
}
Step 7. Test your universal links
- Install your app on a device.
- In the Apple Notes app, create some sample links that you want to test, like
https://example.com/mylink
. - Tap that link and if all went well, it should open in your app!