Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 15: How to display ATT dialog when the app starts in SwiftUI

In iOS 14, It could display ATT (App Tracking Transparency) dialog when app starts in SwiftUI as follows.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    if #available(iOS 14, *) {
        ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
            // loadAd()
        })
    } else {
        // loadAd()
    }
    return true
}

But, in iOS 15.0, it does not work. Apple document describes as follows.

Calls to the API only prompt when the application state is: UIApplicationStateActive. Calls to the API through an app extension do not prompt. https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/3547037-requesttrackingauthorization

How to display ATT dialog when the app starts in iOS 15 ?

2021/9/28 update I solved it as follows.

struct HomeView: View {
    var body: some View {
        VStack {
            Text("Hello!")
        }.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
            ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in })
        }
    }
}
like image 293
donchan Avatar asked Sep 22 '21 11:09

donchan


3 Answers

Instead of calling app tracking transparency permission in didFinishLaunchingWithOptions call in applicationDidBecomeActive it will solve your issue

In AppDelegate

func applicationDidBecomeActive(_ application: UIApplication) {
    requestDataPermission()
}

func requestDataPermission() {
    if #available(iOS 14, *) {
        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:
                print("Unknown")
            }
        })
    } else {
        //you got permission to track, iOS 14 is not yet installed
    }
}

in info.plist

<key>NSUserTrackingUsageDescription</key>
<string>Reason_for_data_tracking</string>
like image 64
Siddhesh Bhide Avatar answered Oct 08 '22 18:10

Siddhesh Bhide


As @donchan already mentioned use the following code:

struct HomeView: View {
    var body: some View {
        VStack {
            Text("Hello!")
        }.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
            ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in })
        }
    }
}
like image 41
Sheikh Wahab Mahmood Avatar answered Oct 08 '22 19:10

Sheikh Wahab Mahmood


For iOS 15, I faced the same problems and I fixed them by delaying code execution for a second.

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        if #available(iOS 14, *) {
            ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
                DispatchQueue.main.async {
                    self.bannerView.load(GADRequest())
                    self.interstitial.load(request)
                }
            })
        } else {
            // Fallback on earlier versions
            self.bannerView.load(GADRequest())
            self.interstitial.load(request)
        }
    }
like image 28
Abhishek Suryawanshi Avatar answered Oct 08 '22 18:10

Abhishek Suryawanshi