shipcheck
APPLE PRIVACY REQUIREMENT

App Tracking Transparency: what the prompt actually requires

If your app reads the advertising identifier or otherwise tracks users across apps and websites, the ATT prompt is not optional, and the timing and wording both matter to App Review.

Using the AppTrackingTransparency framework — Apple Developer

To request permission to track the user and access the device’s advertising identifier, use the App Tracking Transparency framework. You must also include a purpose string in the system prompt that explains why you’d like to track the user. Unless you receive permission from the user to enable tracking, the device’s advertising identifier value will be all zeros and you may not track them as described above.

While you can display the App Tracking Transparency prompt whenever you choose, the device’s advertising identifier value will only be returned once you present the prompt and the user grants permission. Use the purpose string to explain what this data will be used for to help the user understand what they’re opting in to share. If the user allows apps to request to track, but has turned tracking off for your app, you can ask the user to change their preference for your app by providing a shortcut to Settings where they can change the tracking permission.

The identifier for vendor (IDFV) may be used for analytics across apps from the same content provider. In this case, the use of the App Tracking Transparency framework is not required. The IDFV may not be combined with other data to track a user across apps and websites owned by other companies. You remain fully responsible for ensuring that your collection and use of the IDFV comply with applicable law.

For more information, see:

What actually requires the prompt

Reading IDFA (the advertising identifier) or otherwise tracking a user across apps and websites owned by other companies needs ATT permission first -- without it, IDFA reads back as all zeros. The one narrow exception the guidance calls out is IDFV (ID for Vendors), which can be used for cross-app analytics within your own company's apps without triggering the framework -- but IDFV may not be combined with other data to track a user across apps and websites owned by other companies, so mixing it into a third-party ad SDK's payload can still cross the line.

Where React Native and Expo apps get this wrong

Ad SDKs (AdMob, Meta Audience Network, AppLovin, and similar) read the advertising identifier as soon as they initialize, which in a default Expo or RN setup is often before your app has shown the ATT prompt at all -- that's a guideline violation regardless of what the prompt eventually says. `NSUserTrackingUsageDescription` also has to be a real, specific purpose string; Expo's default placeholder text for this key is exactly the kind of generic string App Review rejects on sight, the same pattern that shows up across Expo's other default usage-description strings.

The fix

Expo / React Native

Add `expo-tracking-transparency`, call `requestTrackingPermissionsAsync()` and wait for the result before initializing any ad or analytics SDK that reads IDFA -- not in parallel, not after. Set a specific `NSUserTrackingUsageDescription` in `app.json` under `ios.infoPlist`, naming what the tracking is actually for (e.g. "Used to show you more relevant ads based on your activity in other apps"), not a generic placeholder.

ShipCheck catches this before you submit

A Claude Code plugin for React Native and Expo. Reads your project and store listing, checks them against the live App Store Review Guidelines and Google Play policies -- the same corpus quoted on this page -- and tells you the clause, the reviewer's likely wording, and the fix.

/plugin marketplace add BakerVentures/shipcheck

Free scan on every app. See pricing →