Glossary/Implementation artifacts
Associated Domain
Definition
An Associated Domain is an entry in an iOS app's com.apple.developer.associated-domains entitlement that declares a domain the app is bound to for a named service, such as Universal Links or shared web credentials.
It is the app's half of the domain-to-app handshake. The domain's half is the apple-app-site-association file it hosts, and iOS only treats the pairing as valid when both sides name each other. Miss the entitlement and a perfectly correct AASA file does nothing, with no error anywhere — which is why this is worth understanding as a separate thing from the file it points at.
What the entitlement looks like
The entitlement is an array of strings in your .entitlements file. Each string is a service prefix, a colon, and a host — never a URL, never a path, and never a scheme.
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:example.com</string>
<string>applinks:www.example.com</string>
<string>applinks:*.example.com</string>
<!-- Shared passwords and passkeys with the website -->
<string>webcredentials:example.com</string>
<!-- Development only. Bypasses Apple's CDN so edits to the AASA
file take effect immediately. Remove before submission. -->
<string>applinks:staging.example.com?mode=developer</string>
</array>In Xcode this is the Associated Domains capability under Signing & Capabilities, which writes exactly the array above. Adding the capability also flips the Associated Domains service on for the App ID in your developer account and forces a new provisioning profile — the second step is the one that silently fails when you manage profiles by hand.
It is a host, not a URL
applinks:https://example.com, applinks:example.com/products and applinks:example.com:443 are all invalid. The value after the colon is a bare hostname, optionally with a ?mode= query. Paths are matched by the components array inside the AASA file, not here.
The service prefixes
One entitlement carries several unrelated features, which is why the file often looks busier than a deep linking setup needs. Only applinks matters for link routing.
| Prefix | What it enables | AASA key it pairs with |
|---|---|---|
applinks: | Universal Links — HTTPS URLs on the domain open the app | applinks |
webcredentials: | Password AutoFill and passkeys shared between site and app | webcredentials |
appclips: | App Clip invocations from the domain | appclips |
activitycontinuation: | Legacy Handoff. Superseded by applinks in iOS 9 | activitycontinuation (obsolete) |
Each entitlement entry triggers its own fetch of the domain's AASA file when the app is installed. A long list is not free: keep it to the hosts you actually route from, and prefer one wildcard entry over a dozen enumerated subdomains.
Wildcards do not cover the apex
applinks:*.example.com matches www.example.com and shop.example.com on iOS 14 and later, but not example.com itself. If links are published on the bare domain, it needs its own entry — and its own AASA file, because a wildcard entitlement still fetches one file per host.
Developer mode, and why your edits do nothing
By default iOS does not fetch your AASA file from your server. Apple's CDN fetches it, caches it, and serves that copy to devices — so a fix you deployed a minute ago can take up to 24 hours to reach a phone. The ?mode=developer flag removes the CDN from the path entirely.
| Mode | Fetched from | Use for |
|---|---|---|
| (none) | Apple's CDN at app-site-association.cdn-apple.com | Production. Always. |
?mode=developer | Your domain, directly, on every check | Local iteration on a dev build |
?mode=managed | Your domain, for MDM-managed apps | Enterprise distribution |
Developer mode also requires the device switch: Settings → Developer → Associated Domains Development. The Developer menu only appears after the device has been connected to Xcode at least once. With both in place, the association re-evaluates without waiting on any cache.
# macOS: force a fetch for a domain and print the failure reason
swcutil dl -d example.com
# List every association the machine currently holds
swcutil show
# On device, watch the daemon that does this work
# Console.app -> your device -> filter on process "swcd"Ship a developer-mode entry to the App Store and it is rejected
?mode=developer in a submitted binary fails review. Keep staging hosts in a separate entitlements file selected by build configuration, so the release build cannot carry one by accident.
Why a correct AASA file still does nothing
The entitlement fails in a small number of mechanical ways, none of which produce a message. The link just opens Safari, exactly as it would with no configuration at all.
| Cause | How to confirm |
|---|---|
| Capability enabled in Xcode but not on the App ID | Identifiers → your App ID → Associated Domains is unchecked |
| Profile predates the capability | Regenerate the provisioning profile; the old one lacks the entitlement |
| Wildcard App ID | Associated Domains requires an explicit App ID; com.example.* cannot carry it |
| Host in the entitlement is not the host in the link | example.com and www.example.com are separate entries |
| Entitlement present, app never reinstalled | Association is fetched at install — delete and reinstall to re-evaluate |
| Extension targets missing the entitlement | Share and notification extensions need their own copy if they open links |
Verify what actually shipped rather than what Xcode shows, by reading the entitlements out of the built binary:
# From a .app bundle
codesign -d --entitlements :- /path/to/Shop.app
# From an .ipa
unzip -o Shop.ipa -d /tmp/shop
codesign -d --entitlements :- /tmp/shop/Payload/Shop.appIf com.apple.developer.associated-domains is absent from that output, nothing on the server side matters yet. If it is present and links still fall through, the problem has moved to the file — see aasa-file-not-found and universal-links-not-opening-app.
AASA generator
Generate the apple-app-site-association file that pairs with your entitlement, from the same App ID and paths, in the modern components format. It also fetches a live domain's file and checks the redirect chain, content type and size — the server-side half of the handshake this page describes.
Frequently asked questions
- What is the difference between an Associated Domain and an apple-app-site-association file?
- The Associated Domain is the app-side entitlement naming a domain the app claims. The apple-app-site-association file is the domain-side JSON naming the apps it authorises. iOS only creates an association when both sides reference each other, so a correct file with no entitlement, or an entitlement with no file, produces exactly the same result as no configuration: links open in Safari.
- Do I need to reinstall the app after changing Associated Domains?
- Yes in practice. iOS evaluates associations at install and on app update, then caches the result, so an entitlement change in a new build takes effect when that build is installed. During development, deleting the app and reinstalling forces a clean re-evaluation, and adding ?mode=developer makes each check hit your domain directly instead of Apple's CDN.
- How many domains can one app associate with?
- There is no documented hard cap, but each entry costs a separate network fetch when the app is installed, and Apple advises keeping the list small. Use a single wildcard entry such as applinks:*.example.com instead of enumerating subdomains, and remove hosts you no longer route links from rather than letting the array grow with every campaign.
- Does applinks:*.example.com cover example.com?
- No. The wildcard, available on iOS 14 and later, matches subdomains only, so www.example.com and shop.example.com are covered but the apex domain is not. If you publish links on the bare domain, add applinks:example.com as its own entry and host an apple-app-site-association file on that host as well.
- Why does my Associated Domain work in development but not in TestFlight or the App Store?
- Almost always because the development build carries ?mode=developer, which bypasses Apple's CDN, while the distribution build relies on the CDN copy of your file. If the CDN cannot fetch your apple-app-site-association file — because of a redirect, a wrong content type, or an authentication wall — the developer build keeps working and every other build fails.
Related terms
- Apple App Site Association (AASA) — The apple-app-site-association file is a JSON document hosted at a domain's /.well-known/ path that tells iOS which app is allowed to handle which URLs on that domain.
- Apple Team ID — An Apple Team ID is the ten-character alphanumeric identifier Apple assigns to a developer account, used to namespace that account's App IDs, certificates, and entitlements.
- Universal Link — A Universal Link is a standard HTTPS URL that opens an iOS app directly when that app is installed and the domain has authorised it, and loads the equivalent web page when it is not.
- Universal Links not opening the app — A Universal Link fails to open its app when iOS has no valid association for the domain, when the tapped URL does not match the association's path rules, or when the tap did not originate in a context where iOS honours Universal Links at all.