Requesting Consent from European Users

Under the Google EU User Consent Policy, you must make certain disclosures to your users in the European Economic Area (EEA) and obtain their consent to use cookies or other local storage, where legally required, and to use personal data (such as AdID) to serve ads. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR). To support publishers in meeting their duties under this policy, Google offers a Consent SDK.

Ads served by Google can be categorized as personalized or non-personalized, both requiring consent from users in the EEA. By default, ad requests to Google serve personalized ads, with ad selection based on the user's previously collected data. Google also supports configuring ad requests to serve non-personalized ads. Learn more about personalized and non-personalized ads.

This guide describes how to use the Consent SDK to obtain consent from users. It also describes how to forward consent to the Google Mobile Ads SDK once you have obtained consent.

Prerequisites

The Consent SDK is an open-source library that provides utility functions for collecting consent from your users. The full source code is available on GitHub.

CocoaPods (preferred)

The simplest way to import the SDK into an iOS project is with CocoaPods. Open your project's Podfile and add this line to your app's target:

pod 'PersonalizedAdConsent'

Then from the command line run:

pod install --repo-update

If you're new to CocoaPods, see their official documentation for info on how to create and use Podfiles.

Manual download

You can also download or clone the source of the SDK directly, and follow these instructions to include it in your project:

  1. From finder, drag the PersonalizedAdConsent.xcodeproj file into your project.

  2. Navigate to the Build Phases tab. Under Target Dependencies, click the + button, and add the PersonalizedAdConsent target.

  3. Right-click your project, and select Add Files to "MyProject".... Navigate to PersonalizedAdConsent.bundle. Make sure to check Create folder references.

    Once this is finished, you should see PersonalizedAdConsent.bundle listed in the Build Phases tab under the Copy Bundle Resources section.

When using the Consent SDK, it is recommended that you determine the status of a user's consent at every app launch. To do this, call requestConsentInfoUpdateForPublisherIdentifiers:completionHandler: on an instance of PACConsentInformation.

Swift

import PACPersonalizedAdConsent
...

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.
            }
          }];
}

The call to requestConsentInfoUpdateForPublisherIdentifiers:completionHandler: requires two arguments:

  • An array of publisher IDs that your app requests ads from. Find your publisher ID.

  • A block that accepts an NSError as an input parameter, which provides information on a failed consent update request.

If consent information is successfully updated, PACConsentInformation.sharedInstance.consentStatus provides the updated consent status. It may have the values listed below:

Consent State Definition
PACConsentStatusPersonalized The user has granted consent for personalized ads.
PACConsentStatusNonPersonalized The user has granted consent for non-personalized ads.
PACConsentStatusUnknown The user has neither granted nor declined consent for personalized or non-personalized ads.

Once consent information is successfully updated, you can also check PACConsentInformation.sharedInstance.requestLocationInEEAOrUnknown to see if the user is located in the European Economic Area or the request location is unknown.

If the requestLocationInEEAOrUnknown property is NO, the user is not located in the European Economic Area and consent is not required under the EU User Consent Policy. You can make ad requests to the Google Mobile Ads SDK.

If the requestLocationInEEAOrUnknown property is YES:

  • If the PACConsentStatus is PACConsentStatusPersonalized or PACConsentStatusNonPersonalized, the user has already provided consent. You can now forward consent to the Google Mobile Ads SDK.

  • If the user has an PACConsentStatusUnknown consent, see the Collect consent section below, which describes the use of utility methods to collect consent.

Google's Consent SDK provides two ways to collect consent from a user:

Remember to provide users with the option to Change or revoke consent.

The Google-rendered consent form is a full-screen configurable form that displays over your app content. You can configure the form to present the user with combinations of the following options:

  • Consent to view personalized ads
  • Consent to view non-personalized ads
  • Use a paid version of the app instead of viewing ads

You should review the consent text carefully: what appears by default is a message that might be appropriate if you use Google to monetize your app; but we cannot provide legal advice on the consent text that is appropriate for you. To update consent text of the Google-rendered consent form, modify the consentform.html file included in the Consent SDK as required.

The Google rendered consent form is configured and displayed using the PACConsentForm class. The following code demonstrates how to build a PACConsentForm with all three form options:

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;

The properties of PACConsentForm are described in further detail below:

