From 4a881d16792c11737c315cda1fed304f9e817359 Mon Sep 17 00:00:00 2001 From: Justin Malandruccolo Date: Wed, 2 Aug 2023 08:05:27 -0700 Subject: [PATCH] Updated AdMob Banner samples to use new UMP SDK APIs PiperOrigin-RevId: 553147531 --- .../GoogleMobileAdsConsentManager.h | 12 +- .../GoogleMobileAdsConsentManager.m | 111 +++--------------- .../BannerExample/ViewController.m | 12 +- Objective-C/admob/BannerExample/Podfile.lock | 24 ++-- .../BannerExample/AppDelegate.swift | 4 +- .../GoogleMobileAdsConsentManager.swift | 101 ++-------------- .../BannerExample/ViewController.swift | 7 +- Swift/admob/BannerExample/Podfile.lock | 24 ++-- 8 files changed, 65 insertions(+), 230 deletions(-) diff --git a/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.h b/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.h index 2a741238..13d531b8 100644 --- a/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.h +++ b/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2014 Google LLC +// Copyright (C) 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,23 +26,15 @@ NS_ASSUME_NONNULL_BEGIN @property(class, atomic, readonly, strong, nonnull) GoogleMobileAdsConsentManager *sharedInstance; @property(nonatomic, readonly) BOOL canRequestAds; -@property(nonatomic, readonly) BOOL isFormAvailable; +@property(nonatomic, readonly) BOOL isPrivacyOptionsRequired; /// Helper method to call the UMP SDK methods to request consent information and load/present a /// consent form if necessary. -/// -/// @param viewController The view controller to present the user consent form on screen. -/// @param completionHandler The block to execute after consent gathering finishes. - (void)gatherConsentFromConsentPresentationViewController:(UIViewController *)viewController consentGatheringComplete: (void (^)(NSError *_Nullable error))completionHandler; /// Helper method to call the UMP SDK method to present the privacy options form. -/// -/// Attempts to load a new privacy options form upon completion. -/// -/// @param viewController The view controller to present the privacy options form on screen. -/// @param completionHandler The block to execute after the presentation finishes. - (void)presentPrivacyOptionsFormFromViewController:(UIViewController *)viewController completionHandler: (void (^)(NSError *_Nullable error))completionHandler; diff --git a/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.m b/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.m index 39c713dd..077988ca 100644 --- a/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.m +++ b/Objective-C/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.m @@ -1,5 +1,5 @@ // -// Copyright (C) 2014 Google LLC +// Copyright (C) 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,12 +19,6 @@ #import #import -@interface GoogleMobileAdsConsentManager () - -/// The UMP SDK consent form. -@property(nonatomic, strong) UMPConsentForm *form; - -@end @implementation GoogleMobileAdsConsentManager @@ -38,12 +32,12 @@ + (instancetype)sharedInstance { } - (BOOL)canRequestAds { - return UMPConsentInformation.sharedInstance.consentStatus == UMPConsentStatusNotRequired || - UMPConsentInformation.sharedInstance.consentStatus == UMPConsentStatusObtained; + return UMPConsentInformation.sharedInstance.canRequestAds; } -- (BOOL)isFormAvailable { - return UMPConsentInformation.sharedInstance.formStatus == UMPFormStatusAvailable; +- (BOOL)isPrivacyOptionsRequired { + return UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus == + UMPPrivacyOptionsRequirementStatusRequired; } - (void)gatherConsentFromConsentPresentationViewController:(UIViewController *)viewController @@ -56,7 +50,6 @@ - (void)gatherConsentFromConsentPresentationViewController:(UIViewController *)v // debugSettings.geography = UMPDebugGeographyEEA; parameters.debugSettings = debugSettings; - __weak __typeof__(self) weakSelf = self; // Requesting an update to consent information should be called on every app launch. [UMPConsentInformation.sharedInstance requestConsentInfoUpdateWithParameters:parameters @@ -64,96 +57,24 @@ - (void)gatherConsentFromConsentPresentationViewController:(UIViewController *)v if (requestConsentError) { consentGatheringComplete(requestConsentError); } else { - [weakSelf handleRequestConsentInfoFromViewController:viewController - completionHandler: - consentGatheringComplete]; + [UMPConsentForm + loadAndPresentIfRequiredFromViewController:viewController + completionHandler:^( + NSError + *_Nullable loadAndPresentError) { + // Consent has been gathered. + consentGatheringComplete( + loadAndPresentError); + }]; } }]; } -- (void)handleRequestConsentInfoFromViewController:(UIViewController *_Nonnull)viewController - completionHandler: - (void (^_Nonnull)(NSError *_Nullable))completionHandler { - __weak __typeof__(self) weakSelf = self; - [self loadAndPresentFormFromViewControllerIfRequired:viewController - completionHandler:^(NSError *_Nullable loadAndPresentError) { - // Consent has been gathered. - completionHandler(loadAndPresentError); - // Your app needs to allow the user to change their consent - // status at any time. Load another form and store it so - // it's ready to be displayed immediately after the user - // clicks your app's privacy settings button. - [weakSelf loadPrivacyOptionsFormIfRequired]; - }]; -} - -- (void)loadAndPresentFormFromViewControllerIfRequired:(UIViewController *)viewController - completionHandler: - (void (^)(NSError *_Nullable))completionHandler { - // Determine the consent-related action to take based on the UMPConsentStatus. - if (UMPConsentInformation.sharedInstance.consentStatus == UMPConsentStatusNotRequired || - UMPConsentInformation.sharedInstance.consentStatus == UMPConsentStatusObtained) { - // Consent has already been gathered or not required. - completionHandler(nil); - return; - } - - [UMPConsentForm loadWithCompletionHandler:^(UMPConsentForm *_Nullable consentForm, - NSError *_Nullable loadError) { - if (loadError) { - completionHandler(loadError); - } else { - [consentForm presentFromViewController:viewController - completionHandler:^(NSError *_Nullable formError) { - completionHandler(formError); - }]; - } - }]; -} - -- (void)loadPrivacyOptionsFormIfRequired { - // No privacy options form needed if consent form is not available. - if (!self.isFormAvailable) { - return; - } - - __weak __typeof__(self) weakSelf = self; - [UMPConsentForm loadWithCompletionHandler:^(UMPConsentForm *_Nullable consentForm, - NSError *_Nullable loadError) { - if (loadError) { - // See UMPFormErrorCode for more info. - return NSLog(@"Error: %@", [loadError localizedDescription]); - } else { - weakSelf.form = consentForm; - } - }]; -} - - (void)presentPrivacyOptionsFormFromViewController:(UIViewController *)viewController completionHandler: (void (^)(NSError *_Nullable))completionHandler { - if (!self.form) { - completionHandler([NSError - errorWithDomain:@"com.google" - code:0 - userInfo:@{NSLocalizedDescriptionKey : @"No form available."}]); - - // Your app needs to allow the user to change their consent status at any - // time. Load another form and store it so it's ready to be displayed - // immediately after the user clicks your app's privacy settings button. - [self loadPrivacyOptionsFormIfRequired]; - return; - } - - [self.form presentFromViewController:viewController - completionHandler:^(NSError *_Nullable formError) { - completionHandler(formError); - - // Your app needs to allow the user to change their consent status at any - // time. Load another form and store it so it's ready to be displayed - // immediately after the user clicks your app's privacy settings button. - [self loadPrivacyOptionsFormIfRequired]; - }]; + [UMPConsentForm presentPrivacyOptionsFormFromViewController:viewController + completionHandler:completionHandler]; } @end diff --git a/Objective-C/admob/BannerExample/BannerExample/ViewController.m b/Objective-C/admob/BannerExample/BannerExample/ViewController.m index 0a6786b7..847f00f6 100644 --- a/Objective-C/admob/BannerExample/BannerExample/ViewController.m +++ b/Objective-C/admob/BannerExample/BannerExample/ViewController.m @@ -65,8 +65,7 @@ - (void)viewDidLoad { gatherConsentFromConsentPresentationViewController:self consentGatheringComplete:^(NSError *_Nullable consentError) { if (consentError) { - // Consent gathering failed. This sample loads - // ads using consent obtained in the previous session. + // Consent gathering failed. NSLog(@"Error: %@", consentError.localizedDescription); } @@ -76,20 +75,21 @@ - (void)viewDidLoad { } if (GoogleMobileAdsConsentManager.sharedInstance.canRequestAds) { - [strongSelf startGoogleMobileAdsSDKOnce]; + [strongSelf startGoogleMobileAdsSDK]; } [strongSelf.privacySettingsButton setEnabled:GoogleMobileAdsConsentManager.sharedInstance - .isFormAvailable]; + .isPrivacyOptionsRequired]; }]; + // This sample attempts to load ads using consent obtained in the previous session. if (GoogleMobileAdsConsentManager.sharedInstance.canRequestAds) { - [self startGoogleMobileAdsSDKOnce]; + [self startGoogleMobileAdsSDK]; } } -- (void)startGoogleMobileAdsSDKOnce { +- (void)startGoogleMobileAdsSDK { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // Initialize the Google Mobile Ads SDK. diff --git a/Objective-C/admob/BannerExample/Podfile.lock b/Objective-C/admob/BannerExample/Podfile.lock index 894dcc0f..6b4d9ddc 100644 --- a/Objective-C/admob/BannerExample/Podfile.lock +++ b/Objective-C/admob/BannerExample/Podfile.lock @@ -22,30 +22,30 @@ PODS: - GoogleUtilities/Network (~> 7.11) - "GoogleUtilities/NSData+zlib (~> 7.11)" - nanopb (< 2.30910.0, >= 2.30908.0) - - GoogleUserMessagingPlatform (2.0.1) - - GoogleUtilities/AppDelegateSwizzler (7.11.1): + - GoogleUserMessagingPlatform (2.1.0) + - GoogleUtilities/AppDelegateSwizzler (7.11.4): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (7.11.1): + - GoogleUtilities/Environment (7.11.4): - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/Logger (7.11.1): + - GoogleUtilities/Logger (7.11.4): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (7.11.1): + - GoogleUtilities/MethodSwizzler (7.11.4): - GoogleUtilities/Logger - - GoogleUtilities/Network (7.11.1): + - GoogleUtilities/Network (7.11.4): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (7.11.1)" - - GoogleUtilities/Reachability (7.11.1): + - "GoogleUtilities/NSData+zlib (7.11.4)" + - GoogleUtilities/Reachability (7.11.4): - GoogleUtilities/Logger - nanopb (2.30909.0): - nanopb/decode (= 2.30909.0) - nanopb/encode (= 2.30909.0) - nanopb/decode (2.30909.0) - nanopb/encode (2.30909.0) - - PromisesObjC (2.2.0) + - PromisesObjC (2.3.1) DEPENDENCIES: - Google-Mobile-Ads-SDK @@ -62,10 +62,10 @@ SPEC REPOS: SPEC CHECKSUMS: Google-Mobile-Ads-SDK: 69daa7fb42061b425340706e382e87fab3e666a3 GoogleAppMeasurement: 2d800fab85e7848b1e66a6f8ce5bca06c5aad892 - GoogleUserMessagingPlatform: 5f8b30daf181805317b6b985bb51c1ff3beca054 - GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749 + GoogleUserMessagingPlatform: dce302b8f1b84d6e945812ee7a15c3f65a102cbf + GoogleUtilities: c63691989bf362ba0505507da00eeb326192e83e nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 - PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef + PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 PODFILE CHECKSUM: 1a20a497bcb7223f0fd3886913b5dce10e17dcb5 diff --git a/Swift/admob/BannerExample/BannerExample/AppDelegate.swift b/Swift/admob/BannerExample/BannerExample/AppDelegate.swift index 95036600..76d74e61 100644 --- a/Swift/admob/BannerExample/BannerExample/AppDelegate.swift +++ b/Swift/admob/BannerExample/BannerExample/AppDelegate.swift @@ -27,7 +27,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - print("Google Mobile Ads SDK version: \(GADMobileAds.sharedInstance().sdkVersion)") + print( + "Google Mobile Ads SDK version: \(GADGetStringFromVersionNumber(GADMobileAds.sharedInstance().versionNumber))" + ) return true } diff --git a/Swift/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.swift b/Swift/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.swift index 22fcfbd6..3ff8782d 100644 --- a/Swift/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.swift +++ b/Swift/admob/BannerExample/BannerExample/GoogleMobileAdsConsentManager.swift @@ -1,5 +1,5 @@ // -// Copyright (C) 2015 Google LLC +// Copyright (C) 2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,23 +26,16 @@ import UserMessagingPlatform class GoogleMobileAdsConsentManager: NSObject { static let shared = GoogleMobileAdsConsentManager() - // The UMP SDK consent form. - private var form: UMPConsentForm? - var canRequestAds: Bool { - return UMPConsentInformation.sharedInstance.consentStatus == .notRequired - || UMPConsentInformation.sharedInstance.consentStatus == .obtained + return UMPConsentInformation.sharedInstance.canRequestAds } - var isFormAvailable: Bool { - return UMPConsentInformation.sharedInstance.formStatus == .available + var isPrivacyOptionsRequired: Bool { + return UMPConsentInformation.sharedInstance.privacyOptionsRequirementStatus == .required } /// Helper method to call the UMP SDK methods to request consent information and load/present a /// consent form if necessary. - /// - /// - Parameter viewController: The view controller to present the user consent form on screen. - /// - Parameter completionHandler: The block to execute after consent gathering finishes. func gatherConsent( from consentFormPresentationviewController: UIViewController, consentGatheringComplete: @escaping (Error?) -> Void @@ -51,104 +44,30 @@ class GoogleMobileAdsConsentManager: NSObject { //For testing purposes, you can force a UMPDebugGeography of EEA or not EEA. let debugSettings = UMPDebugSettings() - //debugSettings.geography = UMPDebugGeography.EEA + // debugSettings.geography = UMPDebugGeography.EEA parameters.debugSettings = debugSettings // Requesting an update to consent information should be called on every app launch. UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) { - [weak self] requestConsentError in - guard let self else { return } + requestConsentError in guard requestConsentError == nil else { return consentGatheringComplete(requestConsentError) } - self.loadAndPresentFormFromViewControllerIfRequired( - from: consentFormPresentationviewController - ) { - [weak self] loadAndPresentError in - guard let self else { return } + UMPConsentForm.loadAndPresentIfRequired(from: consentFormPresentationviewController) { + loadAndPresentError in // Consent has been gathered. consentGatheringComplete(loadAndPresentError) - - // Your app needs to allow the user to change their consent status at any time. Load - // another form and store it so it's ready to be displayed immediately after the user - // clicks your app's privacy settings button. - self.loadPrivacyOptionsFormIfRequired() } } } - private func loadAndPresentFormFromViewControllerIfRequired( - from viewController: UIViewController, completionHandler: @escaping (Error?) -> Void - ) { - // Determine the consent-related action to take based on the UMPConsentStatus. - guard - UMPConsentInformation.sharedInstance.consentStatus == .required - || UMPConsentInformation.sharedInstance.consentStatus == .unknown - else { - // Consent has already been gathered or not required. - return completionHandler(nil) - } - - UMPConsentForm.load { form, loadError in - guard loadError == nil else { - return completionHandler(loadError) - } - - form?.present( - from: viewController, - completionHandler: { formError in - completionHandler(formError) - }) - } - } - - private func loadPrivacyOptionsFormIfRequired() { - // No privacy options form needed if consent form is not available. - guard isFormAvailable else { return } - - UMPConsentForm.load { [weak self] form, loadError in - guard let self else { return } - guard loadError == nil else { - // See UMPFormErrorCode for more info. - return print("Error: \(loadError!.localizedDescription)") - } - - self.form = form - } - } - /// Helper method to call the UMP SDK method to present the privacy options form. - /// - /// Attempts to load a new privacy options form upon completion. - /// - /// - Parameter viewController: The view controller to present the privacy options form on screen. - /// - Parameter completionHandler: The block to execute after the presentation finishes. func presentPrivacyOptionsForm( from viewController: UIViewController, completionHandler: @escaping (Error?) -> Void ) { - defer { - // Your app needs to allow the user to change their consent status at any time. Load - // another form and store it so it's ready to be displayed immediately after the user - // clicks your app's privacy settings button. - loadPrivacyOptionsFormIfRequired() - } - - guard let form = form else { - return completionHandler( - NSError( - domain: "@com.google", - code: 0, - userInfo: [NSLocalizedDescriptionKey: "No form available."] - ) - ) - } - - form.present( - from: viewController, - completionHandler: { formError in - completionHandler(formError) - }) + UMPConsentForm.presentPrivacyOptionsForm( + from: viewController, completionHandler: completionHandler) } } diff --git a/Swift/admob/BannerExample/BannerExample/ViewController.swift b/Swift/admob/BannerExample/BannerExample/ViewController.swift index bc1c59d1..b26564db 100644 --- a/Swift/admob/BannerExample/BannerExample/ViewController.swift +++ b/Swift/admob/BannerExample/BannerExample/ViewController.swift @@ -46,8 +46,7 @@ class ViewController: UIViewController, GADBannerViewDelegate { guard let self else { return } if let consentError { - // Consent gathering failed. This sample loads ads using - // consent obtained in the previous session. + // Consent gathering failed. print("Error: \(consentError.localizedDescription)") } @@ -55,9 +54,11 @@ class ViewController: UIViewController, GADBannerViewDelegate { _ = self.startGoogleMobileAdsSDK } - self.privacySettingsButton.isEnabled = GoogleMobileAdsConsentManager.shared.isFormAvailable + self.privacySettingsButton.isEnabled = + GoogleMobileAdsConsentManager.shared.isPrivacyOptionsRequired } + // This sample attempts to load ads using consent obtained in the previous session. if GoogleMobileAdsConsentManager.shared.canRequestAds { _ = startGoogleMobileAdsSDK } diff --git a/Swift/admob/BannerExample/Podfile.lock b/Swift/admob/BannerExample/Podfile.lock index 8dc6f60b..342bddd9 100644 --- a/Swift/admob/BannerExample/Podfile.lock +++ b/Swift/admob/BannerExample/Podfile.lock @@ -22,30 +22,30 @@ PODS: - GoogleUtilities/Network (~> 7.11) - "GoogleUtilities/NSData+zlib (~> 7.11)" - nanopb (< 2.30910.0, >= 2.30908.0) - - GoogleUserMessagingPlatform (2.0.1) - - GoogleUtilities/AppDelegateSwizzler (7.11.1): + - GoogleUserMessagingPlatform (2.1.0) + - GoogleUtilities/AppDelegateSwizzler (7.11.4): - GoogleUtilities/Environment - GoogleUtilities/Logger - GoogleUtilities/Network - - GoogleUtilities/Environment (7.11.1): + - GoogleUtilities/Environment (7.11.4): - PromisesObjC (< 3.0, >= 1.2) - - GoogleUtilities/Logger (7.11.1): + - GoogleUtilities/Logger (7.11.4): - GoogleUtilities/Environment - - GoogleUtilities/MethodSwizzler (7.11.1): + - GoogleUtilities/MethodSwizzler (7.11.4): - GoogleUtilities/Logger - - GoogleUtilities/Network (7.11.1): + - GoogleUtilities/Network (7.11.4): - GoogleUtilities/Logger - "GoogleUtilities/NSData+zlib" - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (7.11.1)" - - GoogleUtilities/Reachability (7.11.1): + - "GoogleUtilities/NSData+zlib (7.11.4)" + - GoogleUtilities/Reachability (7.11.4): - GoogleUtilities/Logger - nanopb (2.30909.0): - nanopb/decode (= 2.30909.0) - nanopb/encode (= 2.30909.0) - nanopb/decode (2.30909.0) - nanopb/encode (2.30909.0) - - PromisesObjC (2.2.0) + - PromisesObjC (2.3.1) DEPENDENCIES: - Google-Mobile-Ads-SDK @@ -62,10 +62,10 @@ SPEC REPOS: SPEC CHECKSUMS: Google-Mobile-Ads-SDK: 69daa7fb42061b425340706e382e87fab3e666a3 GoogleAppMeasurement: 2d800fab85e7848b1e66a6f8ce5bca06c5aad892 - GoogleUserMessagingPlatform: 5f8b30daf181805317b6b985bb51c1ff3beca054 - GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749 + GoogleUserMessagingPlatform: dce302b8f1b84d6e945812ee7a15c3f65a102cbf + GoogleUtilities: c63691989bf362ba0505507da00eeb326192e83e nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 - PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef + PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 PODFILE CHECKSUM: 5e2423953a9b30b3cd8df960c79b52ead14d227a