根据 Google 欧盟地区用户意见征求政策,您必须向位于欧洲经济区 (EEA) 和英国境内的用户披露相关信息,在法律有相应要求的情况下,必须就 Cookie 或其他本地存储方式的使用征得他们的同意,并使用个人数据(例如 AdID)来投放广告。此政策反映了欧盟《电子隐私指令》和《一般数据保护条例》(GDPR) 的要求。
为了帮助发布商履行此政策规定的职责,Google 提供了 User Messaging Platform (UMP) SDK。UMP SDK 现已更新,支持最新的 IAB 标准。所有这些配置现在都可以 AdMob 在“隐私权和消息”中轻松处理。
前提条件
- 完成入门指南
- 如果您正在处理与 GDPR 相关的要求,请参阅IAB 要求对欧盟地区用户意见征求消息的影响
创建消息类型
创建用户消息时,应选择 可用的用户消息类型 , (在您的 AdMob 帐号的隐私权和消息标签页下)。UMP SDK 会尝试显示通过项目中设置的 AdMob 应用 ID 创建的用户消息。如果没有为您的应用配置消息,SDK 会返回错误。
如需了解详情,请参阅 隐私权和消息简介。
导入 SDK
CocoaPods(首选)
如要将该 SDK 导入 iOS 项目,最简便的方法就是使用 CocoaPods。请打开项目的 Podfile 并将下面这行代码添加到应用的目标中:
pod 'GoogleUserMessagingPlatform'
然后运行以下命令:
pod install --repo-update
如果您刚开始接触 CocoaPods,请参阅使用 CocoaPods,详细了解如何创建和使用 Podfile。
手动下载
另一种方法是手动导入 SDK。
然后,将框架拖入您的 Xcode 项目中,确保已选中 Copy items if needed。
然后,您便可将该框架包含在需要使用的任何文件中:
Swift
import UserMessagingPlatform
Objective-C
#include <UserMessagingPlatform/UserMessagingPlatform.h>
请求提供用户意见征求信息
每次启动应用时,您都应使用 requestConsentInfoUpdateWithParameters:completionHandler:
请求更新用户的意见征求信息。这决定了您的用户是需要提供用户意见征求(如果尚未提供)或用户意见征求是否已过期。
以下示例说明了如何在 viewDidLoad()
方法中从 UIViewController
检查状态。
Swift
override func viewDidLoad() {
super.viewDidLoad()
// Create a UMPRequestParameters object.
let parameters = UMPRequestParameters()
// Set tag for under age of consent. false means users are not under age
// of consent.
parameters.tagForUnderAgeOfConsent = false
// Request an update for the consent information.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
[weak self] requestConsentError in
guard let self else { return }
if let consentError = requestConsentError {
// Consent gathering failed.
return print("Error: \(consentError.localizedDescription)")
}
// TODO: Load and present the consent form.
}
}
Objective-C
- (void)viewDidLoad {
[super viewDidLoad];
// Create a UMPRequestParameters object.
UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init];
// Set tag for under age of consent. NO means users are not under age
// of consent.
parameters.tagForUnderAgeOfConsent = NO;
// Request an update for the consent information.
[UMPConsentInformation.sharedInstance
requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable requestConsentError) {
if (requestConsentError) {
// Consent gathering failed.
NSLog(@"Error: %@", requestConsentError.localizedDescription);
return;
}
// TODO: Load and present the consent form.
}];
}
根据需要加载并显示用户意见征求表单
重要提示:以下 API 与 UMP SDK 2.1.0 或更高版本兼容。收到最新的用户意见征求状态后,请对UMPConsentForm
类调用loadAndPresentIfRequiredFromViewController:completionHandler:
以加载用户意见征求表单。如果需要提供同意情况,SDK 会加载一个表单,并立即 从提供的 view controller显示该表单。用户关闭表单后,系统会调用 completion handler
。如果不需要征得用户同意,系统会立即调用 completion handler
。
Swift
override func viewDidLoad() {
super.viewDidLoad()
// Create a UMPRequestParameters object.
let parameters = UMPRequestParameters()
// Set tag for under age of consent. false means users are not under age
// of consent.
parameters.tagForUnderAgeOfConsent = false
// Request an update for the consent information.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
[weak self] requestConsentError in
guard let self else { return }
if let consentError = requestConsentError {
// Consent gathering failed.
return print("Error: \(consentError.localizedDescription)")
}
UMPConsentForm.loadAndPresentIfRequired(from: self) {
[weak self] loadAndPresentError in
guard let self else { return }
if let consentError = loadAndPresentError {
// Consent gathering failed.
return print("Error: \(consentError.localizedDescription)")
}
// Consent has been gathered.
}
}
}
Objective-C
- (void)viewDidLoad {
[super viewDidLoad];
// Create a UMPRequestParameters object.
UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init];
// Set tag for under age of consent. NO means users are not under age
// of consent.
parameters.tagForUnderAgeOfConsent = NO;
__weak __typeof__(self) weakSelf = self;
// Request an update for the consent information.
[UMPConsentInformation.sharedInstance
requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable requestConsentError) {
if (requestConsentError) {
// Consent gathering failed.
NSLog(@"Error: %@", requestConsentError.localizedDescription);
return;
}
__strong __typeof__(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[UMPConsentForm loadAndPresentIfRequiredFromViewController:strongSelf
completionHandler:^(NSError *loadAndPresentError) {
if (loadAndPresentError) {
// Consent gathering failed.
NSLog(@"Error: %@", loadAndPresentError.localizedDescription);
return;
}
// Consent has been gathered.
}];
}];
}
如果您需要在用户做出选择或关闭表单后执行操作,请将相应逻辑放入表单的 completion handler中。
提出广告请求
在您的应用中请求广告之前,请检查您是否已使用 UMPConsentInformation.sharedInstance.canRequestAds
征得用户同意。在征求用户意见时,可在以下两个位置进行检查:
- 在当前会话中征求用户意见后。
- 调用
requestConsentInfoUpdateWithParameters:completionHandler:
后立即执行。 可能是在之前的会话中已征得用户同意。作为延迟时间最佳做法,我们建议您不要等待回调完成,这样您就可以在应用启动后尽快开始加载广告。
UMPConsentInformation.sharedInstance.canRequestAds
始终返回 false
。如果在征求用户意见的过程中发生错误,您仍应尝试请求广告。UMP SDK 会使用上一个会话的用户意见征求状态。
Swift
class ViewController: UIViewController {
// Use a boolean to initialize the Google Mobile Ads SDK and load ads once.
private var isMobileAdsStartCalled = false
override func viewDidLoad() {
super.viewDidLoad()
// Create a UMPRequestParameters object.
let parameters = UMPRequestParameters()
// Set tag for under age of consent. false means users are not under age
// of consent.
parameters.tagForUnderAgeOfConsent = false
// Request an update for the consent information.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
[weak self] requestConsentError in
guard let self else { return }
if let consentError = requestConsentError {
// Consent gathering failed.
return print("Error: \(consentError.localizedDescription)")
}
UMPConsentForm.loadAndPresentIfRequired(from: self) {
[weak self] loadAndPresentError in
guard let self else { return }
if let consentError = loadAndPresentError {
// Consent gathering failed.
return print("Error: \(consentError.localizedDescription)")
}
// Consent has been gathered.
if UMPConsentInformation.sharedInstance.canRequestAds {
self.startGoogleMobileAdsSDK()
}
}
}
// Check if you can initialize the Google Mobile Ads SDK in parallel
// while checking for new consent information. Consent obtained in
// the previous session can be used to request ads.
if UMPConsentInformation.sharedInstance.canRequestAds {
startGoogleMobileAdsSDK()
}
}
private func startGoogleMobileAdsSDK() {
DispatchQueue.main.async {
guard !self.isMobileAdsStartCalled else { return }
self.isMobileAdsStartCalled = true
// Initialize the Google Mobile Ads SDK.
GADMobileAds.sharedInstance().start()
// TODO: Request an ad.
// GADInterstitialAd.load(...)
}
}
}
Objective-C
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Create a UMPRequestParameters object.
UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init];
// Set tag for under age of consent. NO means users are not under age
// of consent.
parameters.tagForUnderAgeOfConsent = NO;
__weak __typeof__(self) weakSelf = self;
// Request an update for the consent information.
[UMPConsentInformation.sharedInstance
requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable requestConsentError) {
if (requestConsentError) {
// Consent gathering failed.
NSLog(@"Error: %@", requestConsentError.localizedDescription);
return;
}
__strong __typeof__(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[UMPConsentForm loadAndPresentIfRequiredFromViewController:strongSelf
completionHandler:^(NSError *loadAndPresentError) {
if (loadAndPresentError) {
// Consent gathering failed.
NSLog(@"Error: %@", loadAndPresentError.localizedDescription);
return;
}
// Consent has been gathered.
__strong __typeof__(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if (UMPConsentInformation.sharedInstance.canRequestAds) {
[strongSelf startGoogleMobileAdsSDK];
}
}];
}];
// Check if you can initialize the Google Mobile Ads SDK in parallel
// while checking for new consent information. Consent obtained in
// the previous session can be used to request ads.
if (UMPConsentInformation.sharedInstance.canRequestAds) {
[self startGoogleMobileAdsSDK];
}
}
- (void)startGoogleMobileAdsSDK {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Initialize the Google Mobile Ads SDK.
[GADMobileAds.sharedInstance startWithCompletionHandler:nil];
// TODO: Request an ad.
// [GADInterstitialAd loadWithAdUnitID...];
});
}
隐私权选项
某些意见征求表单要求用户随时修改其同意声明。如果需要,请按照以下步骤实现隐私设置选项按钮。
要实现这一目标,需要完成以下步骤:
- 实现可以触发隐私设置选项表单的界面元素,例如应用设置页面中的按钮。
-
loadAndPresentIfRequiredFromViewController:completionHandler:
完成后,检查privacyOptionsRequirementStatus
以确定是否显示可呈现隐私设置选项表单的界面元素。 - 当用户与您的界面元素互动时,调用
presentPrivacyOptionsFormFromViewController:completionHandler:
以显示该表单,以便用户随时更新其隐私设置选项。
以下示例展示了如何通过 UIBarButtonItem
显示隐私权选项表单。
Swift
@IBOutlet weak var privacySettingsButton: UIBarButtonItem!
var isPrivacyOptionsRequired: Bool {
return UMPConsentInformation.shared.privacyOptionsRequirementStatus == .required
}
override func viewDidLoad() {
// ...
// Request an update for the consent information.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
// ...
UMPConsentForm.loadAndPresentIfRequired(from: self) {
//...
// Consent has been gathered.
// Show the button if privacy options are required.
self.privacySettingsButton.isEnabled = isPrivacyOptionsRequired
}
}
// ...
}
// Present the privacy options form when a user interacts with the
// privacy settings button.
@IBAction func privacySettingsTapped(_ sender: UIBarButtonItem) {
UMPConsentForm.presentPrivacyOptionsForm(from: self) {
[weak self] formError in
guard let self, let formError else { return }
// Handle the error.
}
}
Objective-C
@interface ViewController ()
@property(weak, nonatomic) IBOutlet UIBarButtonItem *privacySettingsButton;
@end
- (BOOL)isPrivacyOptionsRequired {
return UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus ==
UMPPrivacyOptionsRequirementStatusRequired;
}
- (void)viewDidLoad {
// ...
__weak __typeof__(self) weakSelf = self;
// Request an update for the consent information.
[UMPConsentInformation.sharedInstance
requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable requestConsentError) {
// ...
[UMPConsentForm loadAndPresentIfRequiredFromViewController:strongSelf
completionHandler:^(NSError *loadAndPresentError) {
// ...
// Consent has been gathered.
// Show the button if privacy options are required.
strongSelf.privacySettingsButton.enabled = isPrivacyOptionsRequired;
}];
}];
}
// Present the privacy options form when a user interacts with your
// privacy settings button.
- (IBAction)privacySettingsTapped:(UIBarButtonItem *)sender {
[UMPConsentForm presentPrivacyOptionsFormFromViewController:self
completionHandler:^(NSError *_Nullable formError) {
if (formError) {
// Handle the error.
}
}];
}
测试
如果您希望在开发过程中测试应用中的集成,请按照以下步骤以编程方式注册测试设备。
- 调用
requestConsentInfoUpdateWithParameters:completionHandler:
。 检查日志输出中是否有类似如下的消息,该消息显示了您的设备 ID 以及如何将其添加为测试设备:
<UMP SDK>To enable debug mode for this device, set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
将测试设备 ID 复制到剪贴板。
修改代码,将其调用
UMPDebugSettings().testDeviceIdentifiers
,并传入您的测试设备 ID 列表。
Swift
let parameters = UMPRequestParameters()
let debugSettings = UMPDebugSettings()
debugSettings.testDeviceIdentifiers = ["TEST-DEVICE-HASHED-ID"]
parameters.debugSettings = debugSettings
// Include the UMPRequestParameters in your consent request.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(
with: parameters,
completionHandler: { error in
...
})
Objective-C
UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init];
UMPDebugSettings *debugSettings = [[UMPDebugSettings alloc] init];
debugSettings.testDeviceIdentifiers = @[ @"TEST-DEVICE-HASHED-ID" ];
parameters.debugSettings = debugSettings;
// Include the UMPRequestParameters in your consent request.
[UMPConsentInformation.sharedInstance
requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable error){
...
}];
强制应用地理位置
UMP SDK 提供了一种使用 the debugGeography
property of type UMPDebugGeography
on UMPDebugSettings
测试应用行为的方式,就像设备位于欧洲经济区 (EEA) 或英国一样。请注意,调试设置仅适用于测试设备。
Swift
let parameters = UMPRequestParameters()
let debugSettings = UMPDebugSettings()
debugSettings.testDeviceIdentifiers = ["TEST-DEVICE-HASHED-ID"]
debugSettings.geography = .EEA
parameters.debugSettings = debugSettings
// Include the UMPRequestParameters in your consent request.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(
with: parameters,
completionHandler: { error in
...
})
Objective-C
UMPRequestParameters *parameters = [[UMPRequestParameters alloc] init];
UMPDebugSettings *debugSettings = [[UMPDebugSettings alloc] init];
debugSettings.testDeviceIdentifiers = @[ @"TEST-DEVICE-HASHED-ID" ];
debugSettings.geography = UMPDebugGeographyEEA;
parameters.debugSettings = debugSettings;
// Include the UMPRequestParameters in your consent request.
[UMPConsentInformation.sharedInstance
requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable error){
...
}];
重置同意情况
使用 UMP SDK 测试应用时,您可能会发现重置 SDK 的状态有助于模拟用户的首次安装体验。SDK 提供了 reset
方法来实现此目的。
Swift
UMPConsentInformation.sharedInstance.reset()
Objective-C
[UMPConsentInformation.sharedInstance reset];
GitHub 上的示例
UMP SDK 集成示例: Swift | Objective-C