shouldOfferPersonalizedAds
Indicates whether the consent form should show a personalized ad option. Defaults to YES.
shouldOfferNonPersonalizedAds
Indicates whether the consent form should show a non-personalized ad option. Defaults to YES.
shouldOfferAdFree
Indicates whether the consent form should show an ad-free app option. Defaults to NO.

Once you have created and configured a PACConsentForm object, load the consent form by invoking the loadWithCompletionHandler: method of PACConsentForm, as shown below:

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.
  }
}];

To present the user with the Google-rendered consent form, call presentFromViewController:dismissCompletion: on a loaded PACConsentForm, as demonstrated below:

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;
       }
     }];

The call to presentFromViewController:dismissCompletion: requires two arguments:

  • A UIViewController to present from.

  • A block that accepts an NSError and a BOOL as input parameters. The NSError provides information if there was an error showing the consent form. The userPrefersAdFree BOOL has a value of YES when the user chose to use a paid version of the app in lieu of viewing ads.

After the user selects an option and closes the form, the Consent SDK saves the user's choice and calls the dismissCompletion: block. You can read the user's choice and forward consent to the Google Mobile Ads SDK.

If you choose to get consent yourself, you can use the adProviders property of the PACConsentInformation class to get the ad technology providers associated with the publisher IDs used in your app. Note that consent is required for the full list of ad technology providers configured for your publisher IDs.

Swift

let adProviders = PACConsentInformation.sharedInstance.adProviders

Objective-C

NSArray *adProviders = PACConsentInformation.sharedInstance.adProviders;

You can then use the list of ad providers to obtain consent yourself.

Upon getting consent, record the PACConsentStatus corresponding to the user's response using the status property of the PACConsentInformation class.

Swift

PACConsentInformation.sharedInstance.consentStatus = .personalized

Objective-C

PACConsentInformation.sharedInstance.consentStatus = PACConsentStatusPersonalized;

After reporting consent to the Consent SDK, you can forward consent to the Google Mobile Ads SDK.

It is important that the user is able to change or revoke the consent they have provided at any time. To allow users to update their consent, simply repeat the steps outlined in the Collect consent section when the user chooses to update their consent status.

If a publisher is aware that the user is under the age of consent, all ad requests must set TFUA (Tag For Users under the Age of Consent in Europe). To include this tag on all ad requests made from your app, set the tagForUnderAgeOfConsent property to YES. This setting takes effect for all future ad requests.

Swift

PACConsentInformation.sharedInstance.isTaggedForUnderAgeOfConsent = true

Objective-C

PACConsentInformation.sharedInstance.tagForUnderAgeOfConsent = YES;

Once the TFUA setting is enabled, the Google rendered consent form will fail to load. All ad requests that include TFUA will be made ineligible for personalized advertising and remarketing. TFUA disables requests to third-party ad technology providers, such as ad measurement pixels and third-party ad servers.

To remove TFUA from ad requests, set the tagForUnderAgeOfConsent property to NO.

Testing

The Consent SDK has different behaviors depending on the value of PACConsentInformation.sharedInstance.requestLocationInEEAOrUnknown.

To enable easier testing of your app both inside and outside the EEA, the Consent SDK supports debug options that you can set prior to calling any other methods in the Consent SDK.

  1. Grab your device's advertising ID. You can write the following code to log your advertising ID:

    #import <AdSupport/AdSupport.h>
    // ...

    NSLog(@"Advertising ID: %@", ASIdentifierManager.sharedManager.advertisingIdentifier.UUIDString);

    And then check the console to get it:

    Advertising ID: 41E538F6-9C98-4EF2-B3EE-D7BD8CAF8339
    

  2. Whitelist your device to be a debug device using the advertising ID from the console:

    PACConsentInformation.sharedInstance.debugIdentifiers =
        @[ @"41E538F6-9C98-4EF2-B3EE-D7BD8CAF8339" ];
    

  3. Finally, set the debugGeography to your preferred geography for testing purposes.

    // 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;
    

After completing these steps, calls to update consent status will take into account your debug geography.

The default behavior of the Google Mobile Ads SDK is to serve personalized ads. If a user has consented to receive only non-personalized ads, you can configure an GADRequest object with the following code to specify that only non-personalized ads should be returned:

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];

Send feedback about...

Google Mobile Ads SDK for iOS
Google Mobile Ads SDK for iOS
Need help? Visit our support page.