征求欧洲用户同意

根据 Google《欧盟地区用户意见征求政策》,您必须向位于欧洲经济区 (EEA) 内的用户披露相关信息;在法律有相应要求的情况下,您必须征得他们的同意才能使用 Cookie 或其他本地存储方式;您同样必须征得他们的同意才能使用个人数据(如 AdID)来投放广告。此政策反映了《欧盟电子隐私指令》和《一般数据保护条例》(GDPR) 的要求。

为了帮助发布商履行此政策规定的职责,Google 提供了 Consent SDK。Consent SDK 是一个开源代码库,提供用于征求用户意见的实用程序函数。完整源代码可在 GitHub 上找到。

Google 投放的广告可分为个性化广告和非个性化广告,投放这两类广告都需要在欧洲经济区 (EEA) 内征求用户意见。默认情况下,向 Google 发出的广告请求会投放个性化广告,并根据以前收集的用户数据筛选广告。Google 也支持通过配置广告请求来投放非个性化广告。详细了解个性化广告和非个性化广告

本指南介绍了如何使用 Consent SDK 征求用户意见,以及在征得用户意见后如何将用户意见转发给 Google 移动广告 SDK

前提条件

CocoaPods(首选)

将 SDK 导入 iOS 项目的最简便方法就是使用 CocoaPods。请打开项目的 Podfile 并将下面这行代码添加到应用的目标中:

pod 'PersonalizedAdConsent'

然后使用命令行运行:

pod install --repo-update

如果您刚开始接触 CocoaPods,请参阅其官方文档,了解如何创建和使用 Podfile。

手动下载

您也可以直接下载或克隆 SDK 的源代码,并按照以下说明将其添加到项目中:

  1. 在“访达”中,将 PersonalizedAdConsent.xcodeproj 文件拖拽到项目中。

  2. 导航至 Build Phases 标签页。在 Target Dependencies 下,点击 + 按钮,然后添加 PersonalizedAdConsent 目标。

  3. 右键点击项目,然后选择 Add Files to "MyProject"。导航至 PersonalizedAdConsent.bundle。请确保选中 Create folder references

    添加完成后,您应该会在 Copy Bundle Resources 部分的 Build Phases 标签页中看到列出的 PersonalizedAdConsent.bundle

在使用 Consent SDK 中的任何其他方法之前,您都应该更新用户意见状态以确保 Consent SDK 具有您在 AdMob 界面中所选择的广告技术提供商的最新信息。如果自用户上次提供用户意见后,广告技术提供商列表出现任何更改,则系统会将用户意见状态重新设置为未知状态。

如果您不使用中介

如果您不使用中介,则有两种方法可以实现 Consent SDK 来征求用户意见。

一种方法是使用 Consent SDK 向用户显示由 Google 呈现的用户意见征求表单。该用户意见征求表单会显示您在 AdMob 界面中选择的广告技术提供商列表。而 Consent SDK 会存储用户的意见回复。

另一种方法是使用 Consent SDK 从 AdMob 动态获取完整的广告技术提供商列表,详情请参阅由发布商管理的用户意见征求。但是,在这种情况下,您需要确定如何向用户呈现提供商列表,并向用户显示您自己的用户意见征求表单。

一旦用户做出了用户意见选择,您可以让 Consent SDK 存储该用户的意见选择,详情请参阅存储由发布商管理的用户意见

征得用户意见后,如果用户仅同意接收非个性化广告,则您需要将用户意见转发给 Google 移动广告 SDK

如果您使用 AdMob 中介

您可以使用 Consent SDK 从 AdMob 动态获取完整的广告技术提供商列表,详情请参阅由发布商管理的用户意见征求。对于来自其他广告联盟的广告技术提供商,您需要确定应向用户显示其中哪些提供商来征求用户意见。

作为应用开发者,您既需要为 Consent SDK 所返回的广告技术提供商征求用户意见,也需要为来自其他广告联盟的提供商征求用户意见。如果用户仅同意接收非个性化广告,那么您还需要手动存储用户的意见回复,并将用户意见转发给 Google 移动广告 SDK

Google 目前无法为中介广告联盟征求和处理用户意见,因此您需要为每个广告联盟单独征求和处理用户意见。我们正积极与所有开源且对版本进行标注的中介广告联盟合作,以提供有关如何转发用户意见的详细更新文档。以下中介广告联盟的有关文档已发布:

