iOS 14 の Universal Links の変更点
Photo by Joseph Barrientos on Unsplash
こんにちは、Wantedly で iOS エンジニアをしている樫原 (@kashihararara) です。
この記事は、2020年12月22日 にオンライン開催された potatotips#72 で発表した「iOS 14 からの Universal Links」を記事にしたものです。
[事の発端] QA 環境で Universal Links が動かない!
とある日のこと、QAさんからバグの報告がありました。バグの内容を聞いてみると「QA版アプリの環境だけ、すべての Universal Links が効かずアプリが立ち上がらない」というものでした。
更に詳しく調査をすると、iOS 14 かつ QA版アプリ という条件でのみ Universal Links が動いていないということが判明しました。
更に上記の条件でアプリインストール時の通信をProxyManで確認してみます。すると、https://app-site-association.cdn-apple.com というドメインに対してリクエストをしていることがわかりました。
今までの Universal Links では解決したいURLのドメイン (例えば https://wantedly.com) の /.well-known/apple-app-site-association あるいは /apple-app-site-association にリクエストしていたはずです。一体何が変わったのでしょう?
(~ iOS 13) Universal Links の解決
おさらいですが、iOS 13 までは次の手順で Universal Links が解決されていました。
1. entitlement ファイルの applinks に書かれたドメインの /apple-app-site-association にGETリクエストする
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
// 📝 次の2つに、GETリクエストを送る
// https://people.wantedly.com/.well-known/apple-app-site-association
// https://people.wantedly.com/apple-app-site-association
<string>applinks:people.wantedly.com</string>
</array>
...
</dict>
</plist>
2. GETリクエストで取得した関連ドメインファイル(JSON 形式) にアプリの appID があれば、該当するパスを満たすURLをシステムがハンドリングする際にデフォルトブラウザではなくアプリが開くようになる。
{
"applinks": {
"apps": [],
"details": [
{
// 📝 https://people.wantedly.com/projects というURLと、
// 識別子が "42Z77KT2BJ.com.wantedly.app" のアプリを紐付けている。
"appID": "42Z77KT2BJ.com.wantedly.app",
"paths": [
"/projects",
...
]
}
]
}
}
図で表すとこうです。
(iOS 14 ~) Universal Links の解決
iOS 14 の Universal Links の変更点は2つあります。
① 端末から Apple CDN URLにリクエストするようになった
今までは、https://people.wantedly.com/apple-app-site-association
等に直接端末からリクエストが飛んでいましたが、iOS 14 からは Apple CDN と呼ばれている
https://app-site-association.cdn-apple.com
にリクエストが飛ぶようになりました。
また、WWDC 2020 の What's new in Universal Links というセッションによると、今までは関連するドメインが複数あった場合はその数だけドメインをまたいでリクエストを行っていましたが、これが Apple CDN に対して1回のリクエストだけ全てのドメインの apple-app-site-association を取得できるようになったそうです。
It can download the apple-app-site-association files for all of these domains concurrently, cache them, and send the data to the device with a single network connection.
② ドメインの /apple-app-site-association は Apple CDN からリクエストを受けるようになった
① では 端末が Apple CDN から apple-app-site-asscotiation を取得するとを説明しましたが、それではあなたのドメインの apple-app-site-association はどのように Apple CDN に取り込まれるのでしょうか?
Apple CDN がクローラを使って各ドメインの apple-app-site-association を収集しているとのことです。ただしこのクローラについての詳細な仕様はまだ Apple から公開されていません。
まとめ
QA 環境で Universal Links が動かなかった話に戻ります。こうして Universal Links 自体の挙動が変わっていたことがわかると原因の特定は簡単で、QA 環境のサーバに IP制限 がかかっていて Apple CDN のクローラが /apple-app-site-association を取得できなかったことが原因でした。
対応としては、entitlement の applinks のURLに ?mode=developer
というオプションがあるためこれを利用すると、Apple CDN をバイパスして直接ドメインの /apple-app-site-association を取得しにいくようになります。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
// 📝 加えて、端末の開発者モードで `Associated Domains Development` をONにする必要がある
<string>applinks:people.wantedly.com?mode=developer</string>
</array>
...
</dict>
</plist>
詳しくは Apple の Associated Domains Entitlement ドキュメントにまとめられています。