👻

FlutterでAppsFlyerのディープリンクを導入する手順とハマりポイント

2025/01/06に公開

はじめに

最近Flutterでモバイルアプリ開発をしているkmasuです。
ディープリンクの実装でAppsFlyerのOneLinkを使用したので、AppsFlyer側の設定や上手く動かなかった際にどのような点を確認し、解決したのかをまとめようと思います。

開発環境

開発環境と使用しているサービスは以下になります。

  • flutter:3.24.3
  • Dart:3.5.3
  • Firebase App Distribution

ディープリンクとは

ディープリンクとは、Webページやスマートフォンアプリからアプリの特定コンテンツへ移動するリンクのことです。

ディープリンクの種類

ディープリンクには以下の種類があります。

  1. Custom URL Scheme
    アプリ固有のスキーム(例: myapp://)を用いたリンク形式です。
    : myapp://product/12345
    上記のようなリンクをクリックすると、アプリがインストールされている場合は商品IDが12345の詳細ページに直接遷移するようなことができます。
    アプリがインストールされていない場合は何も起きません。

  2. Universal Links
    iOS用のディープリンク技術で、アプリがインストールされていない場合はウェブページやストアページに遷移します。アプリがインストールされている場合はアプリに遷移します。

  3. App Links
    Android用のディープリンク技術で、ユニバーサルリンクと同様の動作をします。Googleが推奨する形式で、インストールされていない場合はウェブページやPlayストアなどに遷移できます。

  4. Deferred Deep Link(遅延ディープリンク)
    アプリがインストールされていない場合でも、インストール後に指定された画面へ遷移します。

本記事では主にAppsFlyer側で2と3を扱う形になります。


AppsFlyerとは

AppsFlyerは、モバイルマーケティングや広告効果測定のためのプラットフォームです。
広告キャンペーンの効果分析や、ユーザーの行動データ追跡、ディープリンクの設定等行うことができます。

OneLinkとは

OneLinkは、AppsFlyerが提供するディープリンク技術です。iOSやAndroid、ウェブを統一的にサポートしています。本記事では触れませんがDeferred Deep Linkにも対応しています。
Universal Links, App Linksを自前で用意しようとすると、apple-app-site-association, assetlinks.jsonのファイルを自前で用意したサーバに.well-knownディレクトリ配下に置き、外部からアクセスできるようにする必要があります。
開発環境で外部からアクセスさせたくない場合でもAppsFlyer側のサーバの.well-knownにファイルを自動で配置してくれるので、その辺りの煩わしさから解放されます。


OneLink作成手順

0. iOS, Android事前準備

既に済んでいる場合は飛ばしてください。

iOS

  • AppleDeveloperProgramにログイン
  • Identifiersから対象のIdentifierにAssociated Domainsのチェックを入れます

Android

内部テストで開発者内で配布しない場合は飛ばしても問題ありません。

  • google Play Consoleにログインして、内部テスト公開状態まで進めておきます

1. AppsFlyerアカウントの作成

2. アプリの作成

  • ログイン後のサイドメニューから設定→アプリ一覧→アプリの追加からアプリを追加します
  • Androidの場合は公開中であればGoogle PlayのURL、未公開であればパッケージ名を入力します
  • iOSの場合はAppStoreConnectにアプリがある場合はAppStoreConnect内のサイドメニューからアプリ情報に行き、Apple IDを入力します
    • 開発用であれば10桁のユニークな番号を入力します。AppsFlayer側で既に登録されているとエラーになって登録できません

3. OneLinkの作成

OneLinkテンプレートの追加

  • AppsFlayerのサイドメニューからエンゲージメント→OneLink管理→画面右上の縦三点リーダーをクリック→OneLinkテンプレートの追加をクリックします

OneLinkテンプレート アプリ登録, サブドメイン

  • プラットフォームに先ほど作成したアプリを登録します
  • ユニークなサブドメインを入力します
    • ここで入力したものがディープリンクのドメインになります
    • 例)hogehoge.onelink.me

OneLinkテンプレート リダイレクト

アプリがインストールされていない場合
  • ウェブページに遷移させたい場合は該当のURLを入力します
  • ストアに遷移させる場合はそのまま進みます
アプリがインストールされている場合
iOS
  • Universal Linksを使用してアプリを起動するをクリック, ラジオボタンを選択
  • AppleDeveloperProgramでIdentifierを開き、App ID Prefix(teamID)Bundle IDをコピー&ペーストします
  • 開発の場合はテストアプリの追加をクリックし、同様にコピー&ペーストします
Android
  • App Linksを使用してアプリを起動するをクリック, ラジオボタンを選択します
  • アプリビルド時に使用するkeystoreのSHA256フィンガープリントを入力します
    • 以下確認コマンド例です
    • $ keytool -list -v -keystore android/debug.keystore or upload-keystore.jks
  • 後述しますがApp Distribution等を使っている場合は追加で再署名されるSHA256フィンガープリントを入力します