更新用户意见状态

使用 Consent SDK 时,建议您在每次启动应用时都要确定用户的意见状态。为此,请在 PACConsentInformation 的实例上调用 requestConsentInfoUpdateForPublisherIdentifiers:completionHandler:

Swift

import PersonalizedAdConsent
...
class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    PACConsentInformation.sharedInstance.
    requestConsentInfoUpdate(
    forPublisherIdentifiers: ["pub-0123456789012345"])
    {(_ error: Error?) -> Void in
      if let error = error {
        // Consent info update failed.
      } else {
        // Consent info update succeeded. The shared PACConsentInformation
        // instance has been updated.
      }
    }
  }

Objective-C

#import <PersonalizedAdConsent/PersonalizedAdConsent.h>
...
@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  [PACConsentInformation.sharedInstance
      requestConsentInfoUpdateForPublisherIdentifiers:@[ @"pub-0123456789012345" ]
          completionHandler:^(NSError *_Nullable error) {
            if (error) {
              // Consent info update failed.
            } else {
              // Consent info update succeeded. The shared PACConsentInformation
              // instance has been updated.
            }
          }];
}

调用 requestConsentInfoUpdateForPublisherIdentifiers:completionHandler: 需要两个参数:

  • 一组有效且完全激活的发布商 ID,供您的应用发出广告请求。 找到您的发布商 ID

  • 一个接受 NSError 作为输入参数的块,该块会提供失败的用户意见更新请求的相关信息。

如果用户意见信息更新成功,那么 PACConsentInformation.sharedInstance.consentStatus 会提供更新后的用户意见状态。该状态可能具有下列值:

用户意见状态 定义
PACConsentStatusPersonalized 用户已同意接收个性化广告。
PACConsentStatusNonPersonalized 用户已同意接收非个性化广告。
PACConsentStatusUnknown 用户既未同意接收也未拒绝接收个性化广告或非个性化广告。

用户意见信息更新成功后,您还可以检查 PACConsentInformation.sharedInstance.requestLocationInEEAOrUnknown,以查看用户是否位于欧洲经济区内或者请求位置是否未知。

如果 requestLocationInEEAOrUnknown 属性的值为 NO,则该用户不在欧洲经济区内,并且无需根据《欧盟地区用户意见征求政策》征求用户意见。您可以向 Google 移动广告 SDK 发出广告请求。

如果 requestLocationInEEAOrUnknown 属性的值为 YES

Google 的 Consent SDK 提供了两种征求用户意见的方法:

请务必记住为用户提供更改或撤消用户意见的选项。

由 Google 呈现的用户意见征求表单显示在应用内容之上,是一种可配置的全屏表单。在进行相关配置后,您可向用户显示以下选项组合而成的内容:

  • 同意观看个性化广告
  • 同意观看非个性化广告
  • 使用付费版本应用而不观看广告

您应该仔细阅读用户意见文本。一般来说,当您为了通过应用获利而使用 Google 时,默认情况下显示的信息可能已适合您的需要;但对于哪种意见文本适合您的情况,我们无法提供任何法律建议。如要更新由 Google 呈现的用户意见征求表单中的用户意见文本,可根据需要修改 Consent SDK 中的 consentform.html 文件。

您可以使用 PACConsentForm 类来配置和显示由 Google 呈现的用户意见征求表单。以下代码演示了如何使用所有三个表单选项来构建 PACConsentForm

Swift

// TODO: Replace with your app's privacy policy url.
guard let privacyUrl = URL(string: "https://www.your.com/privacyurl"),
  let form = PACConsentForm(applicationPrivacyPolicyURL: privacyUrl) else {
    print("incorrect privacy URL.")
    return
}
form.shouldOfferPersonalizedAds = true
form.shouldOfferNonPersonalizedAds = true
form.shouldOfferAdFree = true

Objective-C

// TODO: Replace with your app's privacy policy url.
NSURL *privacyURL = [NSURL URLWithString:@"https://www.your.com/privacyurl"];
PACConsentForm *form = [[PACConsentForm alloc] initWithApplicationPrivacyPolicyURL:privacyURL];
form.shouldOfferPersonalizedAds = YES;
form.shouldOfferNonPersonalizedAds = YES;
form.shouldOfferAdFree = YES;

