はじめに (対象読者・この記事でわかること)
この記事は、iOSアプリ開発に興味があり、Swiftでアプリ開発をしている方を対象としています。特に、Safariなどの外部ブラウザからアプリに自動で戻る機能を実装したいと考えている開発者に向けています。
この記事を読むことで、Universal LinksとCustom URL Schemeを使って、SafariからiOSアプリに自動で戻る機能を実装する方法がわかります。また、両者の違いや使い分け方、実装時の注意点についても理解できます。これにより、ユーザー体験を向上させたアプリ開発が可能になります。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- Swiftの基本的な知識
- iOSアプリ開発の基本的な知識
- Xcodeの基本的な操作
- StoryboardやプログラムによるUI作成の経験
Universal LinksとCustom URL Schemeの概要と背景
iOSアプリ開発において、Safariなどの外部ブラウザからアプリに戻る機能は、ユーザーエクスペリエンスを向上させる重要な要素です。この機能を実現する主な方法として、Universal LinksとCustom URL Schemeの2つがあります。
Custom URL Schemeは、昔からある技術で、アプリ独自のスキーマ(例:myapp://)を定義し、そのスキーマでリンクを開くことでアプリを起動します。しかし、この方法では、アプリが未インストールの場合にSafariでエラーページが表示されたり、既にインストール済みの場合でも確認ダイアログが表示されたりするため、ユーザー体験が少し劣ります。
一方、Universal LinksはiOS9から導入された比較的新しい技術で、通常のHTTPSリンク(例:https://example.com)をそのまま使用します。これにより、アプリがインストールされている場合はアプリが起動し、インストールされていない場合はWebサイトがSafariで開かれるという、自然なユーザー体験を実現できます。
Universal LinksはApple Developer Programに加入し、ドメインの所有権を証明する必要がありますが、Custom URL Schemeよりもセキュリティが高く、ユーザー体験も優れています。ただし、実装はやや複雑になるため、両者の特徴を理解した上で適切な技術を選択することが重要です。
具体的な実装方法
ステップ1:Custom URL Schemeの実装
まずはシンプルなCustom URL Schemeの実装方法から見ていきましょう。
Info.plistの設定
まず、XcodeプロジェクトのInfo.plistにURL Typesを追加します。
- XcodeでプロジェクトナビゲータからInfo.plistを選択
- 「+」ボタンをクリックして「URL Types」を追加
- 追加された項目の「Item 0 - URL Types」を展開
- 「URL Schemes」を展開し、「Item 0」にアプリ固有のスキーマを入力(例:myapp)
これでアプリが「myapp://」というスキーマを認識できるようになりました。
アプリ側でのURLハンドリング実装
次に、アプリ側でURLを受け取る処理を実装します。SceneDelegate.swift(またはAppDelegate.swift)に以下のコードを追加します。
Swiftfunc scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let url = URLContexts.first?.url else { return } // URLスキーマをチェック if url.scheme == "myapp" { // URLからパラメータを取得 let components = URLComponents(url: url, resolvingAgainstBaseURL: false) // パラメータを処理 if let queryItems = components?.queryItems { for item in queryItems { if item.name == "param1" { print("パラメータ1: \(item.value ?? "")") // ここでパラメータを使った処理を実装 } } } // 特定のパスに応じた処理 if url.path == "/home" { // ホーム画面に遷移 if let windowScene = scene as? UIWindowScene, let window = windowScene.windows.first { let storyboard = UIStoryboard(name: "Main", bundle: nil) let homeViewController = storyboard.instantiateViewController(withIdentifier: "HomeViewController") window.rootViewController = homeViewController window.makeKeyAndVisible() } } } }
このコードでは、URLスキーマが「myapp」の場合に処理を行い、パスやクエリパラメータに応じた処理を実装しています。
Safariからの呼び出し方法
Safariからアプリを起動するには、HTMLのaタグに以下のように記述します。
Html<a href="myapp://">アプリを起動</a> <a href="myapp://home?param1=値">特定の画面に遷移</a>
これで、ユーザーがこれらのリンクをタップすると、アプリが起動し、指定された処理が実行されます。
ステップ2:Universal Linksの実装
次に、より高度なUniversal Linksの実装方法を見ていきましょう。
Apple Developerでの設定
- Apple Developerサイトにログイン
- 「Certificates, Identifiers & Profiles」を選択
- 「Identifiers」から「Associated Domains」を選択
- 「+」ボタンをクリックして新しい識別子を追加
- 識別子タイプを「Associated Domains」に設定
- 設定するドメインを入力(例:example.com)
- 証明書を作成し、ダウンロードしてXcodeプロジェクトにインポート
Associated Domainsの設定
Xcodeプロジェクトの設定でAssociated Domainsを有効にします。
- Xcodeでプロジェクトナビゲータからプロジェクトファイルを選択
- 「Signing & Capabilities」タブを選択
- 「+ Capability」ボタンをクリック
- 「Associated Domains」を検索して追加
- 追加した項目にドメインを入力(形式:applinks:example.com)
サーバー側での設定
Universal Linksを有効にするには、サーバー側にapple-app-site-associationファイルを配置する必要があります。
- apple-app-app-site-associationファイルを作成
- ファイルの内容を以下のように設定(JSON形式)
Json{ "applinks": { "apps": [], "details": [ { "appID": "TEAMID.BUNDLEID", "paths": [ "*"] } ] } }
- TEAMID: Apple Developerから取得できるチームID
- BUNDLEID: アプリのバンドルID
- paths: アプリで許可するパス("*"はすべてを許可)
- このファイルをサーバーのルートディレクトリ(.well-knownディレクトリ)に配置
- ファイルの拡張子なしでアクセスできるように設定(例:https://example.com/.well-known/apple-app-site-association)
アプリ側での実装
アプリ側での実装は比較的シンプルです。SceneDelegate.swift(またはAppDelegate.swift)に以下のコードを追加します。
Swiftfunc scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return } // Universal Linksで受け取ったURLを処理 print("Universal Linksで受け取ったURL: \(url)") // URLのパスやクエリパラメータに応じた処理 if url.path == "/home" { // ホーム画面に遷移 if let windowScene = scene as? UIWindowScene, let window = windowScene.windows.first { let storyboard = UIStoryboard(name: "Main", bundle: nil) let homeViewController = storyboard.instantiateViewController(withIdentifier: "HomeViewController") window.rootViewController = homeViewController window.makeKeyAndVisible() } } // 他のパスに応じた処理を実装 }
このコードでは、ユーザーアクティビティのタイプがWebブラウジングの場合に処理を行い、URLに応じた操作を実装しています。
ハマった点やエラー解決
Universal Linksの実装では、いくつかの典型的な問題に遭遇することがあります。
Universal Linksが機能しない場合のトラブルシューティング
-
apple-app-site-associationファイルの配置場所 - ファイルはルートディレクトリまたは.well-knownディレクトリに配置 - 拡張子なしでアクセス可能であること(.jsonなどの拡張子は不可) - 正しいMIMEタイプ(application/json)で提供されていること
-
ファイルの形式 - JSON形式で正しくフォーマットされていること - 改行やスペースに問題がないこと - BOM(Byte Order Mark)が含まれていないこと
-
ドメインの設定 - Apple DeveloperでAssociated Domainsが正しく設定されていること - ドメインが正しい形式(applinks:example.com)で指定されていること - ドメインの所有権が証明されていること
これらの問題を解決するために、Appleが提供するLink Debuggerツールを使用してUniversal Linksをテストすることをお勧めします。
Custom URL SchemeとUniversal Linksの優先順位
同じドメインに対して両方の方法を実装した場合、優先順位は以下のようになります。
- Universal Links(アプリがインストールされている場合)
- Custom URL Scheme
- Webサイト(アプリがインストールされていない場合)
このため、Universal Linksを実装している場合は、Custom URL Schemeはバックアップとしてのみ使用するようにしましょう。
テスト方法のポイント
Universal Linksのテストでは、以下の点に注意してください。
-
シミュレータでのテスト - シミュレータではUniversal Linksのテストができない場合がある - 実機でのテストが必須
-
キャッシュのクリア - 一度設定したUniversal Linksはキャッシュされる - テスト前に設定を変更した場合は、キャッシュをクリアする必要がある - 設定変更後は、アプリを完全にアンインストールして再インストール
-
複数のデバイスでのテスト - 開発用証明書と配布用証明書で動作が異なる場合がある - 実際に配布する環境でテストすること
まとめ
本記事では、iOSアプリでSafariからアプリに自動で戻る機能を実装する方法について解説しました。
- Custom URL Schemeはシンプルに実装できるが、ユーザー体験がやや劣る
- Universal Linksはユーザー体験が優れているが、設定や実装がやや複雑
- 両者の特徴を理解し、目的に応じて適切な技術を選択することが重要
- テスト時にはキャッシュのクリアや実機での確認が必要
この記事を通して、ユーザーが外部ブラウザからアプリにスムーズに戻れる機能を実装する方法がわかりました。これにより、アプリのユーザーエンゲージメントを向上させることができます。
今後は、ディープリンクやコンテンツ共有機能の実装についても記事にする予定です。
参考資料
- Apple Developer - Supporting Associated Domains
- Apple Developer - Universal Links
- How to Implement Universal Links in iOS - Ray Wenderlich
- iOS App Programming Guide - Supporting Custom URL Schemes
