react-nativeios-permissionsreact-native-permissions

React Native - How to request App Tracking Transparency permissions on iOS?


The solution mentioned here talks about how to set this up with the ATTrackingManager class, however, that is not exposed directly to React Native.

Using the react-native-tracking-transparency package is causing an issue for me at build time:

"Undefined symbols _RCTRegisterModule"

because it only works if you do not include use_flipper! in your podfile... so I am stuck and do not want to patch-package as recommended in solutions here (which imply a fix has already been merged, but I still see "Undefined symbols _RCTRegisterModule" when building with this...

Wondering if there is any wrapper for the ATTrackingManager class for React Native?


Solution

  • Found a solution after asking some colleagues who have worked around this before and posting if anyone else is running into this issue...

    in info.plist make sure to have a NSUserTrackingUsageDescription key. This is the text that shows when requesting permissions:

    <key>NSUserTrackingUsageDescription</key>
        <string>This app uses device identifiers to track marketing attribution and app usage.  Your data is kept confidential and is not shared with any 3rd parties or advertising partners.</string>
    

    Add the Tracking pod to your podfile:

    platform :ios, '12.4'
    target 'RNPath' do
       config = use_native_modules!
       use_frameworks!
       ...
       # add next line
       pod 'Permission-AppTrackingTransparency', :path => "#{permissions_path}/AppTrackingTransparency"
       ...
       end
    end
    

    run pod install and pod update from the ios folder of your project to make that change take affect

    cd ios && pod install && pod update
    

    Then use the react-native-permissions package to request tracking permissions when app state becomes active

    in App.js

    .
    .
    . 
    import { PERMISSIONS, RESULTS, request } from 'react-native-permissions';
    
    export default function () {
    .
    .
    .
    const handleAppStateChange = async (nextAppState) => {
        if (nextAppState == 'active') {
          request(PERMISSIONS.IOS.APP_TRACKING_TRANSPARENCY)
            .then(async (result) => {
              if (result == RESULTS.GRANTED) {
                console.log('Tracking!');
                // do something related to tracking
    
              } else {
                console.log('Not Tracking!');
              }
            })
            .catch((error) => {
              console.log('error in request tracking permissions: ', error);
            });
        }
     }
    
     useEffect(() => {
       let subscription = AppState.addEventListener('change', handleAppStateChange);
       return () => {
          subscription.remove();
       };
     }, []);
    .
    .
    .
    return <App/>
    

    This is nice because it is called every time the app is foregrounded the permission is re-checked so if they have enabled/disabled it from the phone's settings it will take notice and react accordingly.

    Worth noting that this request fails if you don't make sure the application's state is "active" and if it is "backgrounded" or "inactive" it can return unavailable and then might never be presented to the user and stay in that state which is far less than ideal since it will never be allowed, so that's why I'm checking for "active" in that last code segment.