以下是 PACConsentForm 属性的进一步详细说明:

shouldOfferPersonalizedAds
表示用户意见征求表单是否应显示个性化广告选项。默认为 YES
shouldOfferNonPersonalizedAds
表示用户意见征求表单是否应显示非个性化广告选项。默认为 YES
shouldOfferAdFree
表示用户意见征求表单是否应显示无广告应用选项。默认为 NO

创建并配置 PACConsentForm 对象后,请调用 PACConsentFormloadWithCompletionHandler: 方法加载用户意见征求表单,如下所示:

Swift

form.load {(_ error: Error?) -> Void in
  print("Load complete.")
  if let error = error {
    // Handle error.
    print("Error loading form: \(error.localizedDescription)")
  } else {
    // Load successful.
  }
}

Objective-C

[form loadWithCompletionHandler:^(NSError *_Nullable error) {
  NSLog(@"Load complete. Error: %@", error);
  if (error) {
    // Handle error.
  } else {
    // Load successful.
  }
}];

要向用户显示由 Google 呈现的用户意见征求表单,请在已加载的 PACConsentForm 上调用 presentFromViewController:dismissCompletion:,如下所示:

Swift

form.present(from: self) { (error, userPrefersAdFree) in
      if let error = error {
        // Handle error.
      } else if userPrefersAdFree {
        // User prefers to use a paid version of the app.
      } else {
        // Check the user's consent choice.
        let status =
             PACConsentInformation.sharedInstance.consentStatus
      }
    }

Objective-C

 [form presentFromViewController:self
     dismissCompletion:^(NSError *_Nullable error, BOOL userPrefersAdFree) {
       if (error) {
         // Handle error.
       } else if (userPrefersAdFree) {
         // The user prefers to use a paid version of the app.
       } else {
         // Check the user's consent choice.
         PACConsentStatus status =
             PACConsentInformation.sharedInstance.consentStatus;
       }
     }];

调用 presentFromViewController:dismissCompletion: 需要两个参数:

  • 用于显示表单的 UIViewController

  • 一个接受 NSErrorBOOL 作为输入参数的块。如果显示用户意见征求表单时出现错误,则 NSError 会提供相关信息。当用户选择使用付费版本应用而不观看广告时,userPrefersAdFree BOOL 的值为 YES

在用户选择一个选项并关闭表单后,Consent SDK 会保存用户的选择并调用 dismissCompletion: 块。您可以读取用户的选择并将用户意见转发给 Google 移动广告 SDK

由发布商管理的用户意见征求

如果您选择自行征求用户意见,则可以使用 PACConsentInformation 类的 adProviders 属性获取与您应用中使用的发布商 ID 相关联的广告技术提供商。请注意,凡是针对您的发布商 ID 配置的所有广告技术提供商,您均需为其征求用户意见。

您必须等待用户意见状态更新成功后才能访问 PACConsentInformationadProviders 属性,详情请参阅更新用户意见状态部分。

Swift

let adProviders = PACConsentInformation.sharedInstance.adProviders

Objective-C

NSArray *adProviders = PACConsentInformation.sharedInstance.adProviders;

然后,您可以使用广告提供商列表自行征求用户意见。

征得用户意见后,请使用 PACConsentInformation 类的 status 属性记录用户回复所对应的 PACConsentStatus

Swift

PACConsentInformation.sharedInstance.consentStatus = .personalized

Objective-C

PACConsentInformation.sharedInstance.consentStatus = PACConsentStatusPersonalized;

在将用户意见报告给 Consent SDK 后,您可以将用户意见转发给 Google 移动广告 SDK

要允许用户更新其意见,只需在用户选择更新其意见状态时重复征求用户意见部分列出的步骤。

如果发布商知道用户未达到自主年龄,则所有广告请求都必须设置 TFUA(“Tag For Users under the Age of Consent in Europe”)标记,以表示用户位于欧洲境内但未达到自主年龄。要在您的应用发出的所有广告请求中包含此标记,将 tagForUnderAgeOfConsent 属性设置为 YES。此设置将在以后的所有广告请求中生效。

Swift

PACConsentInformation.sharedInstance.isTaggedForUnderAgeOfConsent = true

