4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AppsFlyerAdvent Calendar 2022

Day 20

はじめてのAppsFlyer: (3) iOS SDKでのATTフレームワークの実装

Last updated at Posted at 2022-12-19

前記事「はじめてのAppsFlyer: (2) iOS SDK実装/iOSシミュレーターでの動作確認」の続きの内容となります。
iOS SDKの実装においては、ATTフレームワークの考慮が必要です。AppsFlyer SDKを利用する際に、ATTフレームワーク実装において事前に考慮すべき点や、具体的な実装方法、iOSシミュレーターでの動作確認について解説します。

ATTフレームワークとは?

ATT (App Tracking Transparency) フレームワークとは、AppleがiOS14より導入したユーザープライバシー保護のための方式です。アプリがIDFAを取得するために、定型のポップアップを表示してユーザーに明示的な許可を得ることが必要になりました。以前は、ユーザーが設定でオプトアウトしていない限りはアプリはIDFAの取得ができたのですが、iOS 14.5以降、アプリがIDFAを取得するためにはポップアップでの許可が必須になりました。

ATTフレームワークの実装はオプションであり、IDFAを使わない場合にはこの実装は不要です。ただし、IDFAがないと広告の効果測定ができないアドネットワークもあるため、より正確にアトリビューションを行うことを目指すのであれば、ATTフレームワーク実装が必要となります。

Screenshot 2022-12-19 at 20.35.10.png

AppsFlyerでのATTフレームワーク実装

ATTフレームワークを実装しない場合には、AppsFlyer SDK開始後、直ちにインストール計測が行われますが、ATTフレームワークを実装する場合には、AppsFLyer SDKは開始後すぐにインストール計測を行わずに、指定された「タイムアウト期間」はインストール計測を遅延させます。

このタイムアウト期間の間にユーザーからATT許諾を得られた場合には、その時点で直ちに取得したIDFAの情報を元にインストール計測を行います。
逆にユーザの"Appにトラッキングしないように要求"を選んだ場合や、タイムアウト期間内にユーザーがどちらも選択しなかった場合には、IDFAなしでインストール計測を行います。

Screenshot 2022-12-19 at 20.41.20.png

ATTフレームワーク実装手順

ここからは具体的な実装方法について解説します。

  • 前記事 のようなSDK実装が完了していることを前提として、ATTフレームワークを追加実装する方法となります。
  • AppsFlyer SDKはATTフレームワークに対応しているv.6以上で実装されていることを前提とします。

1 - ATTポップアップのメッセージを定義する

Info.plist内にNSUserTrackingUsageDescriptionというパラメーターとして定義します。NSUserTrackingUsageDescriptionと入力すると、Privacy - Tracking Usage Descriptionに自動的に置き換わりますが、この行のValueとして、メッセージを入力します。

例: 「パーソナライズされた広告を配信するためには許可を選んでください。」

image.png

備考
実際にアプリをリリースする際には、このメッセージをどのような文言にするのかは、結構重要なトピックであり、アプリの特性に合わせた考慮が必要です。
メッセージを検討する上で参考になりそうな情報のリンクを貼っておきます。

2 - requestTrackingAuthorizationの呼び出し

ATTポップアップを表示したい箇所でrequestTrackingAuthorizationを呼び出してください。

例えば、アプリ起動直後にATTポップアップを表示したい場合には、下記のようにdidBecomeActiveNotification内のAppsFlyerLib.shared().start()直後に呼び出します。

AppDelegate.swift
@objc func didBecomeActiveNotification() {
    // start is usually called here:
    // AppsFlyerLib.shared().start()
    if #available(iOS 14, *) {
      ATTrackingManager.requestTrackingAuthorization { (status) in
        switch status {
        case .denied:
            print("AuthorizationSatus is denied")
        case .notDetermined:
            print("AuthorizationSatus is notDetermined")
        case .restricted:
            print("AuthorizationSatus is restricted")
        case .authorized:
            print("AuthorizationSatus is authorized")
        @unknown default:
            fatalError("Invalid authorization status")
        }
      }
    }
}

アプリ内でスタートボタンを押したタイミングでATTポップアップを表示させたいなどの場合は、任意のアクションを定義して、その中で呼び出すことも可能です。

ViewController.swift
@IBAction func tapStart(_ sender: Any) {
    if #available(iOS 14, *) {
      ATTrackingManager.requestTrackingAuthorization { (status) in
        switch status {
        case .denied:
            print("AuthorizationSatus is denied")
        case .notDetermined:
            print("AuthorizationSatus is notDetermined")
        case .restricted:
            print("AuthorizationSatus is restricted")
        case .authorized:
            print("AuthorizationSatus is authorized")
        @unknown default:
            fatalError("Invalid authorization status")
        }
      }
    }
}

いずれの箇所で呼び出した場合にも、requestTrackingAuthorizationを記述したファイルではAppTrackingTransparencyのインポートが必要になりますので、こちらも忘れずに追加します。

import AppTrackingTransparency

参考: Apple Developer - requestTrackingAuthorization(completionHandler:)

3 - waitForATTUserAuthorizationの設定

AppDelegate.swiftのSDKの初期化の箇所で、waitForATTUserAuthorizationを呼び出してください。AppsFlyerLib.shared().start()の前に呼び出されていることが必要になります。

AppDelegate.swift
AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)

timeoutIntervalの値には、SDK開始後、ATTの許諾ダイアログを表示してからユーザーが操作するまでに十分な時間が確保できるような値を秒数で指定してください。
timeoutIntervalの指定例:

  • アプリの初回起動時にATTポップアップを表示する場合: 60秒程度
  • 約2分のチュートリアルの完了後にATTポップアップを表示する場合: 180秒程度

