SwiftUIにおけるディープリンクの扱い方

SwiftUIアプリケーションでカスタムURLスキームとユニバーサルリンクの両方を実装・処理する方法を学び、ユーザーを特定のコンテンツへ誘導しましょう。

Intermediate

SwiftUIにおけるディープリンクの処理には、特定のURLに応答するようアプリを設定し、それらのURLを解析してアプリケーション内の適切なコンテンツに移動させる必要があります。ディープリンクには主に2つの種類があります:カスタムURLスキームとユニバーサルリンクです。

1. カスタムURLスキーム

カスタムURLスキームでは、タップするとアプリケーションが開く一意のプレフィックス(例:myapp://)を定義できます。

設定手順:

  1. XcodeでURLタイプを追加:
    • Xcodeプロジェクトでターゲットを選択します。
    • 「Info」タブに移動します。
    • 「URL Types」で「+」ボタンをクリックし、新しいURLタイプを追加します。
    • 「識別子」を設定します(例: com.yourcompany.yourapp)。アプリのバンドルIDをプレフィックスとして使用するのがベストプラクティスです。
    • 「URLスキーム」を希望のスキームに設定します(例: myapp)。

SwiftUIでの処理:

受信したURLを処理するには、.onOpenURL ビュー修飾子を使用します。この修飾子はiOS 14以降で利用可能です。

import SwiftUI

struct ContentView: View {
 @State private var receivedURL: URL?

 var body: some View {  VStack {  Text("Deep Link Handler")  if let url = receivedURL {  テキスト("受信URL: \(url.absoluteString)")
 // URLを解析し、それに応じてナビゲートする
 // 例: myapp://product?id=123  if url.host == "product",  let components = URLComponents(url: url, resolvingAgainstBaseURL: false),  let id = components.queryItems?first(where: { $0.name == "id" })?.value {  テキスト("商品ID: \(id)")
 }  } else {  テキスト("まだディープリンクを受信していません。")  }  }
 onOpenURL { url in  receivedURL = url
 print("Received custom URL scheme: \(url)")  }  } } 

2. ユニバーサルリンク

ユニバーサルリンクは標準のHTTPSリンク(例:https://yourwebsite.com/path)であり、アプリがインストールされている場合は直接起動し、インストールされていない場合はウェブサイトにフォールバックします。シームレスなユーザー体験を提供します。

設定手順:

  1. 関連ドメイン権限:

    • Xcodeプロジェクトでターゲットを選択します。
    • 「署名と機能」タブに移動します。
    • 「+ Capability」をクリックし、「関連ドメイン」を追加します。
    • applinks:yourwebsite.com の形式でエントリを追加します(例: applinks:example.com)。
  2. apple-app-site-association ファイル:

    • .json 拡張子なしで apple-app-site-association という名前の JSON ファイルを作成します。
    • このファイルをウェブサイトのルートディレクトリまたは.well-knownディレクトリに配置します(例:https://yourwebsite.com/apple-app-site-association または https://yourwebsite.com/.well-known/apple-app-site-association)。
    • このファイルは、ウェブサイト上のどのパスでアプリを開くかを指定します。このファイルにはチームIDとバンドルIDが必要です。

    apple-app-site-association ファイルの例:

    json { "applinks": { "details": [ { "appIDs": [ "YOUR_TEAM_ID.com.yourcompany.yourapp" ], "components": [ { "/": "/products/*", "comment": "/products/ パス内の任意のURLに一致" }, { "/": "/profile/*", "comment": "/profile/ パス内の任意の URL にマッチします" } ] } ] } }

SwiftUIでの処理:

カスタムURLスキームと同様に、.onOpenURL修飾子を使用します。

import SwiftUI struct ContentView: View {  @State private var receivedUniversalLink: URL?

 var body: some View {  VStack {
 テキスト("ユニバーサルリンクハンドラ")
 if let url = receivedUniversalLink {  Text("ユニバーサルリンクを受信しました: \(url.absoluteString)")
 // URLを解析してナビゲート  // 例: https://yourwebsite.com/products/123
 if url.pathComponents.contains("products"),  let productId = url.lastPathComponent {  テキスト("ユニバーサルリンクからの商品ID: \(productId)")  }  } else {
 テキスト("ユニバーサルリンクはまだ受信されていません。")
 }  }  .onOpenURL { url in
 receivedUniversalLink = url  print("受信ユニバーサルリンク: \(url)")  }  }
} 

3. 解析とナビゲーション

より複雑なアプリケーションでは、受信したURLを解析し、SwiftUIのナビゲーションツールを使用してユーザーを正しいビューに誘導する必要があります。

import SwiftUI enum AppRoute: Hashable {  case home  case product(id: 文字列)  ケース プロファイル(id: String)  case settings } class DeepLinkManager: ObservableObject {
 @Published var navigationPath = _ url: URL) {
 guard let host = .host else { return }

 // カスタムURLスキームの例: myapp://product?id=123  // ユニバーサルリンクの例: https://yourwebsite.com/products/123

 if host == "product" || url.pathComponents.contains("products") {  if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
 let id = components.queryItems?.first(where: { $0.name == "id" })?.value ?? url.lastPathComponent {  navigationPath.append(AppRoute.product(id: id))  }
 } else if host == "profile" || url.pathComponents.contains("profile" {
 if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
 let id = components.queryItems?.first(where: { $0.name == "id" })?.value ?? url.lastPathComponent {  navigationPath.append(AppRoute.profile(id: id))  }  }  // 他のパス用のルーティングロジックを追加  } }