Objective-C

PACConsentInformation.sharedInstance.tagForUnderAgeOfConsent = YES;

一旦启用 TFUA 设置,将无法加载由 Google 呈现的用户意见征求表单。因此,凡是包含 TFUA 的所有广告请求,均将无法投放个性化广告和再营销广告。TFUA 禁止向第三方广告技术(例如广告衡量像素和第三方广告服务器)提供商发送请求。

要从广告请求中移除 TFUA,将 tagForUnderAgeOfConsent 属性设置为 NO

测试

Consent SDK 的行为会有所不同,具体取决于 PACConsentInformation.sharedInstance.requestLocationInEEAOrUnknown 的值。例如,如果用户不在欧洲经济区 (EEA) 内,则无法加载用户意见征求表单。

为了让您在欧洲经济区 (EEA) 境内和境外都能更轻松地测试您的应用,Consent SDK 支持可在调用 Consent SDK 中的任何其他方法前进行设置的调试选项。

  1. 获取您设备的广告 ID。您可以使用以下代码来记录您的广告 ID:

    #import <AdSupport/AdSupport.h>
    // ...
    
    NSLog(@"Advertising ID: %@",
          ASIdentifierManager.sharedManager.advertisingIdentifier.UUIDString);

    然后检查控制台,以获取该广告 ID:

    Advertising ID: 41E538F6-9C98-4EF2-B3EE-D7BD8CAF8339
  2. 使用从控制台获取的广告 ID 将您的设备指定为测试设备:

    PACConsentInformation.sharedInstance.debugIdentifiers =
        @[ @"41E538F6-9C98-4EF2-B3EE-D7BD8CAF8339" ];
  3. 最后,请将 debugGeography 设置为您的首选地理测试位置。

    // Geography appears as in EEA for debug devices.
    PACConsentInformation.sharedInstance.debugGeography = PACDebugGeographyEEA;
    // Geography appears as not in EEA for debug devices.
    PACConsentInformation.sharedInstance.debugGeography = PACDebugGeographyNotEEA;

完成这些步骤后,调用更新用户意见状态时均会将您的调试地理位置考虑在内。

此部分中的代码可用于任何版本的 Google 移动广告 SDK。无论您是否使用 Consent SDK 征求用户意见,均可使用这些代码。

默认的 Google 移动广告 SDK 行为是投放个性化广告。如果用户仅同意接收非个性化广告,您可以配置 GADRequest 对象,以指定只应请求非个性化广告。无论用户是否在欧洲经济区 (EEA) 内,以下代码都会导致请求非个性化广告:

Swift

let request = GADRequest()
let extras = GADExtras()
extras.additionalParameters = ["npa": "1"]
request.register(extras)

Objective-C

GADRequest *request = [GADRequest request];
GADExtras *extras = [[GADExtras alloc] init];
extras.additionalParameters = @{@"npa": @"1"};
[request registerAdNetworkExtras:extras];

如果请求的是非个性化广告,则广告请求网址目前会包含 &npa=1。但请注意,这是 Google 移动广告 SDK 的内部实现细节,随时可能会出现更改。

延迟应用衡量(可选)

默认情况下,Google 移动广告 SDK 会初始化应用衡量标准,然后在应用启动时立即开始向 Google 发送用户级事件数据。此初始化行为确保您可以启用 AdMob 用户指标,无需对代码做出其他更改。

但是,如果您的应用需要在征求用户意见后才能发送这些事件,则可以延迟应用衡量,直到明确地初始化移动广告 SDK 或加载广告为止。

要延迟应用衡量,请将布尔值为 YESGADDelayAppMeasurementInit 键添加到应用的 Info.plist。您可以通过编程方式进行此项更改:

<key>GADDelayAppMeasurementInit</key>
<true/>

您也可以在属性列表编辑器中对其进行修改:

常见问题解答

Consent SDK 支持多少家广告技术提供商?
Consent SDK 不限制发布商选择启用的广告技术提供商数量。
如果我在 AdMob 界面中更改我的选择,是否会自动更新 SDK 返回的广告技术提供商列表?
会。如果您对 AdMob 界面中的广告技术提供商列表进行了更改,那么这些更改会在大约一小时内传播到 Google 的广告服务器。