猿でもわかるDeepLinkとアプリ実装虎の巻

2025/01/15に公開

DeepLinkってのは、当該アプリ以外の何か(メール、LINE、Slack)などから、対象ドメインのリンクを踏んだときに、ブラウザではなくネイティブアプリを起動させて、任意の画面を表示すること。iOSだと Universal Linkって言葉だったように思う

他のアプリから当該リンクを踏んだら、自分で作ったアプリが起動してほしいけど、アプリを起動するOSの立場に立つと、どのリンクで起動すればいいか、わかんない。

そのため、各OSは、踏んだリンクがどのアプリで verfiry されているかを検証するわけ。検証するには、私のアプリは、zenn.devのリンクを踏んだら自動でアプリを起動するような設定を行ってますと明示しないといけない。

必要な設定

仮にDeepLinkを発動したいホストが zenn.devだとする。

JSONを作る

  • Androidは assetlinks.jsonというファイル名で/.well-known/assetlinks.jsonにおく。
  • iOSは、apple-app-site-associationというファイル名で./well-known/apple-app-site-association 配下に置く。

メルカリさんだとこんな感じだね。実際においてある。

アプリにDeepLinkやるぞと設定する

  • Androidは、AndroidManifest.xmlにDeepLinkで起動するという設定をいれる。
  • iOSは、info.plistの中にAssociated Domainを仕込む。
  • Androidは、AndroidManifest.xmlで、パスとスキームを指定して、この場合に限りDeepLinkを発動するよっていう指定を行う。iOSは上述の通り。

DeepLink発動したことをアプリで捕まえたい

  • 各ネイティブにおいては、DeepLinkが発動したことを捕まえるイベントハンドラがあった記憶。iOSは、UIApplicationのdelegateにあるし、AndroidはonNewIntent。確かそう。
  • Flutterの場合は、MaterialAppがDeepLinkを発動したことを捕まえる役目を担う。Router APIなら、 MaterialApp.routerを使えば、DeepLinkが発動したことをrouterが検知できる。
  • 昔はmaterialAppにキーワード引数があって、そこでイベントハンドラを実装していたような
  • GoRouterは、Flutterチームが涙目になりながら作ったRouter APIのラッパー
  • GoRouterのおかげで、我々はRoute定義と呼応するパスを定義するだけ。上記の設定さえすればDeepLink対応が可能になる。
  • /sale に対してSaleRouteを作っておけば、他のアプリが/saleのリンクを踏むとSaleRouteに遷移して、対象のWidgetできる。
  • そうはいっても、パス定義とRoute定義が一致しないことがある。よくあるのがWebView対応。特定のパスはWebサイト上のページを出すけど、WebViewを表示するRouteは1個にしたい。その都度WebView固有の設定を埋め込んだWidgetを作るとコピペの嵐になる。
  • その時に使うのがGoRouterのredirect。Router API経由で画面遷移があったときに発動するイベントハンドラで、遷移先を書き換えることができる。/saleに来たけど諸般の事情で/future_saleに飛ばす的な。
  • Redirectの戻り値はString?で、nullであればどこにもリダイレクトせず、指定されたRouteに行く、non null であれば、戻り値で書かれたパスに該当するRouteに飛ぶ。
  • どのRoute定義にマッチしない場合、例外が出る。exception:で指定した処理が呼び出される。
  • SalesForceでメルマガ配信するとSalesForceのリンクになる。ここでは、サービス上のどのURLかはわからないので、自動でリダイレクトさせる設定でHttpクライアントからリクエストを投げ、展開後のURLでリダイレクトさせるなどがある。

遅延リンク

  • リンクを評価するタイミングが即時でないことを指す。アプリ入ってれば/saleでセールに行く。でも、入ってないならブラウザ起動しちゃう。
  • それは困るって話で、リンクを踏んだらアプリを入れてインストール後にリンク先に飛ばすっていうニーズが有る。これが、遅延リンク。Defered Deep Link などとも言う。
  • 遅延リンクがなんで大事かと言えば、多分ほぼ一択だけど、どの広告媒体や訴求メッセージを出せば、最もアプリを入れて起動してくれるかの効果測定が可能だから。クーポン20%OFFが受けるのか、あのSHIPSが最大70%OFFが受けるのか、出たとこ勝負。
  • なので、その広告経由でどれだけ新規ユーザーを捕まえることができるかを知ることができるか、それが大切になる。広告媒体だけでは実現できず、広告を踏んだあとに任意のページに飛ばすリンクとGoogleの広告を踏んだ端末ID紐づけて管理できるサービスが有って、代表的なのが AdjustとAppsFlyer。

俺達のFirebase Dynamic Linksよ・・・

まさにDeepLinkの十徳ナイフ的なサービスだったよ。。。

  • DeepLinkの機能を自動で作ってくれる。確か、assetlinks.json なども自動で作ってくれた記憶がある。マニュアルアップロードの記憶がない。
  • ホスト名は xxx.page.link になる。xxxは世界でユニークである必要がある。ドメインだから。
  • SDKによって、DeepLinkによってアプリが起動したことを簡単に検知できる。FCMと同じように、FirebaseDynamicLinks.instance.onLink.listenって感じでコールバックを定義すれば、DynamicLinksが発動したか否かがわかる
  • Googleだから、Google Analyticsとも連携できる。勝手にやってくれる。
  • https://example.page.link/?link=https://example.com/some-page&apn=com.example.app&isi=123456789&ibi=com.example.app みたいなリンクを作れば、遅延リンクとしても機能するらしい。やったことない。
  • これ全部無料!!!!!! ゴッド・オブ・神!!!

しかしながら、2025 年 8 月 25 日をもって、Firebase Dynamic Linksというサービスは終了となる。なので、ネイティブアプリ界隈がざわついた。

もうDeepLinkをさばくのは飽きた。Remix(RRv7)に切り替えていく。

Discussion