You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:27:07