ATTrackingManager.requestTrackingAuthorization stopped working in iOS 15

  • Call it in “ViewDidAppear”.

Add a Comment

Apple Recommended

Replies

got the same issue - just add delay for 1 sec before showing ATT popup.

At first we show popup for push notifications, then when user made a choice - show ATT popup after 1 sec

  • I have the same scenario.

  • Thank you very much! Adding a 1-second delay after triggering the push notification popup seems to have worked!

  • Thank you very much!

I've been debugging this since yesterday. I noticed the same thing. It does seem to have to do when you have another popup requesting permissions. For us, it's location permission.

Just now, I found a phenomenon that if an app has been installed on iOS 15, even if it is deleted, reinstalled, or restarted, the selection of some system permissions of the app is still remembered, so there is no need to reselect (such as user tracking, location, photos, camera, etc.), and there is no pop-up box, except for notifications.

call it in applicationDidBecomeActive.

Add a Comment

The documentation for requestTrackingAuthorization(completionHandler:) is updated to reflect the latest guidance:

Calls to the API only prompt when the application state is UIApplicationStateActive. The authorization prompt doesn’t display if another permission request is pending user confirmation. Concurrent requests aren’t preserved by iOS, and calls to the API through an app extension don’t prompt. Check the trackingAuthorizationStatus for a status of ATTrackingManager.AuthorizationStatus.notDetermined to determine if you need to make an additional call.

  • Thank you Jason! Your post helped! I did not expect such a setup from iOS SDK

  • @Jason @sergsmyk Hello guys, does you call ATTrackingManager.requestTrackingAuthorization completion handler again in .notDetermined block again ? To resolve this problem ? Or ?

  • I did something like this: `var applicationDidBecomeActiveObserver: Any?

    func method() {

    if UIApplication.shared.applicationState == .active {

          requestTrackingAuthorization()

        } else {

          applicationDidBecomeActiveObserver = NotificationCenter.default.addObserver(         forName: UIApplication.didBecomeActiveNotification,         object: nil,         queue: .main       ) { [weak self] _ in

            self?.requestTrackingAuthorization()

            self?.applicationDidBecomeActiveObserver.flatMap {

              NotificationCenter.default.removeObserver($0)

            }

          }

        }

    }`

Add a Comment

Can you guys show me an example? I'm a visual learner. lol

Unfortunately, our new app has now also been rejected twice. And is now probably waiting for the third rejection. We have several apps where App Tracking Transparency authorization prompt has been showing successfully for a year on iOS 14 or newer. We always called it in viewDidLoad.

Now, the first time the new app was rejected because the App Tracking Transparency authorization prompt did not appear if called from viewDidLoad on iOS 15. That was our mistake because we unfortunately didn't test it on iOS 15.

When we submitted the app for the second time, we showed the App Tracking Transparency authorization prompt in viewDidAppear and tested it on an iOS 15 device. The App Tracking Transparency authorization prompt was displayed successfully. Unfortunately, the app was rejected for the second time with the same reason.

The third time we called the App Tracking Transparency authorization prompt from viewDidAppear after a 2 second delay. Now the app has been waiting for review for a bit longer and we are afraid that it will be rejected again. It is really frustrating. It works with all our test devices and we don't get any more information from the review team.

Would it be possible that on the device of the review employee the "Settings -> Privacy -> Tracking" is disabled?

This is our code for the App Tracking Transparency request:

if (@available(iOS 14, *))
{
	  ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus];

	  if(status == ATTrackingManagerAuthorizationStatusNotDetermined)
	  {
		    [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status)
		    {
			      // Tracking authorization completed. Start loading ads here.

			      [[NSOperationQueue mainQueue] addOperationWithBlock:^
			      {
				        [self loadBannerAd];
				        [self createAndLoadInterstitial];                            
			      }];
		    }];
	  }
	  else
	  {
		    [self loadBannerAd];                    
		    [self createAndLoadInterstitial];
	  }
}
else
{
	  // Fallback on earlier versions
}

Both times this was the reason for the rejection:

  1. 1.2 Legal: Privacy - Data Use and Sharing

Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing

The app privacy information you provided in App Store Connect indicates you collect data in order to track the user, including Advertising Data. However, you do not use App Tracking Transparency to request the user's permission before tracking their activity.

Starting with iOS 14.5, apps on the App Store need to receive the user’s permission through the AppTrackingTransparency framework before collecting data used to track them. This requirement protects the privacy of App Store users.

Next Steps

Here are two ways to resolve this issue:

  • If you do not currently track, or decide to stop tracking, update your app privacy information in App Store Connect. You must have the Account Holder or Admin role to update app privacy information.

  • If you track users, you must implement App Tracking Transparency and request permission before collecting data used to track. When you resubmit, indicate in the Review Notes where the permission request is located.

  • I have the same issue with you. Diving to find the solution for the 3rd submission. I asked the reviewers for some information but they don't even answer one. just copy and paste the robotic answers.

  • Hi, its been week ago, do you mind to share the update for app review? did it accepted?

  • I have the same problem. I told the reviewer that I already implemented it and send him a screenshot of the prompt. This is what I got as a reply...

    "After further review, we have determined that the original rejection feedback is valid. The App Tracking Transparency alert is not displayed upon launching the app and not found at all during the review. We look forward to reviewing your revised and resubmitted app. "

Add delay 2 seconds for first time worked

You may create an information popup prior to requesting the App Tracking Transparency authorization. When the user closes the popup, you request for authorization. In this way, you can be assured that the application state is UIApplicationStateActive.

Adding a delay as others suggested may not work if for some reason the application state is not active when the delay ends e.g. device is slow which causes the delay to expire while app is still on the loading screen.

The app has now been accepted with the 2 seconds delayed call. But since a delay is not a best solution, we have now solved it differently. As before, we now call a method from viewDidLoad without delay. In this method we check the status of the application. If the status is not active, then we call this method recursively after 0.5 seconds. As soon as the status is active, we call App Tracking Transparency authorization prompt. It should work that way and get through the review without any problems. We'll try to submit an update tomorrow.

-(void)initAds
{      
	  UIApplication *applicaiton = [UIApplication sharedApplication];

    if (applicaiton.applicationState == UIApplicationStateActive)
    {
        if (@available(iOS 14, *))
        {
            ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus];

            if(status == ATTrackingManagerAuthorizationStatusNotDetermined)
            {
                [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status)
                {
                    // Tracking authorization completed. Start loading ads here.

                    [[NSOperationQueue mainQueue] addOperationWithBlock:^
                    {
                        [self loadBannerAd];
                        [self createAndLoadInterstitial];
                    }];
                }];
            }
            else
            {
                [self loadBannerAd];
                [self createAndLoadInterstitial];
            }
        }
        else
        {
            // Fallback on earlier versions
        }
    }
    else
    {
        [self performSelector:@selector(initAds)
                       withObject:nil
                       afterDelay:0.5f];
    }
}

I resolved this problem, adding permission request in viewDidAppear of my first ViewController. In my case I have two permission request, App Tracking Transparency and Location. Firstly I call App Tracking Transparency permission and , in its completionHandler I call the Location permission. I my case I didn't need put any delay. Just put in viewDidAppear method. 

The issue seems to be related to requestTrackingAuthorization which is now required to be called in UIApplicationStateActive, but when the prompt is shown the app goes in inactive state, so the status requestTrackingAuthorization gives back isn't correct. Feels like something for Apple to fix quickly, because timeouts and recursions may fail once they fix this