react-native-tracking-transparency icon indicating copy to clipboard operation
react-native-tracking-transparency copied to clipboard

Not possible to request Tracking Transparency in iOS 15

Open ErickMaeda opened this issue 2 years ago • 20 comments

Hello,

I've tested in iOS 15 as it was officially released in 2021/09/20

However when calling method from iOS 15 requestTrackingPermission() I receive not-determined.

The same code executed in iOS 14 is working properly.

Do you have any idea why it's not requesting?

Thanks

import React, { useEffect } from 'react';
import { View } from 'react-native'
import {  requestTrackingPermission } from 'react-native-tracking-transparency';

const requestPermission = async () => {
    const trackingStatus = await requestTrackingPermission();
    alert(`trackingStatus ${trackingStatus}`);
}

const App = () => {
   useEffect(() => {
      requestPermission();
   }, []); 
   return <View />;
};

export default App;

ErickMaeda avatar Sep 21 '21 17:09 ErickMaeda

i don't know why doesn't work on iOS 15 , but i changed the requestTrackingPermission call on onPress event in my login button and works fine again.

josebrc avatar Sep 21 '21 20:09 josebrc

i don't know why doesn't work on iOS 15 , but i changed the requestTrackingPermission call on onPress event in my login button and works fine again.

It's weird. But it's working as you said, maybe we cannot ask for tracking transparency on app startup anymore?

ErickMaeda avatar Sep 22 '21 09:09 ErickMaeda

i don't know why doesn't work on iOS 15 , but i changed the requestTrackingPermission call on onPress event in my login button and works fine again.

It's weird. But it's working as you said, maybe we cannot ask for tracking transparency on app startup anymore?

i don'd know, but another way is using a time out function.


setTimeout(async () => {
      if(Platform.OS=='ios'){
        const trackingStatus = await getTrackingStatus();
        if(trackingStatus === 'not-determined'){
          try {
            await requestTrackingPermission();
          } catch (e) {
            Alert.alert('Error', e?.toString?.() ?? e);
          }
        }
  
      }
    }, 1000);

josebrc avatar Sep 22 '21 15:09 josebrc

Interested to see why the ATT pop up doesn't show anymore with iOS 15. The fix with setTimeout doesn't work for me, but upon an action of the user, like onPress the pop up does show ✅. Thanks for the suggestion

antoinewg avatar Sep 23 '21 16:09 antoinewg

In one of our apps, I discovered that the ATT prompt is triggered even when the app is in inactive state, that means when you e.g. prompt a user with push notifications consent at the same time as with the ATT at startup time, it will be skipped. It was not happening on iOS 14 though 🤷🏽‍♂️

What I did in the end, was listening for the app state changes: whenever the app goes from inactive to active and has the ATT permission not defined, it would trigger the prompt. Seems to work

As it turns out, you can also do it later e.g. upon clicking on the login button as well

danielmark0116 avatar Sep 30 '21 07:09 danielmark0116

For me in iOS 15 the pop up shows, but any user choice will freeze the app. this lead to close the app and open it again.

musti-91 avatar Sep 30 '21 12:09 musti-91

Having this issue

liho00 avatar Oct 04 '21 07:10 liho00

Sometimes the iOS user can disable the request from all apps. So you cannot display the request when this option is enabled (Idk if it's enabled by default or not)

Apple-App-Tracking-Transparency-1

ErickMaeda avatar Oct 14 '21 13:10 ErickMaeda

I was having the same issue, this is caused because in iOS 15 we can only raise the pop up when the app is in active state. To solve this, I added a listener for the AppState change, which can be imported from react-native itself and I just run the function to raise the pop up when the AppState is equal to active.

useEffect(() => {
    const listener = AppState.addEventListener('change', status => {
      if (status === 'active') {
        (async () => {
          const trackingStatus = await getTrackingStatus();
          if (trackingStatus === 'not-determined') {
            requestTrackingPermission();
          }
        })();
      }
    });

    return () => {
      listener && listener.remove();
    };
  }, []);

leonardocroda avatar Oct 19 '21 21:10 leonardocroda

@leonardocroda your work around works, thank you.

simoneantonicchio avatar Nov 03 '21 08:11 simoneantonicchio

May be can trying to change condition @available(iOS 14, *)) to @available(iOS 14, iOS 15, *).

Captura de Tela 2021-11-08 às 00 10 11

I'm trying it now.

fernandopascoalbr avatar Nov 08 '21 03:11 fernandopascoalbr

i don't know why doesn't work on iOS 15 , but i changed the requestTrackingPermission call on onPress event in my login button and works fine again.

It's weird. But it's working as you said, maybe we cannot ask for tracking transparency on app startup anymore?

i don'd know, but another way is using a time out function.


setTimeout(async () => {
      if(Platform.OS=='ios'){
        const trackingStatus = await getTrackingStatus();
        if(trackingStatus === 'not-determined'){
          try {
            await requestTrackingPermission();
          } catch (e) {
            Alert.alert('Error', e?.toString?.() ?? e);
          }
        }
  
      }
    }, 1000);

It's work but why ? =.="

zoom2009 avatar Nov 16 '21 12:11 zoom2009

@fpgce how'd it go ?

a-eid avatar Nov 18 '21 09:11 a-eid

I can confirm that an additional setTimeout is needed. Without it, our app got rejected.

hubciorz avatar Nov 19 '21 08:11 hubciorz

I had the same issue. It was solved by updating the OS to Monterey, execute xcode (click the install menu that appears after running), and then rebuilding.

jongha avatar Nov 20 '21 03:11 jongha

I can confirm that an additional setTimeout is needed. Without it, our app got rejected.

Same here

Facing the same issue, on a real device even with timeout it doesnt pop up

renatomserra avatar Feb 02 '22 23:02 renatomserra

@leonardocroda's solution with AppState.addEventListener worked, however it only asked for permission after the state changed (i.e. put the app in the background, then back to the foreground). To make it also work on launch I had to modify it a little:

React.useEffect(() => {
    if (Platform.OS !== 'ios') {
        return
    }

    const updateTrackingStatus = (status: AppStateStatus) => {
        if (status === 'active') {
            ;(async () => {
                const trackingStatus = await getTrackingStatus()

                if (trackingStatus === 'not-determined') {
                    requestTrackingPermission()
                }
            })()
        }
    }

    // Ready to check the permission now
    if (AppState.currentState === 'active') {
        updateTrackingStatus(AppState.currentState)
    } else {
        // Need to wait until the app is ready before checking the permission
        AppState.addEventListener('change', updateTrackingStatus)

        return () => {
            AppState.removeEventListener('change', updateTrackingStatus)
        }
    }
}, [AppState.currentState])

patik avatar Apr 12 '22 09:04 patik

Where do you import AppStateStatus from ?

hugoh59 avatar Oct 11 '22 09:10 hugoh59

Where do you import AppStateStatus from ?

import { AppStateStatus } from 'react-native'

patik avatar Oct 11 '22 09:10 patik