The Google User Messaging Platform (UMP) SDK is a privacy and messaging tool to help you manage privacy choices. For more information, see About Privacy & messaging. You can see a working IMA implementation with the UMP SDK in either the Objective-C or Swift UMP sample apps.
Create a message type
Create user messages with one of the Available user message types under the Privacy & messaging tab of your Ad Manager account. The UMP SDK attempts to display a privacy message created from the Interactive Media Ads Application ID set in your project.
For more details, see About privacy and messaging.
Import the SDK
The UMP SDK is not included as a dependency of the IMA SDK, so you must explicitly add it yourself.
CocoaPods (preferred)
The easiest way to import the SDK into an iOS project is to use CocoaPods. Open your project's Podfile and add this line to your app's target:
pod 'GoogleUserMessagingPlatform'
Then, run the following command:
pod install --repo-update
If you're new to CocoaPods, see Using CocoaPods for details on how to create and use Podfiles.
Swift Package Manager
The UMP SDK also supports the Swift Package Manager. Follow these steps to import the Swift package.
In Xcode, install the UMP SDK Swift Package by navigating to File > Add Packages....
In the prompt that appears, search for the UMP SDK Swift Package GitHub repository:
https://github.com/googleads/swift-package-manager-google-user-messaging-platform.git
Select the version of the UMP SDK Swift Package you want to use. For new projects, we recommend using the Up to Next Major Version.
Xcode then resolves your package dependencies and downloads them in the background. For more details on how to add package dependencies, see Apple's article.
Add the application ID
You can find your application ID in the
Ad Manager UI.
Add the ID to your
Info.plist
with the following code snippet:
<key>UMPApplicationIdentifier</key>
<string>ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy</string>
Gather consent
To gather consent, complete the following steps:
- Request for the most recent user consent information.
- Load and present a consent form, if required.
Request for consent information
You should request an update of the user's consent information at every app
launch, using
requestConsentInfoUpdateWithParameters:completionHandler:
. This request checks
the following:
- Whether consent is required. For example, consent is required for the first time, or the previous consent decision expired.
- Whether a privacy options entry point is required. Some privacy messages require apps to allow users to modify their privacy options at any time.
Load and present a privacy message form if required
After you have received the most up-to-date consent status, call
loadAndPresentIfRequiredFromViewController:completionHandler:
to load any forms required to
collect user consent. After loading, the forms present immediately.
The following code demonstrates how to request the user's latest consent information. If required, the code loads and presents a privacy message form:
Swift
// Requesting an update to consent information should be called on every app launch.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) {
requestConsentError in
guard requestConsentError == nil else {
return consentGatheringComplete(requestConsentError)
}
UMPConsentForm.loadAndPresentIfRequired(from: consentFormPresentationviewController) {
loadAndPresentError in
// Consent has been gathered.
consentGatheringComplete(loadAndPresentError)
}
}
Objective-C
// Requesting an update to consent information should be called on every app launch.
[UMPConsentInformation.sharedInstance
requestConsentInfoUpdateWithParameters:parameters
completionHandler:^(NSError *_Nullable requestConsentError) {
if (requestConsentError) {
consentGatheringComplete(requestConsentError);
} else {
[UMPConsentForm
loadAndPresentIfRequiredFromViewController:viewController
completionHandler:^(
NSError
*_Nullable loadAndPresentError) {
// Consent has been gathered.
consentGatheringComplete(
loadAndPresentError);
}];
}
}];
Privacy options
Some privacy message forms are presented from a publisher-rendered privacy options entry point, letting users manage their privacy options at any time. To learn more about which message your users see at the privacy options entry point, see Available user message types.
Check if a privacy options entry point is required
After you have called
requestConsentInfoUpdateWithParameters:completionHandler:
, check
UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus
to
determine if a privacy options entry point is required for your app:
Swift
var isPrivacyOptionsRequired: Bool {
return UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus == .required
}
Objective-C
- (BOOL)areGDPRConsentMessagesRequired {
return UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus ==
UMPPrivacyOptionsRequirementStatusRequired;
}
Add a visible element to your app
If a privacy entry point is required, add a visible and interactable UI element to your app that presents the privacy options form. If a privacy entry point is not required, configure your UI element to be not visible and interactable.
Swift
self.privacySettingsButton.isEnabled = ConsentManager.shared.isPrivacyOptionsRequired
Objective-C
// Set up the privacy options button to show the UMP privacy form.
// Check ConsentInformation.getPrivacyOptionsRequirementStatus
// to see the button should be shown or hidden.
strongSelf.privacySettingsButton.hidden =
!ConsentManager.sharedInstance.areGDPRConsentMessagesRequired;
Present the privacy options form
When the user interacts with your element, present the privacy options form:
Swift
UMPConsentForm.presentPrivacyOptionsForm(
from: viewController, completionHandler: completionHandler)
Objective-C
[UMPConsentForm presentPrivacyOptionsFormFromViewController:viewController
completionHandler:completionHandler];
Request ads
Before requesting ads in your app, check if you have obtained consent
from the user using
UMPConsentInformation.sharedInstance.canRequestAds
. There are two
places to check while gathering consent:
- After consent has been gathered in the current session.
- Immediately after you have called
requestConsentInfoUpdateWithParameters:completionHandler:
. It is possible consent has been obtained in the previous session. As a latency best practice, we recommend not waiting for the callback to complete so you can start loading ads as soon as possible after your app launches.
If an error occurs during the consent gathering process, you should still check if you can request ads. The UMP SDK uses the consent status from the previous session.
The following code checks if you can request ads during the consent gathering process:
Swift
ConsentManager.shared.gatherConsent(from: self) { [weak self] consentError in
guard let self else { return }
if let consentError {
// Consent gathering failed. This sample loads ads using
// consent obtained in the previous session.
print("Error: \(consentError.localizedDescription)")
}
// ...
}
Objective-C
[ConsentManager.sharedInstance
gatherConsentFromConsentPresentationViewController:self
consentGatheringComplete:^(NSError *_Nullable consentError) {
if (consentError) {
// Consent gathering failed.
NSLog(@"Error: %@", consentError.localizedDescription);
}
__strong __typeof__(self) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
// ...
if (ConsentManager.sharedInstance.canRequestAds) {
[strongSelf setupAdsLoader];
}
}];
// This sample attempts to load ads using consent obtained in the previous session.
if (ConsentManager.sharedInstance.canRequestAds) {
[self setupAdsLoader];
}
[self setUpContentPlayer];
}
- (IBAction)onPlayButtonTouch:(id)sender {
[self requestAds];
self.playButton.hidden = YES;
}
#pragma mark Content Player Setup
- (void)setUpContentPlayer {
// Load AVPlayer with path to our content.
NSURL *contentURL = [NSURL URLWithString:kTestAppContentUrl_MP4];
self.contentPlayer = [AVPlayer playerWithURL:contentURL];
// Create a player layer for the player.
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.contentPlayer];
// Size, position, and display the AVPlayer.
playerLayer.frame = self.videoView.layer.bounds;
[self.videoView.layer addSublayer:playerLayer];
// Set up our content playhead and contentComplete callback.
self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentDidFinishPlaying:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.contentPlayer.currentItem];
}
#pragma mark SDK Setup
- (void)setupAdsLoader {
self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
self.adsLoader.delegate = self;
}
- (void)requestAds {
// Create an ad display container for ad rendering.
IMAAdDisplayContainer *adDisplayContainer =
[[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
viewController:self
companionSlots:nil];
// Create an ad request with our ad tag, display container, and optional user context.
IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kTestAppAdTagUrl
adDisplayContainer:adDisplayContainer
contentPlayhead:self.contentPlayhead
userContext:nil];
[self.adsLoader requestAdsWithRequest:request];
}
- (void)contentDidFinishPlaying:(NSNotification *)notification {
// Make sure we don't call contentComplete as a result of an ad completing.
if (notification.object == self.contentPlayer.currentItem) {
[self.adsLoader contentComplete];
}
}
#pragma mark AdsLoader Delegates
- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
// Grab the instance of the IMAAdsManager and set ourselves as the delegate.
self.adsManager = adsLoadedData.adsManager;
self.adsManager.delegate = self;
// Create ads rendering settings to tell the SDK to use the in-app browser.
IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init];
adsRenderingSettings.linkOpenerPresentingController = self;
// Initialize the ads manager.
[self.adsManager initializeWithAdsRenderingSettings:adsRenderingSettings];
}
- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
// Something went wrong loading ads. Log the error and play the content.
NSLog(@"Error loading ads: %@", adErrorData.adError.message);
[self.contentPlayer play];
}
#pragma mark AdsManager Delegates
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
// When the SDK notified us that ads have been loaded, play them.
if (event.type == kIMAAdEvent_LOADED) {
[adsManager start];
}
}
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
// Something went wrong with the ads manager after ads were loaded. Log the error and play the
// content.
NSLog(@"AdsManager error: %@", error.message);
[self.contentPlayer play];
}
- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
// The SDK is going to play ads, so pause the content.
[self.contentPlayer pause];
}
- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
// The SDK is done playing ads (at least for now), so resume the content.
[self.contentPlayer play];
}
@end
The following code sets up the IMA DAI SDK after the user's consent is gathered:
Swift
private func requestAds() {
// Create ad display container for ad rendering.
let adDisplayContainer = IMAAdDisplayContainer(
adContainer: videoView, viewController: self, companionSlots: nil)
// Create an ad request with our ad tag, display container, and optional user context.
let request = IMAAdsRequest(
adTagUrl: ViewController.testAppAdTagURL,
adDisplayContainer: adDisplayContainer,
contentPlayhead: contentPlayhead,
userContext: nil)
adsLoader.requestAds(with: request)
}
Objective-C
- (void)setupAdsLoader {
self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
self.adsLoader.delegate = self;
}
Testing
If you want to test the integration in your app as you're developing, follow these steps to programmatically register your test device. Be sure to remove the code that sets these test device IDs before you release your app.
- Call
requestConsentInfoUpdateWithParameters:completionHandler:
. Check the log output for a message similar to the following example, which shows your device ID and how to add it as a test device:
<UMP SDK>To enable debug mode for this device, set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
Copy your test device ID to your clipboard.
Modify your code to call
UMPDebugSettings().testDeviceIdentifiers
and pass in a list of your test device IDs.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){ // ... }];
Force a geography
The UMP SDK provides a way to test your app's behavior as though the device
were located in various regions, such as the EEA or UK, using
UMPDebugGeography
. Note that debug settings only work on test devices.
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){
// ...
}];
Reset consent state
When testing your app with the UMP SDK, you might find it helpful to reset the
state of the SDK so that you can simulate a user's first install experience.
The SDK provides the reset
method to do this.
Swift
UMPConsentInformation.sharedInstance.reset()
Objective-C
[UMPConsentInformation.sharedInstance reset];
Examples on GitHub
See a full example of the UMP SDK integration covered in this page in Swift UmpExample and Objective-C UmpExample.