MASTG-KNOW-0079: Custom URL Schemes
Custom URL schemes allow iOS apps to receive requests from other apps or web pages via a custom URI protocol (for example, myapp://action?param=value). An app declares the schemes it handles and processes incoming URLs through delegate methods. Apple documentation is available at Defining a Custom URL Scheme for Your App.
Registering a Custom URL Scheme¶
Source Code¶
In Xcode, registered URL schemes appear on the app target's Info tab under URL Types. Underneath, they are stored in the Info.plist as a CFBundleURLTypes array:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.example.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
Each entry can declare one or more scheme strings under CFBundleURLSchemes. The CFBundleURLName is an optional reverse-DNS identifier for the scheme owner.
Compiled App Bundle¶
In an IPA or installed app bundle, the same values are found in Info.plist at the root of the .app directory. They can be inspected as described in Identifying Custom URL Scheme Registrations in iOS Apps.
Scheme Collision¶
If multiple apps register the same URL scheme, iOS routes incoming requests to one of them without a guaranteed resolution order. See Registering Custom URL Schemes for details.
Handling Incoming URLs¶
All incoming URL requests are delivered to the app delegate. The system calls the delegate method that best matches the set of methods the app has implemented.
application:openURL:options: (iOS 9+, current)¶
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool
This is the current method for handling incoming URLs. The options dictionary carries contextual metadata:
| Key | Description |
|---|---|
UIApplication.OpenURLOptionsKey.sourceApplication |
Bundle identifier of the app that sent the request, or nil if not available. |
UIApplication.OpenURLOptionsKey.annotation |
Property-list value supplied by the originating app (optional). |
UIApplication.OpenURLOptionsKey.openInPlace |
Boolean indicating whether the URL refers to a file that should be opened in place. |
The sourceApplication key provides the caller's bundle identifier. It is populated by UIKit when the caller used openURL:options:completionHandler:. It may be nil when the URL is opened by the system (for example, from a web browser or a universal link redirect) or when the originating app did not supply an identifier. See application(_:open:options:) in the Apple developer documentation.
Deprecated Delegate Methods¶
The following delegate methods are deprecated and receive no options dictionary:
application:handleOpenURL:— deprecated in iOS 9.0.application:openURL:sourceApplication:annotation:— deprecated in iOS 9.0.
The UIApplication instance method openURL: (for sending URL requests to other apps) is deprecated since iOS 10.0 in favor of openURL:options:completionHandler:.
Querying Other Apps¶
Before opening a URL in another app, an app can call canOpenURL: to check whether a registered handler exists. Since iOS 9.0, the schemes passed to canOpenURL: must be declared in the calling app's Info.plist under LSApplicationQueriesSchemes:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
<string>googledrive</string>
</array>
Up to 50 schemes may be declared. canOpenURL: returns NO for any scheme not listed, regardless of whether a handler app is installed. The openURL:options:completionHandler: method is not subject to this restriction and will attempt to open any URL.
URL Structure and Parameters¶
Incoming URLs follow the standard URI structure:
scheme://host/path?key=value&key2=value2
URL parameters are typically parsed via URLComponents or URLQueryItem. The host, path, and individual query items are accessible as named properties of those types.