What is the difference between a custom URL scheme and a universal link, and which do you use?

6.7.2 · L3 · Interview

Predict first

A user taps a universal link for your domain on a phone that does not have the app. What happens?

// A: nothing
// B: the link opens the web page in the browser
// C: an error dialog
  • A
  • B
  • C

Mental model. A custom scheme is a nickname anyone can use. A universal link is a signed letter from the domain owner saying “this address belongs to that app”.

A custom URL scheme (myapp://item/42), declared in CFBundleURLTypes, is simple but weak: any app can claim the same scheme (the system picks one, not necessarily yours), there is no verification, and if the app is not installed the link just fails. A universal link is an ordinary https:// URL on a domain you own. When the app is installed, the system opens your app instead of Safari; when it is not, the same link opens the web page, so it degrades gracefully. It is verified because only the owner of the domain can publish the association file that grants it.

Prefer universal links for anything shared with users (email, messages, QR codes, marketing), because they are secure, work when the app is absent and are one link for web and app. Keep custom schemes for private, local hops (an app opening another app you control, or testing). In code, handle universal links in the scene delegate’s scene(_:continue:) with an NSUserActivity of type NSUserActivityTypeBrowsingWeb, or in SwiftUI with .onOpenURL, and treat the incoming URL as untrusted input to validate like any request.

It is an ordinary https URL, so without the app it simply loads the page. A custom scheme would fail.

Custom URL schemeUniversal link
Looks likemyapp://item/42https://example.com/item/42
Verified by the systemno, any app can claim ityes, via the domain’s association file
App not installedthe link failsthe web page opens
NeedsCFBundleURLTypesassociated-domains entitlement and a hosted file
Good forprivate app-to-app hopslinks shared with users

Common traps

  • Putting sensitive actions behind a custom scheme. Another app can send or intercept it. Validate and require confirmation.
  • Trusting a link’s parameters. Anyone can create the URL. Check authentication and authorisation, not just the path.

They might follow up with

  • What happens when a user taps a universal link inside Safari on the same domain? It opens the page unless they chose to open the app, so test the paths users actually take.
  • Which callback handles a cold-launch link? The scene’s connection options carry the user activity or URL contexts.

Related questions

  • 6.7.3 What does the apple-app-site-association file contain, and how does the system verify a domain?
  • 6.1.3 What are entitlements, and what happens when they do not match the provisioning profile?
  • 6.7.1 What is Info.plist for, and which keys matter most?

← What is Info.plist for, and which keys matter most?   What does the apple-app-site-association file contain, and how does… →