UIKit でディープリンクを処理するには、主に 2 つのメカニズムがあります:カスタムURLスキーム (Custom URL Schemes) と ユニバーサルリンク (Universal Links) です。どちらもユーザーをアプリ内の特定のコンテンツに直接ナビゲートさせることができますが、ユニバーサルリンクは、そのシームレスなユーザーエクスペリエンスと優れたフォールバック動作により、一般的に好まれています。
1. カスタムURLスキーム
カスタムURLスキームを使用すると、アプリのURLに一意のプレフィックス(例:myapp://product/123)を定義できます。ユーザーがこのスキームを持つリンクをタップすると、iOSはアプリを起動します。
設定:
-
Xcode でURLスキームを登録する:
- Xcode でプロジェクトを開きます。
- プロジェクトナビゲーターでプロジェクトを選択し、ターゲットを選択します。
- 「Info」タブに移動します。
- 「URL Types」セクションで、「+」ボタンをクリックして新しいURLタイプを追加します。
- 「Identifier」には、アプリのバンドルID(例:
com.yourcompany.yourapp)を使用できます。 - 「URL Schemes」には、希望するカスタムスキーム(例:
myapp)を入力します。
-
AppDelegateまたはSceneDelegateで受信したURLを処理する:-
AppDelegateを使用するアプリの場合(古いアプリまたはScene Delegatesを使用しないアプリ):application(_:open:options:)メソッドを実装します。swift func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // Parse the URL and navigate to the appropriate content print("Received URL: \(url)") handleDeepLink(url) return true } -
SceneDelegateを使用するアプリの場合(iOS 13 以降):scene(_:openURLContexts:)またはscene(_:continue:)を実装します。```swift func scene(_ scene: UIScene, openURLContexts URLContexts: Set
) { guard let url = URLContexts.first?.url else { return } print("Received URL: (url)") handleDeepLink(url) } // For Universal Links, you'll also use this method func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return } print("Received Universal Link: (url)") handleDeepLink(url) } ```
-
2. ユニバーサルリンク
ユニバーサルリンクは、ウェブサイトとアプリの両方で機能する標準のHTTPSリンクです。アプリがインストールされている場合、リンクは直接アプリで開かれます。インストールされていない場合は、Safariで開かれます。これにより、はるかにスムーズなユーザーエクスペリエンスが得られます。
設定:
-
apple-app-site-associationファイルを作成する:- このJSONファイルは、iOSにアプリがどのURLを処理できるかを伝えます。
- このファイルをウェブサーバーのルートまたは
.well-knownサブディレクトリ(例:https://yourdomain.com/apple-app-site-association)にホストします。 - 例:
json { "applinks": { "apps": [], "details": [ { "appID": "TEAM_ID.com.yourcompany.yourapp", "paths": [ "/product/*", "/settings/*" ] } ] } }TEAM_IDとcom.yourcompany.yourappを実際の値に置き換えてください。
-
Xcode で Associated Domains Capability を有効にする:
- Xcode で、プロジェクトとターゲットを選択します。
- 「Signing & Capabilities」タブに移動します。
- 「+ Capability」をクリックし、「Associated Domains」を選択します。
- アプリが処理する必要のある各ドメインにエントリを追加します。プレフィックスとして
applinks:を付けます(例:applinks:yourdomain.com)。
-
AppDelegateまたはSceneDelegateで受信した URL を処理する:- ユニバーサルリンクは
NSUserActivityオブジェクトを使用して処理されます。 -
AppDelegateの場合:application(_:continue:restorationHandler:)を実装します。swift func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return false } print("Received Universal Link: \(url)") handleDeepLink(url) return true } -
SceneDelegateの場合: 上記のカスタムURLスキームセクションで示したscene(_:continue:)メソッドを使用します。
- ユニバーサルリンクは
3. 一般的なディープリンク処理ロジック (handleDeepLink 関数)
カスタムURLスキームを使用する場合でも、ユニバーサルリンクを使用する場合でも、URLを解析してアプリ内でナビゲートするためのコアロジックは同様です。
func handleDeepLink(_ url: URL) {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
return
}
// Example: myapp://product/123?color=red
// Example: https://yourdomain.com/product/123?color=red
if components.host == "product" {
// Extract product ID from path components or query parameters
let productID = components.path.replacingOccurrences(of: "/", with: "")
let color = components.queryItems?.first(where: { $0.name == "color" })?.value
// Navigate to product detail screen
// (e.g., using a UINavigationController or presenting a new view controller)
if let rootViewController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController {
let productViewController = ProductDetailViewController() // Your custom VC
productViewController.productID = productID
productViewController.selectedColor = color
rootViewController.pushViewController(productViewController, animated: true)
}
} else if components.host == "settings" {
// Navigate to settings screen
if let rootViewController = UIApplication.shared.windows.first?.rootViewController as? UINavigationController {
let settingsViewController = SettingsViewController() // Your custom VC
rootViewController.pushViewController(settingsViewController, animated: true)
}
}
// Add more conditions for different paths/hosts
}
4. セキュリティに関する考慮事項
ディープリンクは潜在的な攻撃ベクトルとなる可能性があります。常にすべてのURLパラメータを検証し、不正な形式のURLは破棄してください。ディープリンクを通じて利用可能なアクションは、ユーザーデータを危険にさらさないものに限定し、コンテンツを直接削除したり機密情報にアクセスしたりすることを決して許可しないでください。
5. ディープリンクのテスト
ディープリンクは次のようにテストできます:
* Safari でカスタムURLスキームを入力する(例:myapp://product/123)。
* ターミナルで xcrun simctl openurl booted <URL> コマンドを使用して、iOSシミュレーターでURLを開く。
* Safari でウェブページからユニバーサルリンクをタップする。