iOS/Swift应用GDPR与ATT权限适配问题(遭苹果拒审求助)
iOS/Swift应用GDPR与ATT弹窗逻辑优化(解决苹果拒审问题)
问题背景
应用在EEA地区先弹出GDPR授权弹窗,再显示ATT授权弹窗,违反苹果审核规则:
用户一旦拒绝追踪权限,同一请求流程内不得再次询问;在用户授予追踪权限前,不得开展任何追踪活动
需要根据GDPR表单的用户选择结果,决定是否发起ATT授权请求,但现有代码无法实现该逻辑。
现有代码问题
- 仅通过
UMPConsentStatus判断是否完成GDPR授权,无法获取用户是否允许广告追踪的具体选择 loadForm方法存在循环调用(弹窗关闭后再次调用loadForm),会导致无限弹窗- ATT授权请求时机不符合苹果要求,未结合GDPR结果判断
解决方案
核心思路:GDPR授权完成后,检查用户是否同意个性化广告/跨应用追踪类权限,仅当用户同意时才请求ATT授权;否则直接初始化广告,跳过ATT请求。
修改后的代码实现
func setupAdvertisement() { fatalError("This method must be overridden in the subclass") } func requestATTAuthorizationIfNeeded() { guard #available(iOS 14.5, *) else { return } let trackingStatus = ATTrackingManager.trackingAuthorizationStatus if trackingStatus == .notDetermined { ATTrackingManager.requestTrackingAuthorization { [weak self] _ in DispatchQueue.main.async { self?.setupAdvertisement() } } } else { setupAdvertisement() } } func showAdvertisement() { // 直接初始化广告,不再在此处处理ATT请求 DispatchQueue.main.async { self.setupAdvertisement() } } @objc func handleConsentCompletion() { let consentInfo = UMPConsentInformation.sharedInstance switch consentInfo.consentStatus { case .required: loadForm() case .obtained, .notRequired: // 检查用户是否允许个性化广告(即同意追踪类行为) let allowsPersonalizedAds = consentInfo.consentStatus == .obtained && consentInfo.adProviders.isEmpty == false // 可通过UMPConsentDetails获取更精准选择 if allowsPersonalizedAds { requestATTAuthorizationIfNeeded() } else { showAdvertisement() } case .unknown: print("GDPR consent status unknown") @unknown default: print("Unexpected GDPR consent status") } } func UMPSetup() { let parameters = UMPRequestParameters() parameters.tagForUnderAgeOfConsent = false UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) { [weak self] error in if let error = error { print("UMP setup error: \(error.localizedDescription)") // 出错时默认按非EEA地区处理,直接检查ATT self?.requestATTAuthorizationIfNeeded() return } let formStatus = UMPConsentInformation.sharedInstance.formStatus if formStatus == .available { self?.loadForm() } else { // 无需GDPR授权,直接处理ATT self?.requestATTAuthorizationIfNeeded() } } } func loadForm() { UMPConsentForm.load { [weak self] form, loadError in guard let self = self else { return } if let error = loadError { print("Load consent form error: \(error.localizedDescription)") self.handleConsentCompletion() return } guard let form = form, UMPConsentInformation.sharedInstance.consentStatus == .required else { self.handleConsentCompletion() return } form.present(from: self) { dismissError in if let error = dismissError { print("Present consent form error: \(error.localizedDescription)") } // 弹窗关闭后处理后续逻辑,不再循环调用loadForm self.handleConsentCompletion() } } }
关键修改说明
- 新增
requestATTAuthorizationIfNeeded方法:单独处理ATT授权请求,仅在状态为.notDetermined时发起请求,完成后初始化广告 - 优化
handleConsentCompletion逻辑:- GDPR授权完成后,通过
UMPConsentInformation判断用户是否允许个性化广告(如需更精准可通过UMPConsentDetails获取细分授权) - 仅当用户同意个性化广告时,才请求ATT授权;否则直接初始化广告
- GDPR授权完成后,通过
- 修复循环弹窗问题:移除
loadForm中弹窗关闭后重复调用自身的逻辑,改为调用handleConsentCompletion处理后续流程 - 错误处理优化:UMP请求或表单加载出错时,默认按非EEA地区处理,避免阻塞广告初始化
补充说明
- 若需更精准的用户GDPR选择,可通过
UMPConsentDetails.sharedInstance获取用户对每个广告供应商的授权情况 - 确保所有追踪行为(包括广告初始化)仅在用户同意ATT或GDPR允许时执行,严格符合苹果审核要求
内容的提问来源于stack exchange,提问作者đăng Phan Nhật
相关产品推荐
相关产品推荐

