React Native ExpoアプリのIDFA対応

React Native Expo アプリで、iOS 14.5 から必須となった IDFA 対応をしました。AdMob を使っているスマホアプリは、トラッキングの許可を求めるダイアログを表示しなければなりません。IDFA 対応に必要な修正と審査についてまとめます。

IDFA と AppTrackingTransparency とは

IDFA (Identifier for Advertisers) は、端末にランダムで割り当てられるデバイス ID(広告識別子)です。アプリの中で配信される広告は、このデバイス ID を使ってユーザにフィットするよう調整されています。しかし、IDFA はユーザから許可を得ないと使えません。

ユーザーのプライバシーとデータの使用 - App Store - Apple Developer

トラッキングを有効にする許可をユーザーから得ない限り、デバイスの広告識別子の値はすべてゼロになります。

許可を得るためには、AppTrackingTransparency を使ってトラッキングの許可/不許可を選べるダイアログを表示させます。もしユーザがトラッキングを許可してくれたら IDFA を使えます。許可してくれなければ当然使えません。

iOS 14.5、iPadOS 14.5、tvOS 14.5 以降では、ユーザーをトラッキングしたり、ユーザーのデバイスの広告識別子にアクセスしたりする際には、AppTrackingTransparency のフレームワークを通じてユーザーの許可を得る必要があります。

AdMob を使うためには トラッキング許可申請が必須

AdMob は IDFA を使って広告を最適化しています。iOS アプリで AdMob を利用するためには、AppTrackingTransparency を使ってユーザにトラッキングの許可を申請するように修正しなければいけません。

自動的に収集されるユーザー プロパティ - Google AdMob ヘルプ

iOS アプリで年齢、性別、インタレスト カテゴリの各プロパティを自動的に取得するには、IDFA を収集する必要があります。

トラッキング不許可を緩和する SKAdNetwork

仮にトラッキングの許可が得られなかった場合は、広告収益減少の緩和策として SKAdNetwork を利用できます。SKAdNetwork は Apple が提供しているコンバージョントラッキングのための仕組みです。コンバージョンを計測できれば、広告主はより高い価格で広告枠を買ってくれるようになります。

SKAdNetwork に対応していないと、AdMob 管理画面の上部に以下の表示が出て警告してくれます。

Apple の SKAdNetwork を使用できるよう設定されていないアプリがあります アプリのインストールなど、広告で発生したすべてのユーザー アクティビティが正確に評価されるよう、SKAdNetwork に Google のネットワーク ID を必ず設定してください。

React Native Expo での IDFA 対応

getPermissionsAsync, requestPermissionsAsync を呼び出す

React Native Expo の AdMob モジュールには、トラッキングのパーミッションの状態を取得する getPermissionsAsync と、パーミッションを要求する requestPermissionsAsync が用意されています。両方ともパラメータは無く呼び出すだけです。

Admob - Expo Documentation

Permissions - Expo Documentation

const status = await AdMob.getPermissionsAsync();
const status = await AdMob.requestPermissionsAsync();

getPermissionsAsync でパーミッションの状態を取得して、ユーザにパーミッションを要求すべきか否かを以下のように判定しました。

!status.granted && status.canAskAgain;

requestPermissionsAsync を呼び出すと画面にダイアログが表示されます。少しでもトラッキングを許可してくれるユーザが増やすため、requestPermissionsAsync の直前に Alert.alert()で許可お願いします!ダイアログを表示しています。

なお、requestPermissionsAsync を呼び出すタイミングはアプリ起動直後じゃないとGuideline 5.1.2 - Legal - Privacy - Data Use and Sharingに引っかかって審査が通りませんでした。requestPermissionsAsync を呼び出すまでは AdMob の広告枠を非表示にしてもダメでした。

NSUserTrackingUsageDescription を設定

app.json の infoPlist に NSUserTrackingUsageDescription を追加します。値には、トラッキング許可ダイアログに表示する文字列を指定します。多言語対応の方法を調べたのですがわからなかったため英語で記載しました。

app.json / app.config.js - Expo Documentation

      "infoPlist": {
        "NSUserTrackingUsageDescription": "This identifier will be used to deliver personalized ads to you."
      }

NSUserTrackingUsageDescription を設定しておかないと、実機で requestPermissionsAsync を呼び出した瞬間にアプリがクラッシュします。エミュレータでは発生せず、審査でアプリ落ちるよ、Guideline 2.1 - Performance - App Completenessだよと怒られました。

実機で試してログを取ったところ、NSUserTrackingUsageDescription が未設定だと強制終了させられるようです。

Exception Type: EXC_CRASH (SIGKILL) Exception Codes: 0x0000000000000000, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Termination Reason: TCC, This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSUserTrackingUsageDescription key with a string value explaining to the user how the app uses this data.

React Native Expo での SKAdNetwork 対応

app.json の infoPlist に SKAdNetworkIdentifier を追加します。値には、Google の SKAdNetworkIdentifier 値(cstr6suwn9.skadnetwork)を指定します。

SKAdNetwork を有効にしてコンバージョンを測定する

      "infoPlist": {
        "SKAdNetworkIdentifier": "cstr6suwn9.skadnetwork"
      }