Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authorisation popup is not showing in iOS 16.5 #44

Open
amitaman opened this issue Jun 1, 2023 · 26 comments
Open

Authorisation popup is not showing in iOS 16.5 #44

amitaman opened this issue Jun 1, 2023 · 26 comments

Comments

@amitaman
Copy link

amitaman commented Jun 1, 2023

Hi Team,
i am using the latest version of ATT in my flutter app when i published my app to app store they rejected saying:
We're looking forward to completing our review, but we need more information to continue. Your app uses the AppTrackingTransparency framework, but we are unable to locate the App Tracking Transparency permission request when reviewed on iOS 16.5.

Method:
Future<void> initPlugin() async { // Platform messages may fail, so we use a try/catch PlatformException. try { final TrackingStatus status = await AppTrackingTransparency.trackingAuthorizationStatus; setState(() => _authStatus = '$status'); // If the system can show an authorization request dialog if (status == TrackingStatus.notDetermined) { final TrackingStatus status = await AppTrackingTransparency.requestTrackingAuthorization(); setState(() => _authStatus = '$status'); if (status == TrackingStatus.authorized && defaultTargetPlatform == TargetPlatform.iOS) { _webViewController!.evaluateJavascript( source: 'document.getElementById("onetrust-accept-btn-handler").click()', ); } } } on PlatformException { setState(() => _authStatus = 'PlatformException was thrown'); } final uuid = await AppTrackingTransparency.getAdvertisingIdentifier(); if (kDebugMode) { print("UUID: $uuid"); }

Calling:
void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) => initPlugin()); }

@mkbsugita
Copy link

Can you write in formatted text with three back quote?

Did you try it?
#32

    TrackingStatus authorizationStatus =
        await AppTrackingTransparency.trackingAuthorizationStatus;
    int timeoutCount = 0;
    while (authorizationStatus == TrackingStatus.notDetermined &&
        timeoutCount < 10) { // Adjust yourself.. maybe up to ~50
      authorizationStatus =
          await AppTrackingTransparency.requestTrackingAuthorization();
      await Future.delayed(const Duration(milliseconds: 200));
      timeoutCount++;
    }

@luminkhant
Copy link

I have the same issue today. Apple reject since it is not working for iOS 16.5, Did you already find out the solution ?
@amitaman

@Zaveri21
Copy link

@luminkhant i was facing this same issue. I added bellow code in appDelegate.swift file and Authorisation default alert showing in iOS 16+

func applicationDidBecomeActive(_ application: UIApplication) {
    if #available(iOS 14, *) {
        ATTrackingManager.requestTrackingAuthorization { status in
            switch status {
            case .authorized:
                // Tracking authorization dialog was shown
                // and we are authorized
                print("Authorized")
            case .denied:
                // Tracking authorization dialog was
                // shown and permission is denied
                print("Denied")
            case .notDetermined:
                // Tracking authorization dialog has not been shown
                print("Not Determined")
            case .restricted:
                print("Restricted")
            @unknown default:
                print("Unknown")
            }
        }
    }
}

@deniza
Copy link
Owner

deniza commented Jun 13, 2023

hi @Zaveri21

The code you provided is printing current tracking status. Could you please explain what else you did to make it work in your case? Thank you.

@JariHuomo
Copy link

I would like to hear more details too @Zaveri21 how you got this fixed, thanks!

@Zaveri21
Copy link

Zaveri21 commented Jun 18, 2023

Hi @deniza & @JariHuomo Happy coding 😀

My app was approved and live in apple store with the help of above code block.

this swift code will work for iOS 14 or above version. ATTrackingManager.requestTrackingAuthorization used for ask permission so that default iOS permission alert will open. so I added this code in my applicationDidBecomeActive method so on app launch/active I am able to prompt alert until package app_tracking_transparency issue resolved. I used this package flutter side to handle App tracking transparency for lower version nothing changed in dart side code.

@deniza
Copy link
Owner

deniza commented Jun 19, 2023

Thanks for the explanation. I want to present further information and recommend a more flutter friendly approach:

The applicationDidBecomeActive function in iOS is called when your app is brought to the foreground. This can happen when the user taps on your app icon, or the app moved from inactive to active state.

Showing a native dialog in iOS will result in the application switching to the inactive state. This is because the dialog will take focus away from your app, and the system will need to pause your app's execution until the dialog is dismissed.

You can not display ATT dialog when the application is in inactive state. I suspect that your application somehow become inactive during the call to requestTrackingAuthorization function and hence does not work properly. The most common reason for this to happen is that you request some other permission like notification permission, or camera usage permission that also shows a native dialog and sends your app to inactive state.

You can always check that your application is in an active state before calling requestTrackingAuthorization function. In your stateful widget, override didChangeAppLifecycleState function like this:

