ATTrackingManager.requestTrackingAuthorization在Not Determined状态下未弹出
解决方案
核心问题分析
你的determineDataTrackingStatus方法存在异步逻辑错误:ATTrackingManager.requestTrackingAuthorization是异步执行的,闭包内的代码不会立刻执行,所以你直接返回的authorizationStatus永远是nil,导致后续的二次调用逻辑完全无效。另外,你需要控制视图渲染流程,确保ATT授权完成后再进入主界面。
修正后的代码实现
1. 更新ContentView,控制视图流程
import SwiftUI import AppTrackingTransparency import UIKit enum Tab { case photos case list } struct ContentView: View { @EnvironmentObject var authState: AuthenticationState @State private var selection: Tab = .photos // 控制ATT检查是否完成,完成后才显示主视图 @State private var isATTChecked = false // 保存当前ATT授权状态 @State private var attStatus: ATTrackingManager.AuthorizationStatus? var body: some View { Group { if isATTChecked { // ATT检查完成后,显示主界面 if authState.loggedInUser != nil { SeriesTabs(selection: $selection) } else { AuthentiationView() } } else { // ATT检查中,可显示加载提示或空视图 ProgressView("准备中...") } } .onAppear(perform: checkATTAuthorization) // 监听应用激活事件,每次打开/回到前台都检查ATT状态 .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in checkATTAuthorization() } } private func checkATTAuthorization() { guard #available(iOS 14, *) else { // iOS14以下无需处理,直接标记检查完成 isATTChecked = true return } // 先获取当前状态,避免重复弹窗 let currentStatus = ATTrackingManager.trackingAuthorizationStatus attStatus = currentStatus switch currentStatus { case .notDetermined: // 未确定状态,发起授权请求 ATTrackingManager.requestTrackingAuthorization { status in DispatchQueue.main.async { self.attStatus = status self.isATTChecked = true self.printATTStatus(status) } } default: // 已确定状态,直接标记检查完成 isATTChecked = true printATTStatus(currentStatus) } } private func printATTStatus(_ status: ATTrackingManager.AuthorizationStatus) { switch status { case .authorized: print("授权允许跟踪") case .denied: print("授权拒绝跟踪") case .notDetermined: print("授权未确定") case .restricted: print("授权受限制") @unknown default: print("未知授权状态") } } }
2. 关于ApplicationDidBecomeActive的设置
在SwiftUI中,不需要单独配置AppDelegate,直接在View或App结构体中通过onReceive监听系统通知即可。上面的代码已经在ContentView中添加了监听:
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in checkATTAuthorization() }
这段代码会在应用每次从后台回到前台、或者首次启动激活时触发ATT状态检查。
关键说明
- ATT系统弹窗仅会在用户首次遇到
.notDetermined状态时弹出一次,用户选择允许/拒绝后,后续再调用requestTrackingAuthorization不会再弹系统提示。如果需要重新触发弹窗,用户必须前往「设置-隐私与安全性-跟踪」中重置应用的跟踪权限。 - 我们通过
isATTChecked变量控制视图渲染,确保用户完成ATT授权(或状态已确定)后,才进入登录/主界面,符合你的需求。
内容的提问来源于stack exchange,提问作者Jacksonsox
相关产品推荐
相关产品推荐

