From e4d987e5bf4c76aa702e9caf2a4c8e5b7859f455 Mon Sep 17 00:00:00 2001 From: Ram Parameswaran Date: Thu, 24 May 2018 17:44:34 -0700 Subject: [PATCH] Version v1.0.1 of the Consent SDK. --- .../project.pbxproj | 17 +++----- .../PACPersonalizedAdConsent.h | 3 ++ .../PACPersonalizedAdConsent.m | 11 +++-- .../PersonalizedAdConsent/PACView.h | 1 + .../PersonalizedAdConsent/PACView.m | 43 +++++++++++++------ .../consentform.html | 33 +++++++++++--- 6 files changed, 75 insertions(+), 33 deletions(-) diff --git a/PersonalizedAdConsent/PersonalizedAdConsent.xcodeproj/project.pbxproj b/PersonalizedAdConsent/PersonalizedAdConsent.xcodeproj/project.pbxproj index c117efd..93309b7 100755 --- a/PersonalizedAdConsent/PersonalizedAdConsent.xcodeproj/project.pbxproj +++ b/PersonalizedAdConsent/PersonalizedAdConsent.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 48; objects = { /* Begin PBXBuildFile section */ @@ -142,11 +142,12 @@ TargetAttributes = { 5A92D29E2076961800FFE51D = { CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 5A92D2992076961800FFE51D /* Build configuration list for PBXProject "PersonalizedAdConsent" */; - compatibilityVersion = "Xcode 9.3"; + compatibilityVersion = "Xcode 8.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -316,11 +317,7 @@ INFOPLIST_FILE = PersonalizedAdConsent/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "$(SRCROOT)/PersonalizedAdConsent/module.modulemap"; PRODUCT_BUNDLE_IDENTIFIER = com.google.PersonalizedAdConsent; @@ -343,11 +340,7 @@ INFOPLIST_FILE = PersonalizedAdConsent/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "$(SRCROOT)/PersonalizedAdConsent/module.modulemap"; PRODUCT_BUNDLE_IDENTIFIER = com.google.PersonalizedAdConsent; diff --git a/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.h b/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.h index 2b60dcb..41a6fdd 100755 --- a/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.h +++ b/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.h @@ -16,6 +16,9 @@ #import +/// Personalized ad consent SDK version string. +extern NSString *_Nonnull const PACVersionString; + /// Personalized ad consent error domain. extern NSErrorDomain _Nonnull const PACErrorDomain; diff --git a/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.m b/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.m index 8d6e87f..4ed7f4b 100755 --- a/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.m +++ b/PersonalizedAdConsent/PersonalizedAdConsent/PACPersonalizedAdConsent.m @@ -29,10 +29,11 @@ @interface PACAdProvider () - (nullable instancetype)initWithDictionary:(nullable NSDictionary *)dictionary; @end +NSString *const PACVersionString = @"1.0.1"; NSString *const PACUserDefaultsRootKey = @"personalized_ad_status"; static NSString *const PACInfoUpdateURLFormat = - @"https://adservice.google.com/getconfig/pubvendors?es=2&pubs=%@"; + @"https://adservice.google.com/getconfig/pubvendors?es=2&plat=ios&v=%@&pubs=%@"; typedef NSString *PACStoreKey NS_STRING_ENUM; static PACStoreKey const PACStoreKeyTaggedForUnderAgeOfConsent = @"tag_for_under_age_of_consent"; @@ -44,6 +45,8 @@ - (nullable instancetype)initWithDictionary:(nullable NSDictionary *personalizedAdStatus = @{ + PACStoreKeyVersionString : PACVersionString, + PACStoreKeyPlatform : @"ios", PACStoreKeyTaggedForUnderAgeOfConsent : _tagForUnderAgeOfConsent ? @1 : @0, PACStoreKeyIsRequestInEEAOrUnknown : _isRequestInEEAOrUnknown ? @1 : @0, PACStoreKeyHasAnyNonPersonalizedPublisherIdentifier : @@ -267,8 +272,8 @@ - (nullable NSURL *)infoUpdateURLForPublisherIdentifiers: if (!publisherIdentifierString.length) { publisherIdentifierString = @""; } - NSString *infoUpdateURLString = - [[NSString alloc] initWithFormat:PACInfoUpdateURLFormat, publisherIdentifierString]; + NSString *infoUpdateURLString = [[NSString alloc] + initWithFormat:PACInfoUpdateURLFormat, PACVersionString, publisherIdentifierString]; if ([self debugModeEnabled]) { NSString *debugGeographyParam = @""; diff --git a/PersonalizedAdConsent/PersonalizedAdConsent/PACView.h b/PersonalizedAdConsent/PersonalizedAdConsent/PACView.h index 32323ea..263151f 100755 --- a/PersonalizedAdConsent/PersonalizedAdConsent/PACView.h +++ b/PersonalizedAdConsent/PersonalizedAdConsent/PACView.h @@ -24,6 +24,7 @@ static PACFormKey const PACFormKeyAppPrivacyPolicyURLString = @"app_privacy_url" static PACFormKey const PACFormKeyConstentInfo = @"consent_info"; static PACFormKey const PACFormKeyAppName = @"app_name"; static PACFormKey const PACFormKeyAppIcon = @"app_icon"; +static PACFormKey const PACFormKeyPlatform = @"plat"; /// Loads and displays the consent form. @interface PACView : UIView diff --git a/PersonalizedAdConsent/PersonalizedAdConsent/PACView.m b/PersonalizedAdConsent/PersonalizedAdConsent/PACView.m index 095fcb6..1fb1ed1 100755 --- a/PersonalizedAdConsent/PersonalizedAdConsent/PACView.m +++ b/PersonalizedAdConsent/PersonalizedAdConsent/PACView.m @@ -162,31 +162,49 @@ - (instancetype)initWithFrame:(CGRect)frame { - (void)loadWithFormInformation:(nonnull NSDictionary *)formInformation completionHandler:(nonnull PACLoadCompletion)handler { formInformation = [formInformation copy]; + PACLoadCompletion wrappedHandler = ^(NSError *_Nullable error) { + if (handler) { + handler(error); + } + }; dispatch_async(dispatch_get_main_queue(), ^{ if (self->_loadCompletionHandler) { // In progress. NSError *error = PACErrorWithDescription(@"Another load is in progress."); - if (handler) { - handler(error); - } + wrappedHandler(error); return; } self->_formInformation = formInformation; - self->_loadCompletionHandler = ^(NSError *_Nullable error) { - if (handler) { - handler(error); - } - }; + self->_loadCompletionHandler = wrappedHandler; [self loadWebView]; }); } +/// Returns the resource bundle located within |bundle|. +- (nullable NSBundle *)resourceBundleForBundle:(nonnull NSBundle *)bundle { + NSURL *resourceBundleURL = + [bundle URLForResource:@"PersonalizedAdConsent" withExtension:@"bundle"]; + if (resourceBundleURL) { + return [NSBundle bundleWithURL:resourceBundleURL]; + } + return nil; +} + /// Loads the consent form HTML into the web view. - (void)loadWebView { - NSURL *bundleURL = - [[NSBundle mainBundle] URLForResource:@"PersonalizedAdConsent" withExtension:@"bundle"]; - NSBundle *bundle = [NSBundle bundleWithURL:bundleURL]; - NSURL *URL = [bundle URLForResource:@"consentform" withExtension:@"html"]; + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSBundle *resourceBundle = [self resourceBundleForBundle:bundle]; + if (!resourceBundle) { + resourceBundle = [self resourceBundleForBundle:[NSBundle mainBundle]]; + } + if (!resourceBundle) { + NSError *error = + PACErrorWithDescription(@"Resource bundle not found. Ensure the resource bundle is " + @"packaged with your application or framework bundle."); + [self loadCompletedWithError:error]; + return; + } + NSURL *URL = [resourceBundle URLForResource:@"consentform" withExtension:@"html"]; NSURLRequest *URLRequest = [[NSURLRequest alloc] initWithURL:URL]; [_webView loadRequest:URLRequest]; } @@ -198,6 +216,7 @@ - (void)updateWebViewInformation { [self->_formInformation mutableCopy]; mutableFormInformation[PACFormKeyAppName] = PACShortAppName(); mutableFormInformation[PACFormKeyAppIcon] = PACIconDataURIString(); + mutableFormInformation[PACFormKeyPlatform] = @"ios"; NSString *infoString = PACJSONStringForDictionary(mutableFormInformation); NSString *command = PACCreateJavaScriptCommandString(@"setUpConsentDialog", @{ diff --git a/PersonalizedAdConsent/PersonalizedAdConsent/PersonalizedAdConsent.bundle/consentform.html b/PersonalizedAdConsent/PersonalizedAdConsent/PersonalizedAdConsent.bundle/consentform.html index f11aa6d..f1f4b2d 100755 --- a/PersonalizedAdConsent/PersonalizedAdConsent/PersonalizedAdConsent.bundle/consentform.html +++ b/PersonalizedAdConsent/PersonalizedAdConsent/PersonalizedAdConsent.bundle/consentform.html @@ -600,16 +600,37 @@ var infoJSON = args['info'] || ''; var formInfo; - var consentInfo; - var rawResponseJSON; - var rawResponse; try { formInfo = JSON.parse(infoJSON) || {}; - consentInfo = formInfo['consent_info'] || {}; - rawResponseJSON = consentInfo['raw_response'] || ''; + } catch(e) { + formLoadCompleted('Error: consent SDK passed invalid data to the ' + + 'consent form. ' + e.message); + return; + } + + var consentInfo = formInfo['consent_info'] || {}; + var rawResponseJSON = consentInfo['raw_response'] || ''; + + if (!rawResponseJSON) { + var method; + if (formInfo['plat'] === 'ios') { + method = '-[PACConsentInformation ' + + 'requestConsentInfoUpdateForPublisherIdentifiers:completionHandler:]'; + } else { + method = 'com.google.ads.consent.ConsentInformation.requestConsentInfoUpdate()'; + } + var message = 'Error: no information available. Successful call to ' + + method + ' required before using this form.'; + formLoadCompleted(message); + return; + } + + var rawResponse; + try { rawResponse = JSON.parse(rawResponseJSON) || {}; } catch(e) { - formLoadCompleted('Error: invalid data. ' + e.message); + formLoadCompleted('Error: consent form received invalid data from ' + + 'the consent server. ' + e.message); return; }