URIスキームのフォールバック
  • 上記の設定でディープリンクが起動しなかった際に呼ばれるCustom URL Schemeを設定できます
  • iOSの場合はoneLinkのパラメータにaf_force_deeplink パラメーターを設定しないと、機能しません
  • 設定するとOneLinkでCustom URL Scheme開く際に確認ダイアログがでます
デスクトップ上でリンクがクリックされた場合
  • 自前のウェブページなどがある場合、PCでディープリンクをクリックした際にウェブに飛ばしたい時に設定します
  • 設定する場合はURLを入力します

テンプレートの作成をクリックします。

  • 上記のテンプレートの作成が完了したら新しいリンクからリンクを作成します
  • ディープリンクの確認だけであれば各項目そのままで作成して問題ありません
    • 本記事では割愛します。
  • https://OneLinkサブドメイン/テンプレートID/URL IDのリンクが作成されます

実装側にコード追加

iOS
  • Runner.entitlementsに以下を追加します
<?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>
            <string>applinks:hoge.onelink.me</string>
        </array>
	</dict>
</plist>
Android
  • AndroidManifest.xmlに以下を追加します
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <data android:scheme="https" android:host="applinks:hoge.onelink.me"/>
</intent-filter>
appsflyer-flutter-pluginの導入
  • ディープリンクの遷移自体に影響しませんが、起動後に何かしら処理をさせたい場合に必要なので触れておきます。
  • READMEに従ってSDKを導入します
  • 詳細は本記事では割愛します

https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/tree/master

作成したURLをクリックして正常に遷移すれば完了です。


ハマりポイント

ここからは遷移しなくてハマった点やどう解決したかなどを書きます。

iOSで遷移しない

自分の場合はRunner.entitlementsに追記してあるものの、追記前の箇所でエラーになりapplinksの箇所が通らなくなっていたのが原因でした..

気づいた手順は以下になります、

  • まずはAppsFlyerの.well-knownにapple-app-site-associationが配置されているかを確認します。

    • https://onelinkサブドメイン/.well-known/apple-app-site-associationにアクセスするとp7mファイルがDLされるのでテキストエディタで開きます
    • 以下のようになっていれば問題なく配置されています
      • {"appclips":{"apps":[省略]},"applinks":{"apps":[],"details":[{"paths":["/URL ID/*"],"appID":"チームID.bundleID"}]}}
  • AppsFlyerは問題なかったので、xcodeのコンソールを有効にしてアプリ起動時のログを確認します

    • xcodeのView→Debug Area→Activate Consoleで表示されます
    • xcodeでビルドしたアプリ起動時にRunner.entitlementsの処理が走り, .well-knownを確認しに行っているので、処理の前にエラーが起きていてエラーログが吐き出されてるのが確認できました

Runner.entitlementsでエラーを起きないように修正後、遷移するようになりました。

Androidで遷移しない

自分の場合の原因はOneLinkテンプレートの作成の項で記載したFirebase App Distributionを使用している場合に該当して遷移しませんでした。また、設定しても遷移しなかったので解決した手順を書きます。

気づいて解決した手順は以下になります。

まずはAppsFlyerの.well-knownにassetlinks.jsonが配置されているかを確認します。

  • https://onelinkサブドメイン/.well-known/assetlinks.jsonにアクセス
    • package_name, sha256_cert_fingerprintsの値が正しく入っていれば配置されています。
  • バイナリのフィンガープリントが一致しているかを確認します。
    • $ keytool -printcert -jarfile aabファイルのpath
    • ここで一致していなければ一致するようにAppsFlyer側のフィンガープリントに追加する等します。
  • アプリを端末にインストールしてディープリンクが起動するか確認します。
    • ここでも遷移しない場合は、adbコマンドでapplinksの検証が済んでいるかを確認します。
      • $ adb shell pm get-app-links パッケージ名
    • Domain verification state:が1024やdeniedなど出ていたら検証に失敗した状態なので再度検証を走らせます。
      • 時間が経てば自動で再検証してくれるようですが、結果がリセットされないと再検証してくれないようなので手動で再検証の実行をさせてしまう方が早いかと思います。
    • appliknsの状態をリセットするコマンドを叩きます。
      • $ adb shell pm set-app-links --package パッケージ名 0 all
    • 再度検証するコマンドを叩きます。
      • $ adb shell pm verify-app-links --re-verify パッケージ名
    • 再度確認コマンドを叩いてDomain verification stateがverifiedになっていることを確認します

これでディープリンクが機能するようになりました。

おわりに

FlutterでAppsFlyerのディープリンクを使用する手順やハマった点などをまとめてみました。
Dynamic links 終了などでAppsFlyerを使ったりする場合などで少しでも参考になれば幸いです。

参考

レバテック開発部

Discussion