class _MyWidgetState extends State<MyApp> {
...
@override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // App has been brought to the foreground.
      // call ATT functionality here. ie: ATTrackingManager.requestTrackingAuthorization
    }
  }

Below approach is better than calling ATT in a delayed Future call, or in a loop as suggested by other fellow developers. Also you stay in the dart side instead of native code, which may be more preferable.

Please try it if you have any issues and respond this thread if it's working or not working in your use case.

@amitaman
Copy link
Author

amitaman commented Jun 19, 2023

I have the same issue today. Apple reject since it is not working for iOS 16.5, Did you already find out the solution ? @amitaman

Hi @luminkhant My app is also got approved. i used an extra dialog, before showing the actual Authorization dialog.

    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      final TrackingStatus status = await AppTrackingTransparency.trackingAuthorizationStatus;
      setState(() => _authStatus = '$status');
      // If the system can show an authorization request dialog
      if (status == TrackingStatus.notDetermined) {
        // Show a custom explainer dialog before the system dialog
        if (await **showCustomTrackingDialog(context)**) {
          // Wait for dialog popping animation
          await Future.delayed(const Duration(milliseconds: 200));
          // Request system's tracking authorization dialog
          final TrackingStatus status = await AppTrackingTransparency.requestTrackingAuthorization();
          setState(() => _authStatus = '$status');
        }
        if (status == TrackingStatus.authorized && defaultTargetPlatform == TargetPlatform.iOS) {
         //
        }
      }
    } on PlatformException {
      setState(() => _authStatus = 'PlatformException was thrown');
    }
    final uuid = await AppTrackingTransparency.getAdvertisingIdentifier();
    if (kDebugMode) {
      print("UUID: $uuid");
    }
  }```

```Future<bool> showCustomTrackingDialog(BuildContext context) async =>
    await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Dear User'),
        content: const Text(
          Constants.attMessage,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: const Text('Continue'),
          ),
        ],
      ),
    ) ??
    false;```

@onurkagan
Copy link

onurkagan commented Jun 21, 2023

The problem seems on Apple. They rejected my app update with the same reason. But when i installed ios 16.5 on an iPhone and work it, I saw that permission was requested. Somehow i think there is a problem during the review. I sent the screen recording of the application and explained that the request came to the screen as soon as the application was opened and this time they approved it. I think there is no problem with the package.

@yanqiuLove
Copy link

yanqiuLove commented Aug 2, 2023

我的项目是Flutter创建的,iOS端语言使用的是OC,针对该问题我的解决方案如下:
在AppDelegate.m文件中加入以下代码:
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/ASIdentifierManager.h>
- (void)applicationDidBecomeActive:(UIApplication *)application { if (@available(iOS 14, *)) { // iOS14及以上版本先请求权限 [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { // 获取到权限后使用老方法获取idfa if (status == ATTrackingManagerAuthorizationStatusAuthorized) { NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString]; NSLog(@"%@",idfa); } else { NSLog(@"请在设置-隐私-跟踪中允许App请求跟踪"); } }]; } else { // iOS14以下版本使用老方法 // 判断在设置-隐私里是否打开了广告跟踪 if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) { NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString]; NSLog(@"%@",idfa); } else { NSLog(@"请在设置-隐私-广告中打开广告跟踪功能"); } } }

@michaelsof47
Copy link

where i have to access package from app_tracking_transparency ?

@SancoDevs1
Copy link

HI all, i am facing this issue on IOS 16.6, unable to see the ATT prompt on ios 16.6 whereas it is coming in previous versions. any solution for it, please guide, thanks,

@michaelsof47
Copy link

is there package that i have modified ? i want to try it to modify support iOS 16.6

@SahidKhan89
Copy link

Has anyone found a workaround for this package to work with iOS 16.6 ?

Apple keep rejecting now.

@deniza
Copy link
Owner

deniza commented Sep 6, 2023

Hi. I tested the package both on ios 16.5 and 16.6 and it seems working fine for me. Please try to call it delayed in a Future.delayed callback, or use an explainer dialog before showing native ATT dialog.

@edismooth
Copy link

Same issue. Now I changed this plugin to permission_handler. I hope they will approve it. Btw if you want to crate fix for this plugin you can compare this two files (I know, the second one is not Swift):

https://github.com/deniza/app_tracking_transparency/blob/master/ios/Classes/SwiftAppTrackingTransparencyPlugin.swift

https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler_apple/ios/Classes/strategies/AppTrackingTransparencyPermissionStrategy.m

@deniza
Copy link
Owner

deniza commented Sep 6, 2023

This plugin, or any of the att plugins out there do nothing fancy actually. We just check and return ATT status with one function call; ATTrackingManager.trackingAuthorizationStatus, and show ATT dialog by using another api call; ATTrackingManager.requestTrackingAuthorization.

Other then some cosmetic differences both of the implementations are the same; just a basic wrapper around native functionality.

@edismooth
Copy link

Thank you for your quick reply @deniza!

I missed that example with description: https://github.com/deniza/app_tracking_transparency/blob/a072384e2299ad3021aab2ca5e6031a7bf40079e/example/lib/main.dart#L31C3-L31C89
I hope that now the application will pass Apple's review without any problems.

@Mik77o
Copy link

Mik77o commented Sep 22, 2023

Today , we got from app reviewer...
SmartSelect_20230922_173932_Gmail.jpg

@mzm008
Copy link

mzm008 commented Jan 1, 2024

I think the request dialog is not reopen when user reject this auth

@timokz
Copy link

timokz commented Jan 11, 2024

Hey @deniza thanks for your work and the active contributions. What is your suggested approach of resolving this issue occuring?
calling the ATT dialog in didChangeAppLifecycleState , or something like awaiting a delayed future?
EDIT: Assuming your example code is already in use, calling the dialog after initialization is comple.

@G4SD3O
Copy link

G4SD3O commented Feb 6, 2024

Hi there

I encounter the similar problem. App rejected by Apple
"We're looking forward to completing our review, but we need more information to continue. Your app uses the AppTrackingTransparency framework, but we are unable to locate the App Tracking Transparency permission request when reviewed on iOS 17.3."
As I am using XCode 15.2, I can't test with a simulator with an iOS version higher than 17.2 (Thanks Apple for not providing the right tools to test without a real device).

Anyway, here is the code I use

My main widget is a ConsumerStatefulWidget (from riverpod)

InitState method

@override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _requestAppTracking();
    });
  } 

_requestAppTracking method

  Future<void> _requestAppTracking() async {
    Future<void>.delayed(timeout).then((value) async {
      final TrackingStatus status =
          await AppTrackingTransparency.trackingAuthorizationStatus;
      developer.log('Tracking Status Init: $status');
      // If the system can show an authorization request dialog
      if (status == TrackingStatus.notDetermined) {
        // Request system's tracking authorization dialog
        final TrackingStatus status =
            await AppTrackingTransparency.requestTrackingAuthorization();
        developer.log('Tracking Status After Request: $status');
      }

      ref.read(splashStateProvider.notifier).updateState(SplashState.initGame);
    });
  }

build method

@override
  Widget build(BuildContext context) {
    ref.listen<SplashState>(splashStateProvider,
        (SplashState? previousState, SplashState newState) async {
      switch (newState) {
        case SplashState.ready:
          Navigator.pushNamed(
            context,
            "/home",
          );
          break;
        case SplashState.initGame:
          await _initApp();
          break;
        case SplashState.requestAppTransparency:
          break;
      }
    });
...

_initApp method

Future<void> _initApp() async {
    //bunch of services initialization. Not relevant here

    ref.read(splashStateProvider.notifier).updateState(SplashState.ready);
  }

I finally could get my hands on a device with 17.3 installed and indeed the AppTrackingPopup does not show during the startup. What is even weirder is that the app navigates to the "home" screen (as stated in the listen section in build()). This only happens if the await AppTrackingTransparency.requestTrackingAuthorization() directly returns without waiting for action from the user.

I am a bit lost here.
Anyone with similar issue with 17.3 ?
Thanks for your help

@RyosukeOK
Copy link

@G4SD3O
I have the same issue today. Apple reject my app since it is not working for iOS 17.3 .

Guideline 2.1 - Information Needed
We're looking forward to completing our review, but we need more information to continue. Your app uses the AppTrackingTransparency framework, but we are unable to locate the App Tracking Transparency permission request when reviewed on iOS 17.3.
~~

@G4SD3O
Copy link

G4SD3O commented Feb 7, 2024

It works on the simulator with iOS 17.2 and the release note for iOS 17.3 does not indicate major change in this area so this is very weird.
@deniza any thoughts? ;)

@deniza
Copy link
Owner

deniza commented Feb 7, 2024

To expedite the troubleshooting process, I'd like to suggest testing the plugin with a simplified test code. This is often helpful in isolating potential conflicts or integration issues within your larger app's codebase. Can you please test the plugin in such a test environment?

@G4SD3O
Copy link

G4SD3O commented Feb 8, 2024

I have created a simple project to reproduce the issue. Here are my first results:

  1. it works perfectly using a simulator with iOS 17.2
  2. I have been testing on a real phone with iOS 17.3 but this one belongs to my daughter who is less than 18 years old so the tracking is automatically disabled (status = TrackingStatus.restricted). That is why the ATT popup never appears. Good to know for future tests

I still need to find a real phone with iOS 17.3 as the latest Xcode version does not allow me to test this version.

Does anyone know an online service (free or very cheap) we can use to do further testing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests