【Swift/iOS】ユニバーサルリンクの実装方法!Laravelでの実装
この記事からわかること
- Swift/iOSのユニバーサルリンク(ディープリンク)の実装方法
- Custom URL Schemeとの違い
- apple-app-site-accosiationとは?
- Laravelで実装しているサーバーで動作させる方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:16.0
- iOS:18.0
- Swift:5.9
- macOS:Sonoma 14.6.1
ユニバーサルリンクとは?
iOSの「ユニバーサルリンク」はディープリンクの一種でアプリを直接起動させることができるリンクのことです。ユニバーサルリンクを使用することでリンククリック時にアプリを起動させるだけでなく、アプリ側で処理を記述しておくことで特定の画面を開いた状態で起動させたりデータのやり取りなどを行うことも可能になっています。
ユニバーサルリンクでは設定したドメインにアクセスするだけで対象のアプリを開くことができるようになります。
Custom URL Schemeとの違い
同じようなディープリンクにCustom URL Schemeがあります。これは独自で設定した固有のスキーム(例:my-test-app://
)を使用してアプリを起動させることができます。
Custom URL Scheme | ユニバーサルリンク | |
---|---|---|
スキーム | 任意のスキーム | HTTPS |
アプリ未インストール時の挙動 | 動作しない | Webページを開く |
競合のリスク | スキームが被ると動作しない | なし |
実装方法 | アプリで完結 | サーバーへの設置も必要(※) |
ユニバーサルリンクの実装方法
実装のSTEP
- サーバー側にapple-app-site-associationファイルを設置
- アプリ側にAssociated Domainsを追加
実装のSTEPは大きく分けると上記の2つです。どちらかというとサーバー側の作業の方が多い感じになります。
サーバー側にapple-app-site-associationファイルを設置
サーバー側にはユニバーサルリンクを動作させるための設定ファイルapple-app-site-association
を設置する必要があります。この設定ファイルはJSON形式で起動対象のアプリと起動対象のリンクを指定します。JSON形式のファイルですが拡張子.json
などは必要ありません。
{
"applinks": {
"apps": [],
"details": [{
"appID": "[TeamId].[バンドルID]",
"paths": ["*"]
}]
}
}
appID
にはチームIDと対象アプリのバンドルIDを.
で繋げたものを指定します。paths
にはリンクのドメイン配下のパスを指定します。,
で複数指定することも可能です。
"paths": [ "/myapp", "/myapps/2024/*"]
apple-app-site-association
の作成ができたらサーバーに設置します。その際に注意することhは以下の2点です。
- サーバーのルートまたは.well-knownサブディレクトリに配置
- Content-Typeはapplication/jsonを指定
1.サーバーのルートまたは.well-knownサブディレクトリに配置
配置する場所はpublic_html
の直下または.well-known
ディレクトリを作成してその直下に配置します。
├── ドメインディレクトリ
│ ├── public_html
│ ├── apple-app-site-association
--------- or ------------
│ ├── .well-known
│ ├── apple-app-site-association
:
2.Content-Typeはapplication/jsonを指定
アクセスされた時のContent-Type
をapplication/json
に変更するように指定しておきます。ここはサーバーによって最適な方法で実装できていればOKです。
<Files "apple-app-site-association">
ForceType application/json
</Files>
サーバーへの設置とContent-Type
の設定が完了して正常に動作していればhttps://app-site-association.cdn-apple.com/a/v1/ドメイン
にアクセスすると設置したJSONが返却されるようになります。
$ curl -v https://app-site-association.cdn-apple.com/a/v1/ドメイン
* Request completely sent off
< HTTP/1.1 200 OK
< Apple-From: https://ドメイン/apple-app-site-association
< Apple-Origin-Format: json
< Cache-Control: max-age=21600,public
< Content-Length: 98
< Content-Type: application/json
< Date: Wed, 18 Dec 2024 10:52:45 GMT
< Age: 8581
// 〜〜〜〜〜〜〜〜〜〜〜〜〜
<
* Connection #0 to host app-site-association.cdn-apple.com left intact
{"applinks":{"apps":[],"details":[{"appID":"チームID.バンドルID","paths":["*"]}]}}
これでサーバー側の準備は完了です。
アプリ側にAssociated Domainsを追加
アプリ側の設定は「+ Capability」から「Associated Domains」を追加してapplinks:ドメイン名
を追加するだけです。
これで設定したドメインのURLにアクセスした際に対象のアプリがインストールされていれば以下のように「"対象アプリ名"アプリで開く」と表示されるようになり、クリックすることでアプリを起動させることができるようになります。
データの受け渡し
アプリを起動した際のURLはSwiftUIであればonOpenURL
から取得することができます。URLにクエリ情報などを持たせることでアプリ側からデータを参照することができるのでその値に応じて画面を遷移させたり特定の処理を行うことも可能になっています。
struct RootView: View {
var body: some View {
VStack(spacing: 0) {
}.onOpenURL { url in
// ユニバーサルリンクで起動した際のURL
print("URL: \(url.absoluteString)") // https://ドメイン/profile?user=123
print("Query : \(url.query!)") // user=123
}
}
}
おすすめ記事:URLでのデータの渡し方
Laravelでapple-app-site-associationを設置する
Laravelでサーバーサイドを構築している場合apple-app-site-association
の設置場所に迷いました。結果web.php
で以下のように指定するのが一番スマートでわかりやすかったので共有しておきます。
Route::get('/apple-app-site-association', function () {
return response()->json([
"applinks" => [
"apps" => [],
"details" => [
[
"appID" => "[TeamId].[バンドルID]",
"paths" => ["*"]
]
]
]
])->header('Content-Type', 'application/json');
});
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。