【Swift/iOS】Custom URL Scheme(ディープリンク)の実装方法!アプリ間の遷移
この記事からわかること
- Swift/iOSのCustom URL Scheme(ディープリンク)の実装方法
- ユニバーサルリンクとの違い
- データの受け渡し
- 異なるのアプリ間の遷移
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:16.0
- iOS:18.0
- Swift:5.9
- macOS:Sonoma 14.6.1
Custom URL Scheme(ディープリンク)とは?
iOSの「Custom URL Scheme」はディープリンクの一種でアプリを直接起動させることができるリンクのことです。これを使用することでアプリを起動させるだけでなく、特定の画面を開いた状態で起動させたりデータのやり取りなどを行うことも可能です。
Custom URL Schemeでは固有のスキーム(例:my-test-app://
)を設定することで対象のアプリを開くことができるようになります。
ユニバーサルリンクとの違い
同じようなディープリンクにユニバーサルリンクがあります。これはhttps://
を使用してアプリを起動させることができます。
Custom URL Scheme | ユニバーサルリンク | |
---|---|---|
スキーム | 任意のスキーム | HTTPS |
アプリ未インストール時の挙動 | 動作しない | Webページを開く |
競合のリスク | スキームが被ると動作しない | なし |
実装方法 | アプリで完結 | サーバーへの設置も必要(※) |
※ 以下のようなJSON形式のファイルをサーバー側に設置
{
"applinks": {
"apps": [],
"details": [{
"appID": "XXXXXX.com.XXXX.XXXXXX",
"paths": ["*"]
}]
}
}
詳細な実装方法は以下の記事を参考にしてください。
Custom URL Scheme(ディープリンク)の実装方法
実装するのは簡単で「TARGET」>「info」>「URL Types」 の「+」をクリックしてIdentifier
とURL Schemes
に適切な値を入れておくだけです。
Identifier
はアプリを一意に識別できる値であれば良いのでバンドルIDなどにしておくと安心です。URL Schemes
は実際にアプリを起動させるためのスキームになるので対象アプリがスキーム名から分かるような命名を行えば基本何でも良さそうです。
この設定を行うと「info.plist」にも以下のような設定値が反映されるようになります。上記で設定した値は実際には「info.plist」で管理されているだけなので共通です。
これで実装は完了なのでちゃんと実装できているか試してみます。前提として端末に対象アプリがインストールされている必要があるので注意してください。
Safariを開いて検索欄に先ほど指定したURL Schemesの末尾に://
を付与したものを入力して確定します。
すると「このページを"対象アプリ名"で開きますか?」と出るので「開く」をクリックするとアプリを起動させることができます。
リンクが動作しない場合の原因は?
リンクが正しく動作しない場合は以下の点を確認してみてください。
- アプリがインストールされているか
- スキームが他のアプリと重複していないか
スキーム名は一部Appleネイティブアプリ用に定義されているので重複しないように注意してください。
データを受け渡す
Custom URL Schemeを使用してアプリにデータを渡すことも可能です。スキームでアプリを起動できるように設定さえしてしまえばリンクにクエリなどを使用してデータを付与するだけでデータを渡すことができるようになるので、その値に応じてアプリ内で処理を行えば特定の画面へ遷移させたり、データを保存するといったことが可能になります。
URL経由でアプリが起動した際にURLを取得するのはUIKit(Storyboard)とSwift UIで異なるので注意してください。
UIKit(Storyboard)のライフサイクルでURLを取得する
UIKit(Storyboard)のライフサイクルの場合はSceneDelegate
クラスのscene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>)
からURL経由でアプリを起動した際のリンクを取得することができます。
例えばmy-test-app://profile?user=123
のようなリンクで起動したとします。するとURLオブジェクトから対象の値を取得することができるようになります。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// 〜〜〜〜〜〜〜〜
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else {
return
}
print("URL: \(url.absoluteString)") // my-test-app://profile:8080?user=123
print("Scheme : \(url.scheme!)") // my-test-app
print("Query : \(url.query!)") // user=123
}
}
AppDelegate
のapplication(_ :, open url:, options:)
で取得できる記事をちらほらありましたが現在は(?)取得できないようなので注意してください。
SwiftUIのライフサイクルでURLを取得する
Swift UIの場合はonOpenURL
モディファイアから対象のURLを取得することができます。AppDelegate
などを実装しても変わらず取得できないので注意してください。
@main
struct LinkTestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
print("URL: \(url.absoluteString)") // my-test-app://profile:8080?user=123
print("Scheme : \(url.scheme!)") // my-test-app
print("Query : \(url.query!)") // user=123
}
}
}
}
異なるアプリ間の遷移
Custom URL Schemeを使用することでアプリAからアプリBを起動するといったことができるようになります。起動させるにはopen
メソッドを使用するだけですが少し注意点があります。
guard let url = URL(string: "my-test-appb://") else { return }
guard UIApplication.shared.canOpenURL(url) else { return }
UIApplication.shared.open(url)
LSApplicationQueriesSchemesキーの追加
アプリ内からCustom URL Schemeを使用してアプリを起動させたい場合はLSApplicationQueriesSchemes
キーの指定が必要になります。そのため「info.plist」の中にLSApplicationQueriesSchemes
キーを追加し、配列内にアプリ内から起動させたいアプリのスキームを追加してください。
例えば「アプリAからアプリBを起動したい場合はアプリAのinfo.plistにアプリBのスキームを追加」すればOKです。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。