MacOS/MacCatalyst调用ATTrackingManager请求追踪授权无弹窗如何解决
问题原因
- 调用时机不匹配:MacCatalyst 运行时中,
ViewDidLoad阶段应用的根窗口尚未完全注册到系统的窗口服务,ATT 授权弹窗依赖当前活跃的 keyWindow 作为展示宿主,此时调用会因找不到有效展示容器而静默失败,不会触发弹窗。 - Info.plist 配置缺失/不生效:若仅为 iOS 目标配置了
NSUserTrackingUsageDescription权限描述,未同步给 MacCatalyst 目标启用该配置,系统会直接拦截授权请求,不会弹出提示。 - 系统全局权限关闭:Mac 系统的「隐私与安全性」设置中如果关闭了「允许App请求跟踪」总开关,所有应用的跟踪授权请求都会被直接拒绝,不会弹出弹窗。
- 系统版本不支持:
ATTrackingManager仅兼容 MacOS 10.15.4 及以上版本,若 MacCatalyst 部署目标低于该版本,接口调用会直接失效。
解决方法
- 调整授权调用时机
不要在ViewDidLoad中调用请求,改为在ViewDidAppear:阶段触发,或者监听UIApplicationDidBecomeActiveNotification通知,等应用完全进入活跃状态后再调用,示例代码如下:
import AppTrackingTransparency import AdSupport // 方式1:在ViewDidAppear中调用 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) requestTrackingPermission() } // 方式2:监听应用活跃通知 override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(requestTrackingPermission), name: UIApplication.didBecomeActiveNotification, object: nil) } @objc private func requestTrackingPermission() { guard #available(macOS 10.15.4, iOS 14, *) else { return } // 先判断是否还未请求过权限,非未决定状态下调用不会弹出弹窗 guard ATTrackingManager.trackingAuthorizationStatus == .notDetermined else { return } ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in print(status) switch status { case .authorized: break case .notDetermined: break case .restricted: break case .denied: break @unknown default: break } }) }
- 校验Info.plist配置
确保项目Info.plist中已经添加NSUserTrackingUsageDescription字段,填写了明确的权限使用说明,同时在Xcode的项目配置页中,确认该字段的目标成员资格包含MacCatalyst运行目标。 - 检查Mac系统全局权限
打开「系统设置→隐私与安全性→跟踪」,确认「允许App请求跟踪」开关处于开启状态。如果开关已关闭,授权请求会直接返回denied状态,不会弹出弹窗,需要引导用户手动开启该开关后再尝试。 - 确认部署版本要求
将项目的MacCatalyst部署目标设置为10.15.4及以上,或者调用接口前添加版本判断,避免在不支持的系统版本上调用失效接口。
内容的提问来源于stack exchange,提问作者ZArez
相关产品推荐
相关产品推荐

