0

My app is used to build with Swift 6 and it works perfectly fine. However, since I am using Google AdMob for monetization, I have to implement the App Tracking Transparency (ATT) prompt dialog at the start of the app.

This is my current implementation:

import SwiftUI import GoogleMobileAds import AppTrackingTransparency class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Initialize Mobile Ads SDK MobileAds.shared.start(completionHandler: nil) // Request ATT authorization after a delay DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { self.requestIDFA() } return true } func requestIDFA() { ATTrackingManager.requestTrackingAuthorization { status in // Handle authorization status switch status { case .authorized: print("ATT: User authorized tracking") case .denied: print("ATT: User denied tracking") case .restricted: print("ATT: Tracking is restricted") case .notDetermined: print("ATT: User has not made a choice") @unknown default: print("ATT: Unknown status") } } } } @main struct MyApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() } } } 

I tested with iOS 16 and 17, and it works as expected. But when I tested on iOS 18 emulator, the prompt appears, click on the Allow or Not Allow, and it froze. The user choice is still registered as ATT: User authorized tracking show in the log (and after exit the app and open again, the log still show the correct user ATT choice).

The problem is relating to thread assertion issue. For example:

Thread 2 Queue : com.apple.root.default-qos (concurrent) #0 0x00000001023e4214 in _dispatch_assert_queue_fail () #12 0x00000001025afb38 in _pthread_wqthread () 

My solution: After trying to debug, I found out that I only need to switch from Swift 6 to Swift 5. And the application works again.

My Request: My request is that I still want to build the app with Swift 6 (for future proof purposes), how can I do so? Thanks~

3
  • 1
    Have you tried calling the async version of requestTrackingAuthorization? I know some of the closure-based apis are not ready for Swift 6 yet. Commented Mar 30 at 11:24
  • It actually works, thank you very much. Commented Mar 30 at 12:05
  • For me, after implementing the ATT, the app always froze for several minutes after the first launch. It turned out the issue was caused by Xcode and the simulator — installing the final package on a real device didn’t have this problem. Commented Oct 4 at 23:48

1 Answer 1

0

Thanks to Sweeper for the solution. To fix, I updated the code like this:

func requestIDFA() { Task { @MainActor in let status = await ATTrackingManager.requestTrackingAuthorization() handleATTStatus(status) } } func handleATTStatus(_ status: ATTrackingManager.AuthorizationStatus) { switch status { case .authorized: print("ATT: User authorized tracking") case .denied: print("ATT: User denied tracking") case .restricted: print("ATT: Tracking is restricted") case .notDetermined: print("ATT: User has not made a choice") @unknown default: print("ATT: Unknown status") } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.