基于Google UserMessagingPlatform的用户同意实现三大技术疑问
Google UserMessagingPlatform(UMP)技术疑问
已实现的核心代码
请求同意信息更新
func requestConsentInfoUpdate(in vc: UIViewController, completion: (() -> Void)?) { let parameters = UMPRequestParameters() parameters.tagForUnderAgeOfConsent = false UMPConsentInformation.sharedInstance.requestConsentInfoUpdate( with: parameters, completionHandler: { [weak self] error in if error != nil { // 处理错误 } else { if UMPConsentInformation.sharedInstance.formStatus == UMPFormStatus.available { // 表单可用(且需要同意)时加载表单 self?.loadForm(in: vc, completion: completion) } else if UMPConsentInformation.sharedInstance.formStatus == UMPFormStatus.unknown { // 文档建议再次请求更新 self?.requestConsentInfoUpdate(in: vc, completion: completion) } else { completion?() } } }) }
该函数在首个ViewController展示时调用,确保广告启动前完成隐私流程。
表单加载与展示
private func loadForm(in vc: UIViewController, completion: (() -> Void)?) { UMPConsentForm.load(completionHandler: { [weak self] form, loadError in if loadError != nil { // 处理错误 } else { if UMPConsentInformation.sharedInstance.consentStatus == UMPConsentStatus.required { self?.present(form: form, in: vc, completion: completion) } else { completion?() } } }) } private func present(form: UMPConsentForm?, in vc: UIViewController, completion: (() -> Void)?) { form?.present( from: vc, completionHandler: { [weak self] _ in if UMPConsentInformation.sharedInstance.consentStatus == UMPConsentStatus.obtained { GADMobileAds.sharedInstance().start(completionHandler: nil) completion?() } }) }
具体疑问解答
1. 未成年人标识如何处理?
不能默认设置tagForUnderAgeOfConsent = false,需严格按照合规要求处理:
- 如果应用核心受众是未成年人,直接将该参数设为
true,UMP会自动适配未成年人专属合规流程(不展示个性化广告相关选项)。 - 如果应用可能覆盖未成年用户,必须先通过年龄验证流程确认用户年龄:
- 用户确认是未成年人时,设置
tagForUnderAgeOfConsent = true; - 用户确认是成年人时,设置为
false。
- 用户确认是未成年人时,设置
- 跳过年龄验证直接默认成年人属于违规操作,会违反GDPR等隐私法规。
2. 是否存在无限递归风险?
当前实现确实存在无限递归风险。如果UMPFormStatus.unknown状态持续出现(比如网络异常、服务器无响应),代码会无限制重复调用requestConsentInfoUpdate,最终导致栈溢出或应用卡顿。
解决方法是添加重试次数限制:
// 修改函数,增加重试次数参数 func requestConsentInfoUpdate(in vc: UIViewController, retryCount: Int = 3, completion: (() -> Void)?) { let parameters = UMPRequestParameters() parameters.tagForUnderAgeOfConsent = false UMPConsentInformation.sharedInstance.requestConsentInfoUpdate( with: parameters, completionHandler: { [weak self] error in if error != nil { completion?() } else { switch UMPConsentInformation.sharedInstance.formStatus { case .available: self?.loadForm(in: vc, completion: completion) case .unknown: if retryCount > 0 { self?.requestConsentInfoUpdate(in: vc, retryCount: retryCount - 1, completion: completion) } else { // 重试次数耗尽,直接执行完成回调 completion?() } default: completion?() } } }) }
设置合理的重试次数(比如3次),超过后终止递归,避免无限循环。
3. 如何向中介广告合作伙伴传递同意信息?
UMPConsentStatus.obtained仅表示用户完成了同意流程,不代表用户同意个性化广告。需根据UMP返回的具体同意细节,向中介平台传递对应状态:
获取具体同意状态:
通过UMPConsentInformation.sharedInstance.consentType或consentDetails获取用户的实际选择,比如是否同意个性化广告、是否同意数据收集等。Unity Ads 适配示例:
在UMP表单展示完成的回调中,根据用户的同意状态调用Unity Ads的GDPR API:
private func present(form: UMPConsentForm?, in vc: UIViewController, completion: (() -> Void)?) { form?.present( from: vc, completionHandler: { [weak self] _ in let consentInfo = UMPConsentInformation.sharedInstance // 启动谷歌广告 GADMobileAds.sharedInstance().start(completionHandler: nil) // 向Unity Ads传递GDPR同意状态 let hasConsentForPersonalizedAds = consentInfo.consentType == .personalized UnityAds.setGDPRConsentStatus(hasConsentForPersonalizedAds ? .granted : .denied) completion?() }) }
注意:不同中介平台的API调用方式不同,需参考对应平台的隐私合规文档,确保在用户完成UMP流程后及时传递正确的同意状态。
内容的提问来源于stack exchange,提问作者oneshot
相关产品推荐
相关产品推荐