注意
requestTrackingAuthorizationを実装していないのに、waitForATTUserAuthorizationだけ呼び出すのは避けてください。
無駄にタイムアウト期間分のみインストール計測を遅延させてしまうだけになります。

また、「いつATT許諾されるかわからないので、timeoutIntervalを例えば1時間後(3,600秒後)など大きな値を設定する」というのはアンチパターンです。
定義通りであれば「ユーザーからの回答が得られないままタイムアウト期間が過ぎた場合には、その時点でインストール計測される」のですが、そのアプリが非アクティベートされたら、アプリに実装されているSDKも動作しません。つまり、タイムアウト期間を過ぎた1時間後のタイミングでインストール計測される可能性は低く、その後もう一度アプリを起動したタイミングで初めてインストール計測されることになってしまいます。
結果的に実際のインストール数と乖離した計測結果になりうるので、このような実装は避けるべきです。

動作確認

上記の実装を行うと、ATTポップアップが表示され、IDFAが取得できることを確認できます。
requestTrackingAuthorizationの呼び出しはアプリ内でスタートボタンを押したタイミングでATTポップアップを表示させる実装を行い、iOSシミュレータでの動作確認をし、デバッグログの中身を検証してみます。

Screenshot 2022-12-19 at 22.20.44.png

1 - 「Appにトラッキングしないように要求」を選択した場合

ATTポップアップ表示後、「Appにトラッキングしないように要求」を選択し、そのデバッグログをみるとATT許諾のステータスがdeniedになったことが確認できます。

AuthorizationSatus is denied
2022-12-19 22:12:50.003118+0900 AdventTest[34984:3506825] [AppsFlyerSDK] [com.appsflyer.serial] [ATT] Tracking authorization update from `oldStatus`: 0 to `newStatus`: 2
2022-12-19 22:12:50.003550+0900 AdventTest[34984:3506825] [AppsFlyerSDK] [com.appsflyer.serial] Denied/Restricted
2022-12-19 22:12:50.003949+0900 AdventTest[34984:3506825] [AppsFlyerSDK] [com.appsflyer.serial] Denied/Restricted

また、IDFAを示すadvertiserIdがnullであることが確認できます。

{"timestamp":"1671455570.107637","uid":"1671455556104-2851091","bundlename":"","cell":
{"mcc":"tv|sim", ...,"att_status":2,...,"advertiserId":"", ...

2 - 「許可」を選択した場合

一度iOSシミュレータのアプリを削除し、もう一度アプリをデプロイし、アプリを起動するとATTポップアップ表示されます。
「許可」を選択すると、ATT許諾のステータスがauthorizedになったことが確認できます。

AuthorizationSatus is authorized
2022-12-19 22:16:11.097623+0900 AdventTest[37931:3520243] [AppsFlyerSDK] [com.appsflyer.serial] [ATT] Tracking authorization update from `oldStatus`: 0 to `newStatus`: 3
2022-12-19 22:16:11.139215+0900 AdventTest[37931:3520245] [AppsFlyerSDK] [com.appsflyer.serial] Dynamically loaded library: AdSupport
2022-12-19 22:16:11.146197+0900 AdventTest[37931:3520249] [AppsFlyerSDK] [com.appsflyer.serial] dlopen
2022-12-19 22:16:11.146506+0900 AdventTest[37931:3520248] [AppsFlyerSDK] [com.appsflyer.serial] dlopen

IDFAを示すadvertiserIdはALL0の値になってます。
これはiOSシミュレーターがIDFAを持たないためであり、実機デバイスで確認するとその端末のIDFAの値がみられます。

{"timestamp":"1671455766.846198","uid":"1671455761926-8537326","bundlename":"","cell":
{"mcc":"tv|sim", ...,"att_status":3,...,"advertiserId":"00000000-0000-0000-0000-000000000000", ...

3 - タイムアウト期間超過の場合

デバッグログ上では、AppsFlyer SDK開始のメッセージ後、ちょうど60秒後のタイムアウトのタイミングで"ATT timer expired"になったことが確認できます。

2022-12-19 22:06:27.719555+0900 AdventTest[31579:3491202] [AppsFlyerSDK] [com.apple.main-thread] AppsFlyer SDK version 6.9.1 started build (92)
...
2022-12-19 22:07:27.962460+0900 AdventTest[31579:3493682] [AppsFlyerSDK] [com.appsflyer.serial] [ATT.2] ATT timer expired. Preparing queued events: 2
2022-12-19 22:07:27.962871+0900 AdventTest[31579:3493681] [AppsFlyerSDK] [com.appsflyer.serial] NotDetermined
2022-12-19 22:07:27.963274+0900 AdventTest[31579:3493683] [AppsFlyerSDK] [com.appsflyer.serial] NotDetermined

deniedの場合と同様に、IDFAを示すadvertiserIdはnullになっています。

{"timestamp":"1671453713.383594","uid":"1671455185355-7453864","bundlename":"","cell":
{"mcc":"tv|sim", ...,"att_status":0,...,"advertiserId":"", ...

まとめ

この記事では、少し取っ付きづらいATTフレームワークの実装について解説しました。
これから実装される方の参考になればうれしいです。

前記事、この記事ではiOSシミュレーターでの検証まででした。次の記事では、これまで実装したアプリを利用して、実機デバイスを使った非オーガニックインストール計測のテスト方法を解説します。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?