From db9fa3cbc1e57c6f14d835adac7967b473183fb6 Mon Sep 17 00:00:00 2001 From: Duc Phi Viet Date: Sun, 8 Mar 2026 22:57:14 +0100 Subject: [PATCH 1/2] Defer ATT request until app becomes active --- ios/Classes/TrackingAuthorizationPlugin.swift | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/ios/Classes/TrackingAuthorizationPlugin.swift b/ios/Classes/TrackingAuthorizationPlugin.swift index 2ea9ffd7..9742c99f 100644 --- a/ios/Classes/TrackingAuthorizationPlugin.swift +++ b/ios/Classes/TrackingAuthorizationPlugin.swift @@ -40,19 +40,31 @@ public class TrackingAuthorizationPlugin: NSObject, FlutterPlugin { private func requestTrackingAuthorization(result: @escaping FlutterResult) { if #available(iOS 14, *) { - removeObserver() - ATTrackingManager.requestTrackingAuthorization { [weak self] status in - if status == .denied && ATTrackingManager.trackingAuthorizationStatus == .notDetermined { - self?.addObserver(result: result) - return - } - result(Int(status.rawValue)) - } + requestTrackingAuthorizationWhenActive(result: result) } else { result(Self.notSupportedStatus) } } + @available(iOS 14, *) + private func requestTrackingAuthorizationWhenActive(result: @escaping FlutterResult) { + if UIApplication.shared.applicationState != .active { + addObserver(result: result) + return + } + + removeObserver() + ATTrackingManager.requestTrackingAuthorization { [weak self] status in + if status == .denied && ATTrackingManager.trackingAuthorizationStatus == .notDetermined { + self?.addObserver(result: result) + return + } + + self?.removeObserver() + result(Int(status.rawValue)) + } + } + private func addObserver(result: @escaping FlutterResult) { removeObserver() observer = NotificationCenter.default.addObserver( From 7a42f461b15aca203bda5bfbd75c02c989e22d2b Mon Sep 17 00:00:00 2001 From: Jakub Mrozek Date: Tue, 31 Mar 2026 19:04:37 +0200 Subject: [PATCH 2/2] Add comment explaining concurrent call assumption in addObserver --- ios/Classes/TrackingAuthorizationPlugin.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ios/Classes/TrackingAuthorizationPlugin.swift b/ios/Classes/TrackingAuthorizationPlugin.swift index 9742c99f..b5e742be 100644 --- a/ios/Classes/TrackingAuthorizationPlugin.swift +++ b/ios/Classes/TrackingAuthorizationPlugin.swift @@ -66,6 +66,9 @@ public class TrackingAuthorizationPlugin: NSObject, FlutterPlugin { } private func addObserver(result: @escaping FlutterResult) { + // Concurrent calls are not expected here — the Dart layer enforces a single + // in-flight ATT request. removeObserver() is called defensively in case that + // assumption is ever violated. removeObserver() observer = NotificationCenter.default.addObserver( forName: UIApplication.didBecomeActiveNotification,