この記事は 2024 年 2 月時点の記録です(2026 年 7 月 追記)
App Tracking Transparency(ATT)の考え方そのものは変わっていませんが、設定方法とテストの手順が変わりました。現在の内容を 5 点にまとめます。
1. Expo のバージョン
2026 年 7 月時点で
expo-tracking-transparencyの推奨バージョンは 57 系です。API の名前は変わっていませんが、周辺のワークフローが大きく変わっています。Expo 公式ドキュメントを先にご確認ください。2. Info.plist と AndroidManifest.xml の手編集は原則不要になりました
現在は config plugin(CNG/Continuous Native Generation)を使う書き方が標準です。
app.jsonに次のように書けば、NSUserTrackingUsageDescriptionが自動で設定されます。{ "expo": { "plugins": [ [ "expo-tracking-transparency", { "userTrackingPermission": "This identifier will be used to deliver personalized ads to you." } ] ] } }Android の
com.google.android.gms.permission.AD_IDについても、公式ドキュメントにはライブラリ側の AndroidManifest.xml から自動的に追加されると記載されています。ネイティブプロジェクトを手動で管理している構成(本文の Expo Bare のような形)では、本文の手順が引き続き必要です。ご自身の構成に合わせて選んでください。3. 「要求する前に状態を確認する」のが現在の推奨です
本文では起動時に無条件で
requestTrackingPermissionsAsync()を呼んでいます。現在は、まず現在の状態を取得し、未確定(undetermined)のときだけ要求を出す書き方が案内されています。状態取得にはgetTrackingPermissionsAsync()、もしくはuseTrackingPermissions()フックを使います。AdMob と組み合わせる場合はさらに順序が重要です。ATT の応答が返ってから Google Mobile Ads SDK を初期化します。初期化の時点で広告のプリロードが始まるため、並行で走らせると間に合わないことがあります。
4. 実機テストでハマりやすい点
- ユーザーが一度答えると、システムがその選択を記憶し、アプリを削除して再インストールするまで二度と表示されません。挙動を確認したいときは再インストールが必要です
- 端末側の「Appからのトラッキング要求を許可」設定がオフだと、この権限は常に拒否されます。実装ミスではありません
- iOS シミュレータでは広告 ID(IDFA)が常に null になります。確認は実機で行ってください
- 広告 ID の取得には
getAdvertisingId()を使います。値は保存せず、必要なたびに取得するのが推奨です5. EEA・英国向けは ATT だけでは足りません
ATT は Apple 側の仕組みです。AdMob で欧州経済領域(EEA)および英国のユーザーに広告を配信する場合は、2024 年 1 月 16 日以降、これとは別に Google 認定の同意管理プラットフォーム(CMP)が必要です。対応していない場合、その地域では制限付き広告しか配信されません。実装の詳細はAdMob バナー広告の記事の追記にもまとめています。
※ 上記は 2026 年 7 月時点の公式ドキュメント(Expo・Google)に基づく整理であり、当方の環境での再検証は行っていません。実装時は必ず公式ドキュメントで最新をご確認ください。
Apple は、IDFA にアクセスするための App Tracking Transparency 認証リクエストを表示することをアプリに要求しています (パーソナライズされた広告を使用するか、パーソナライズされていない広告を使用するかはユーザーに選択を委ねます)。
開発環境(Expo Bare)
- “typescript”: “^5.2.2”
- “expo”: “~49.0.13”,
- “react”: “18.2.0”,
- “react-native”: “0.72.6”,
- “expo-router”: “^2.0.0”,
- “react-native-paper”: “^5.10.6”,
- “react-native-google-mobile-ads”: “^12.3.0”,
- “expo-tracking-transparency“: “~3.1.0”,
セットアップ
パッケージを設置する
$ npx expo install expo-tracking-transparency $ npx pod-install
iOS設定(Expo Bare用)
// ios/<proejct-name>/Info.plist ... <key>NSUserTrackingUsageDescription</key> <string>Your custom usage description string here.</string> ...
Android設定(Expo Bare用)
// android/app/src/main/AndroidManifest.xml ... <!-- Added permissions --> <uses-permission android:name="com.google.android.gms.permission.AD_ID"/> ...
実装する
import React, { useEffect } from 'react';
import { Text, StyleSheet, View } from 'react-native';
import { requestTrackingPermissionsAsync } from 'expo-tracking-transparency';
export default function App() {
useEffect(() => {
(async () => {
const { status } = await requestTrackingPermissionsAsync();
if (status === 'granted') {
console.log('Yay! I have user permission to track data');
}
})();
}, []);
return (
<View style={styles.container}>
<Text>Tracking Transparency Module Example</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
iOS 17.4 & iPhone 15 Proでは、requestTrackingPermissionsAsync() の実行タイミングはアプリが アクティブ状態 になってからではないとランダムでAppTrackingTransparencyのプロンプトが表示されないことがあります! 24/5/25(月)追記




コメント