GDPR IAB support

This guide outlines the steps required to support the GDPR IAB TCF v2 message as part of the UMP SDK. It is intended to be paired with Get started which gives an overview of how to get your app running with the UMP SDK and the basics of setting up your message. The guidance below is specific to the GDPR IAB TCF v2 message.

Prerequisites

Delay app measurement

By default, the Google Mobile Ads SDK initializes app measurement and begins sending user-level event data to Google immediately when the app starts. This initialization behavior ensures that you can enable AdMob user metrics without making additional code changes.

However, if your app requires user consent before these events can be sent, you can delay app measurement until you explicitly initialize the Mobile Ads SDK or load an ad.

To delay app measurement, add the GADDelayAppMeasurementInit key with a boolean value of YES to your app's Info.plist. You can make this change programmatically:

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

Consent revocability is a requirement of the Privacy & messaging user consent program. You must provide a way to allow users who want to revoke consent to do so, then present the consent message to those users again.

To accomplish this:

  1. Implement a UI element, such as a button in your app's settings page, that can trigger a new consent form.
  2. After you've called requestConsentInfoUpdateWithParameters:completionHandler:, check UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus to determine whether to display the UI element that can re-present the consent form.
  3. When a user interacts with your UI element, call presentPrivacyOptionsFormFromViewController:completionHandler: to show the form so the user can update their consent status at any time.

The following example shows how to present the privacy options form from a UIBarButtonItem.

Swift

// Show a privacy options button if required.
var isPrivacySettingsButtonEnabled: Bool {
  return UMPConsentInformation.shared.privacyOptionsRequirementStatus == .required
}

// Present the privacy options form when a user interacts with your
// 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

// Show a privacy options button if required.
- (BOOL)isPrivacySettingsButtonEnabled {
  return UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus ==
         UMPPrivacyOptionsRequirementStatusRequired;
}

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

See our banner examples on GitHub:

Mediation

Follow the steps in Add ad partners to published GDPR messages to add your mediation partners to the ad partners list. Failure to do so can lead to partners failing to serve ads on your app.

Mediation partners might also have additional tools to help with GDPR compliance. See a specific partner's integration guide for more details.

After GDPR consent has been collected, you can read consent choices from UserDefaults following the TCF v2 spec. The IABTCF_PurposeConsents key indicates consent for each of the TCF purposes.

The code snippet below shows how to check consent for Purpose 1:

Swift

// Example value: "1111111111"
let purposeConsents = UserDefaults.standard.string(forKey: "IABTCF_PurposeConsents")
// Purposes are zero-indexed. Index 0 contains information about Purpose 1.
let hasConsentForPurposeOne = purposeConsents?.first == "1"

Objective-C

// Example value: "1111111111"
NSString *purposeConsents = [NSUserDefaults.standardUserDefaults
                             stringForKey:@"IABTCF_PurposeConsents"];
// Purposes are zero-indexed. Index 0 contains information about Purpose 1.
BOOL hasConsentForPurposeOne = [purposeConsents hasPrefix:@"1"];

Troubleshooting

Error 3.3: The TC string last updated date was more than 13 months ago

Consent must be reobtained from the user. You should call requestConsentInfoUpdateWithParameters:completionHandler: at the start of every app session. If the TC string is expired, the UMP SDK indicates that consent must be reobtained by setting UMPConsentInformation.consentStatus to UMPConsentStatus.required. If you haven't already, implement a request to load and present a new UMP form in your app.

It's possible for the TC string to expire mid-session, resulting in a small amount of 3.3 errors. And if on the next app session you start loading ads at the same time as you check requestConsentInfoUpdateWithParameters:completionHandler:, those requests could also give 3.3 errors until requestConsentInfoUpdateWithParameters:completionHandler: completes; however, this should be a tiny fraction of overall 3.3 errors (less than 0.1%). that are expected.