web側がユニバーサルリンクの対応するときの備忘録

# ユニバーサルリンクの対応【web】

## ユニバーサルリンクの設定についての備忘録

とあるプロジェクトで苦労したユニバーサルリンクについての備忘録を書いていきます。順を追って困った時何をしたか、仕様について書いていこうと思います。

### ユニバーサルリンク(Universal Links)とは
ios9からこの仕組みが利用できるようになりました。
webサイトをクリックしたときにiOSアプリを起動するための手法のことです。ディープリンクの一種です。


### もともとのお客様の求めている仕様はというと
**「アプリを持っているときはアプリへ、持ってないときはAppStoreに飛んでほしい」** というものでした。
URLスキームであれば昔対応したことがあったのですが、ユニバーサルリンクは初めてでした。URLスキームと大して仕様かわらないっしょ！なんて軽い気持ちでいたがそんなことはなく、かなり大変でした。

### 実装するにあたって必要な作業
ここからはios、web、サーバーで協力が必要だった必要作業です

#### apple-app-site-associationのファイル設定
ios側にユニバーサルリンクの設定が有効になるようにドメイン設定はしてもらうことはもちろんのこと(ios側の話は割愛です)、web側でも有効になるようにapple-app-site-associationというファイルを用意する必要がありました。

このファイルの注意点として、
* ファイル名をapple-app-site-associationから変えてはいけない
* ファイルはhttps://example.com/.well-known/apple-app-site-association または https://example.com/apple-app-site-association のようにルートディレクトリ、.well-knownサブディレクトリに配置します。
* このファイルは必ずHTTPSのwebサーバーに設置する

自分が担当したものでは.well-knownサブディレクトリに配置しています。
web側では開発環境ごとにapple-app-site-associationの中身が違っていたので、ファイル名についてはapple-app-site-association-環境　という風にしておいて、ビルド時に「‐環境」の部分を外して使ってました。

team idとbundle identifierをiosチームからもらうようにしましょう。
apple-app-site-associationで設定されるappIDは
team id+bundle identifierとなります。

```json
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "team id+bundle identifier",
                "paths": [
                  "NOT /webview/passwordreset",
                  "*"
                ]
            }
        ]
    }
}
``````


#### 同ドメインではweb⇒アプリに遷移しない問題があった
https://example.com/webview/authentication を閲覧中で、このドメインから https://example.com/ に遷移する際、アプリを持っていたらアプリに飛ぶ
という挙動にしたい場合、https://example.com/ が同ドメインだとアプリに遷移しません。(アプリに遷移するボタン等があった場合、気を付ける必要があった)

https://example.test.jp/　 ⇒　遷移　⇒　https://example.com/
という風にドメインを変える工夫が必要です。

自分が担当したところでは、
https://website.jp/ こちらのドメインでユニバーサルリンクを設置していたため、
https://uni.website.jp/ (web or アプリ遷移用ボタン設置)　⇒　https://website.jp/ とすることでアプリを持っていたらアプリに遷移するということを実現できました。


公式も凄く小さく注意書きしてあります。見逃します。。
[App Search Programming Guide: Support Universal Links](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html)

まずこちらで準備は完了です。


### ユニバーサルリンクが起動する条件
* ユーザーアクションによる(URLをクリックする)遷移であること
  * JSでのリダイレクトでは発動しません
  * URLを直接検索バーに入力して遷移しても起動しません
  
* ドメインが変わること
* webに遷移した時でもサイト上部にユニバーサルリンクが設置していること(一度ユニバーサルリンクをクリックしてかつアプリを持っていれば以降アプリを開くようになる)

### ユニバーサルリンクが起動しなくなってしまう条件
* apple-app-site-associationを設置しているサイトのURLを長押しすること
  * これをするとアプリをもっていようがwebに遷移されます
* httpsではない
* ブラウザがSafariではない
* アプリで特殊なハンドリングをされてないこと(パラメータ等を受け取って指定したアプリのページを開くようにしましょう)

### apple-app-site-associationを更新した時
※2020/09/03追記
apple-app-site-associationを更新した時にユニバーサルリンクが立ち上がらなくなる場合があります。
その場合、apple-app-site-associationファイルを設置したwebサイトにはユニバーサルリンクが表示されなくなったりします。
対策を調べていたところ、このような記事を見つけました。
[apple-app-site-associationファイルを更新してからアプリに反映されるタイミング - はい！今やってます！](https://yuji-ueda.hatenadiary.jp/entry/2017/03/16/172144)
[apple-app-site-association jsonファイルはアプリで更新されますか?](https://www.366service.com/jp/qa/faa2997480ba451c197953962cfcc153)
[Does the apple-app-site-association json file ever get updated in app?](https://stackoverflow.com/questions/35187576/does-the-apple-app-site-association-json-file-ever-get-updated-in-app)

要はアプリバージョンを変更するか、アプリを再インストールすると再度apple-app-site-associationを読みにいってくれるようなのです。
自分のプロジェクトではアプリ再インストールで解消しました。


### ちなみに
最初にお客様が言っていたアプリを持ってない場合にAppStoreに遷移させたいという内容はユニバーサルリンクの観点だけで書くと不可能でしたので、仕様にしてもらいました。
[Apple Developer Documentation](https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content)
アプリを持ってない場合はwebに飛ぶ仕様です。
自分の担当したところではアプリに遷移しない場合setTimeoutでappStoreに飛ぶように実装してましたが、ユニバーサルリンクの仕様とバッティングしてうまくいかず、webに飛んだりAppStoreに飛んだりしまいました。ユニバーサルリンクではwebに飛ぶのが仕様なのでAppStoreに飛ばす際は[OneLink™ 概要 – ヘルプセンター](https://support.appsflyer.com/hc/ja/articles/115005248543-OneLink-%E6%A6%82%E8%A6%81)などの計測リンクを使ったり、webページに飛んでしまった時にAppStoreにリダイレクトするなりをしたほうがよさそうです。今回は部分的にoneLinkでアプリの有無判定を行っています。

### 参考リンク
[apple-app-site-associationのpaths(遷移対象パス)の作り方（UniversalLinks対応） - Qiita](https://qiita.com/keroppi0_0/items/1a7fab4a8cc78412d30c)
[UniversalLinksでのお問い合わせ,運用事例 - Qiita](https://qiita.com/keroppi0_0/items/c1a2910414b323df76f0)
[[Swift] 同一ドメインでのユニバーサルリンク(Universal Links)は動作しないので注意 - Qiita](https://qiita.com/takashico/items/dafb0a749bca8156ddd6)
[iOSアプリのユニバーサルリンクの仕組み - lasciva blog](https://15dog.hatenablog.com/entry/2019/03/06/iOS%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E3%83%A6%E3%83%8B%E3%83%90%E3%83%BC%E3%82%B5%E3%83%AB%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF)

ios13になったことで変わった仕様もあるようです。
[UniversalLinks（ユニバーサルリンク）「apple-app-site-association」の書き方　パラメーター対応（iOS13以降） - Qiita](https://qiita.com/gurensouen/items/4fc282b91dff468cf9ed)