App Tracking Transparency Dialog does not appear on iOS
Asked Answered
E

7

28

Apple reviewer has just rejected my app since ATT request doesn't appear: "We are unable to locate the App Tracking Transparency permission request when reviewed on iOS 15.0.1."

My code is as shown below:

if #available(iOS 14, *) {
  ATTrackingManager.requestTrackingAuthorization { (status) in
    //print("IDFA STATUS: \(status.rawValue)")
    FBAdSettings.setAdvertiserTrackingEnabled(true)
  }
}

I implemented this code both in AppDelegate didFinishLaunchingWithOptions and viewDidLoad. ATT permission request appear on iOS 14, but not in iOS 15.

Examination answered 2/10, 2021 at 17:45 Comment(2)
Have you set NSUserTrackingUsageDescription in Info.plist? developer.apple.com/documentation/bundleresources/…Miltiades
Of course, otherwise, permission request wouldn't have appeared on iOS 14Bala
E
31

Damn it I fixed it:( This is all about the iOS alert system. I was requesting App Tracking Transparency after a notification request was asked. Once the notification request alert closed, the ATT alert needed to have appeared. It was working fine on iOS 14, but on iOS 15 to display an alert right after another one, it is needed to have a delay period between each other.

Edit: Here is my code that display two alert respectively:

 func setNotification(){
    //Ask for notification permission
    let n = NotificationHandler()
    n.askNotificationPermission {
        //n.scheduleAllNotifications()
        
        //IMPORTANT: wait for 1 second to display another alert
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            if #available(iOS 14, *) {
              ATTrackingManager.requestTrackingAuthorization { (status) in
                //print("IDFA STATUS: \(status.rawValue)")
                //FBAdSettings.setAdvertiserTrackingEnabled(true)
              }
            }
        }
    }
}

And for your convenience here is my NotificaitionHandler class:

import UserNotifications

class NotificationHandler{
//Permission function
func askNotificationPermission(completion: @escaping ()->Void){
    
    //Permission to send notifications
    let center = UNUserNotificationCenter.current()
    // Request permission to display alerts and play sounds.
    center.requestAuthorization(options: [.alert, .badge, .sound])
    { (granted, error) in
        // Enable or disable features based on authorization.
        completion()
    }
}
Examination answered 3/10, 2021 at 10:32 Comment(7)
kindly if you can give more details on how you implemented that. maybe share some codeZink
I have edited my answer @TonuiNicholusBala
i was try it and i was publish with this answer with my own project on app store. but, i was suprisely it rejected by apple.Vasiliu
And if it takes 1.5 sec? What you should be checking is the UIApplication.shared.applicationState, it's probably inactive when you call it. A better solution would be to call it in AppDelegate applicationDidBecomeActive, or add notification for UIApplication.didBecomeActiveNotification and request authentication thereNubia
Ya, same case exactly with me. 2 requests for permissions. notification and tracking.Verbiage
I tried all possible solutions of this page (as of 10th June '22) and had no luck yet. I'm building my iOS app with Flutter.Reeder
what the?? something i was realize after read this and evaluate with apple tester team every one month.Vasiliu
A
20

An Apple person suggests that you request it through applicationDidBecomeActive(_:) in AppDelegate. That's how I fixed the issue for iOS.

import UIKit
import AppTrackingTransparency

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
    func applicationDidBecomeActive(_ application: UIApplication) {
        if #available(iOS 15.0, *) {
            ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
                
            })
        }
    }
}
Aerator answered 2/10, 2021 at 21:43 Comment(6)
This doesn't work for me!Bala
We were calling requestTrackingAuthorization from the applicationDidFinishLaunching and on the iOS 15 app is inactive. Moving it to applicationDidBecomeActive resolved our issue.Pocketknife
worked for me, thank youDornick
You can call it from anywhere by creating a notification for didBecomeActive: NotificationCenter.default.addObserver(self, selector: #selector(showTrackingAction), name: UIApplication.didBecomeActiveNotification, object: nil)Nubia
This is the correct answer, and I can also verify apple recommends this as well.Abate
anyway, this code it will be worked for any flutter iOS Projects?Vasiliu
T
8

I've changed to call the request from

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
}

to

@available(iOS 13.0, *)
func sceneDidBecomeActive(_ scene: UIScene) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        self.requestPermission()
    }
}

func requestPermission() {
    if #available(iOS 15.0, *) {
            ATTrackingManager.requestTrackingAuthorization(completionHandler: { 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:
                   
                }
            })
        }
    }
}
Tion answered 29/11, 2021 at 6:58 Comment(0)
B
6

In my case, Settings -> Privacy & Security -> Tracking -> "Allow Apps to Request to Track" was off on the device.

After turn it on, I was able to see dialog.

It's Flutter app, real device, iOS 16.5

Baur answered 19/6, 2023 at 8:11 Comment(1)
U saved me !!!!Teddy
L
4

Here's how to call the request in SwiftUI when app becomes active:

@main
struct MyApp: App {
    @Environment(\.scenePhase) var scenePhase
    
    var body: some Scene {
        WindowGroup {
            MainView()
                .onChange(of: scenePhase, perform: { newValue in
                    if newValue == .active {
                        ATTrackingManager.requestTrackingAuthorization { status in
                            // do something
                        }
                    }
                })
        }
    }
}
Laliberte answered 6/12, 2022 at 23:8 Comment(0)
I
2

I've changed to call the request from the AppDelegate's applicationDidBecomeActive method and it worked!

The popup is being presented on the first app launch on iOS15.

Incensory answered 10/10, 2021 at 2:4 Comment(0)
A
1

It seems like in newer iOS like 17.x it appears right after app start, especially in iPad, on top of that, when trying to get this approved, it will be hidden underneath the TestFlight info screens.

I did a little trick and added my own info screen telling the user about app tracking and why it is important, the user click a button and the ATT dialog will pop up. Got approved right away.

Argot answered 27/11, 2023 at 9:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.