【Flutter】AppsFlyerで実装するアトリビューション計測・ディープリンク導入ガイド
こんにちは、株式会社PentagonでFlutterエンジニアをしているTakayaです。
モバイルアプリの成長において、適切なアトリビューション計測とディープリンク実装は欠かせません。しかし、AppsFlyerのFlutter導入は管理画面設定から実装まで多岐にわたり、特にATT(App Tracking Transparency)対応やプライバシー保護の観点で迷いやすいポイントが多数存在します。
【こんな人に読んでほしい】
- FlutterでiOS/Androidアプリを開発・運用しているエンジニア
- 広告計測/ディープリンク実装をこれから行う、または改善したいチーム
- ATTやストア申請の観点を踏まえたプライバシー実装も押さえたいPM/EM
【この記事を読むメリット】
- 管理画面の初期設定(マイアプリ登録/OneLinkテンプレート)の具体的手順と要点を理解する
- Flutter SDK実装(初期化、ATT遅延、DeepLinkハンドリング)をコード付きで再現できる
- プライバシー保護方針とアトリビューション計測の実務注意点を把握する
【結論】 AppsFlyerの導入は管理画面設定→SDK実装(初期化、計測、ディープリンク)→プライバシー対応の3ステップで構成されます。適切な実装により、正確なアトリビューション計測とスムーズなディープリンク体験を実現できます。
【この記事の前提】
- Flutter: 3.24.0以降
- appsflyer_sdk: 6.14.0以降
- iOS: 14.0以降(ATT対応)
- Android: API Level 21以降
1. 初期設定(管理画面)
マイアプリ登録
AppsFlyerでの計測を開始するには、まず管理画面でアプリを登録する必要があります。
- Devキー発行:アプリ実装で使用するアカウント識別子
- 一般設定:
- Android:未公開でもパッケージ名で登録可能
- iOS:アプリIDまたはストアURLが必要(開発時点でアプリIDはダミーでOK)
詳細な手順については、AppsFlyerマイアプリ登録ガイドを参照してください。
OneLinkテンプレート
OneLinkは、AppsFlyerが提供するディープリンク機能です。事前にマイアプリ登録が完了している必要があります。
設定項目:
xxxx.onelink.me
のサブドメインを決定- 未インストール時の遷移先URLなどを設定
詳細な設定方法はOneLinkテンプレートガイドをご確認ください。
2. 実装仕様(Flutter SDK)
依存関係の追加
# pubspec.yaml
dependencies:
appsflyer_sdk: ^6.14.0
AppsFlyer機能の実装
以下は、Flutterでよく用いられる状態管理ライブラリのRiverpodを使用した、AppsFlyer管理クラスAppsFlyerManagerの実装例です。
@Riverpod(keepAlive: true)
AppsFlyerManager appsFlyerManager(Ref ref) {
final appsFlyerOptions = AppsFlyerOptions(
afDevKey: 'YOUR_DEV_KEY', // 管理画面から取得
// iOSのみAppIDが必要
appId: Platform.isIOS ? 'YOUR_APP_ID' : '',
// AppsFlyerへのデータ送信前に、ユーザーによるATT同意をどれくらいの時間待つか(60秒)
timeToWaitForATTUserAuthorization: 60,
);
final appsFlyerSdk = AppsflyerSdk(appsFlyerOptions);
return AppsFlyerManager(appsFlyerSdk);
}
class AppsFlyerManager {
AppsFlyerManager(this._appsFlyerSdk);
final AppsflyerSdk _appsFlyerSdk;
Future<void> initialize() async {
/// ディープリンクの初期化
/// initSdk(SDKの初期化)より前に処理する必要あり
_appsFlyerSdk.onDeepLinking((deepLinkResult) {
if (deepLinkResult.status == Status.FOUND) {
final deepLink = deepLinkResult.deepLink;
if (deepLink != null) {
_handleDeepLink(deepLink);
}
} else {
print('AppsFlyerディープリンクエラー: ${deepLinkResult.error}');
}
});
/// SDKの初期化
await _appsFlyerSdk.initSdk(
registerConversionDataCallback: true,
registerOnAppOpenAttributionCallback: true,
registerOnDeepLinkingCallback: true,
);
}
/// 画面表示などのイベントログの送信
Future<void> logEvent(
String name, {
required Map<String, dynamic> parameters,
}) async {
try {
await _appsFlyerSdk.logEvent(name, parameters);
print('AppsFlyerイベントログ送信成功: name=$name parameters=$parameters');
} on Exception catch (e) {
print('AppsFlyerイベントログ送信失敗: $e');
}
}
/// ディープリンクハンドリング
void _handleDeepLink(Map<String, dynamic> deepLinkData) {
final deepLinkValue = deepLinkData['deep_link_value'] as String?;
final deepLinkSub1 = deepLinkData['deep_link_sub1'] as String?;
// アプリ内ナビゲーション処理
if (deepLinkValue != null) {
// 例:商品詳細画面への遷移
}
}
}
SDK起動遅延(ATT対応)
ATT(App Tracking Transparency)とは、ユーザーのアプリ内トラッキングを制御するプライバシー機能です。ユーザーが許可しない限り、アプリはデバイスの広告識別子(IDFA)にアクセスできず、ユーザー単位の分析が難しくなります。
重要な仕様:
- AppsFlyerへのデータ送信前に、ユーザーによるATT同意をどれくらいの時間待つかを設定
- 遅延タイマーカウントはSDK初期化時に開始
- 遅延待機中の挙動:
- バックグラウンド遷移でフォアグラウンドに戻るまでタイマー一時停止、イベントはキャッシュ保持
- アプリキルで次回起動まで一時停止、キャッシュは削除
ATT同意状況別のIDFA送信パターン:
待機状況 | 同意状況 | IDFA送信 |
---|---|---|
待機内 | 同意 | あり |
待機内 | 拒否 | なし |
待機内 | 無回答→満了 | なし |
待機後 | 同意 | あり(以降継続) |
待機後 | 拒否 | なし(以降継続) |
3. アトリビューション計測
インストール計測はAppsFlyerのSDKで自動取得されるため実装不要です。CUIDとして任意のIDを送信することで社内システムなどと連携させた分析も可能です。
// ユーザーID設定例
await _appsFlyerSdk.setCustomerUserId('user_123456');
4. アプリ内イベント計測
命名・文字数制約
イベント送信に含められるkeyは45文字以下とする必要があります。
実装例
Future<void> sendPurchaseEvent({
required String productId,
required double revenue,
required String currency,
}) async {
final eventParameters = {
'af_revenue': revenue,
'af_currency': currency,
'af_content_id': productId,
'af_content_type': 'product',
};
try {
await _appsFlyerSdk.logEvent('af_purchase', eventParameters);
print('購入イベント送信成功: $eventParameters');
} catch (e) {
print('購入イベント送信失敗: $e');
}
}
5. OneLinkによるディープリンク
URL構造とパラメータ
URL例:https://your-app.onelink.me/
主要パラメータ:
deep_link_value
:メインの値(画面名など)deep_link_sub1〜10
:追加パラメータ(商品ID、記事IDなど)
具体例:
https://your-app.onelink.me/ABC1/screen?deep_link_value=product&deep_link_sub1=item_123&deep_link_sub2=campaign_summer
Flutterでのディープリンクハンドリング
void _handleDeepLink(DeepLink deepLink) {
final deepLinkValue = deepLink.deepLinkValue;
final deepLinkSub1 = deepLink.getStringValue('deep_link_sub1');
final deepLinkSub2 = deepLink.getStringValue('deep_link_sub2');
print('ディープリンク受信: screen=$deepLinkValue, deep_link_sub1=$deepLinkSub1, deep_link_sub2=$deepLinkSub2');
// アプリ内ナビゲーション
switch (deepLinkValue) {
case 'product':
_navigateToProduct(deepLinkSub1, deepLinkSub2);
break;
case 'article':
_navigateToArticle(deepLinkSub1);
break;
default:
_navigateToHome();
}
}
6. プライバシー保護実装
AppsFlyerでは、プライバシー保護のための複数の設定が用意されています。詳細はプライバシー設定ガイドをご確認ください。
// プライバシー設定例
await _appsFlyerSdk.anonymizeUser(true); // ユーザー匿名化
await _appsFlyerSdk.stop(true); // データ収集停止
まとめ
AppsFlyerのFlutter導入において重要なポイントをまとめると:
- 管理画面設定:アプリ登録とOneLinkテンプレートの事前準備が必須
- ATT対応:SDK起動遅延の適切な設定で、プライバシー要件とデータ精度のバランスを実現
- イベント設計:分析目的を果たすための出力箇所、文字数制約を考慮したイベント命名規則の策定
- ディープリンク:OneLinkパラメータの活用で柔軟なユーザー体験を提供
これらの実装により、効果的な広告計測とユーザー導線の最適化を実現できます。AppsFlyerの強力な機能を活用して、アプリの成長を加速させていきましょう!