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.