Prerequisites
- Xcode 13 or higher.
This guide describes how to invoke the PAL SDK to receive a nonce and monitor playback events. To see a sample app that uses PAL to generate a nonce, download the iOS example from GitHub.
Add the PAL SDK to your project
Install the PAL SDK using Swift Package Manager
The Programmatic Access Library SDK supports Swift Package Manager starting in version 2.5.3. Follow the steps below to import the Swift package.
In Xcode, install the PAL SDK Swift Package by navigating to File > Add Packages....
In the prompt that appears, search for the PAL SDK Swift Package GitHub repository:
https://github.com/googleads/swift-package-manager-google-programmatic-access-library-ios
Select the version of the PAL SDK Swift Package you want to use. For new projects, we recommend using the Up to Next Major Version.
Once you're finished, Xcode resolves your package dependencies and downloads them in the background. For more details on how to add package dependencies, see Apple's article.
Manually download and install the PAL SDK
If you don't want to use Swift Package Manager, you can download the PAL SDK and manually add it to your project.
- Download and extract the PAL SDK for iOS
- Follow the Apple Developer Guide to incorporate the framework in your project.
Generate a nonce
A "nonce" is a single encrypted string generated by PAL using the
PALNonceLoader
. The PAL SDK requires each new stream to be accompanied by a
newly generated nonce. However, nonces can be reused for multiple ad requests
within the same stream.
All of the code snippets below are modifications to ViewController.m
in the
PAL iOS sample application.
To request a nonce, start by importing the PAL library:
@import ProgrammaticAccessLibrary;
You still have control over the stream correlator, or &scor
, which should be
reset once for each new stream. All ad requests of the same stream should share
the same PALNonceLoader
and stream correlator value for frequency capping and
competitive exclusion features to work properly.
Next, create an instance of the PALNonceLoader
, and add stubs for the two
delegate methods:
@interface ViewController () <PALNonceLoaderDelegate>
// The nonce loader to use for nonce requests.
@property(nonatomic) PALNonceLoader *nonceLoader;
// The view in which a video would play. In this sample, it is mocked for
// simplification.
@property(nonatomic, weak) IBOutlet UIView *videoView;
@end
...
- (void) viewDidLoad {
[super viewDidLoad];
// The default value for 'allowStorage' and 'directedForChildOrUnknownAge' is
// 'NO', but should be updated once the appropriate consent has been gathered.
// Publishers should either integrate with a CMP or use a different method to
// handle storage consent.
PALSettings *settings = [[PALSettings alloc] init];
settings.allowStorage = YES;
settings.directedForChildOrUnknownAge = NO;
self.nonceLoader = [[PALNonceLoader alloc] initWithSettings:settings];
self.nonceLoader.delegate = self;
}
#pragma mark - PALNonceLoaderDelegate methods
- (void)nonceLoader:(PALNonceLoader *)nonceLoader
withRequest:(PALNonceRequest *)request
didLoadNonceManager:(PALNonceManager *)nonceManager {
}
- (void)nonceLoader:(PALNonceLoader *)nonceLoader
withRequest:(PALNonceRequest *)request
didFailWithError:(NSError *)error {
}
Then, initiate a nonce request, populate its properties, and use it to initialize a nonce manager:
@interface ViewController () <PALNonceLoaderDelegate>
// The nonce loader to use for nonce requests.
@property(nonatomic) PALNonceLoader *nonceLoader;
// The nonce manager result from the last successful nonce request.
@property(nonatomic) PALNonceManager *nonceManager;
// The view in which a video would play. In this sample, it is mocked for
// simplification.
@property(nonatomic, weak) IBOutlet UIView *videoView;
@end
...
- (void)viewDidLoad {
...
self.nonceLoader.delegate = self;
[self requestNonceManager];
}
...
#pragma mark - UI Callback methods
/**
* Requests a new nonce manager with a request containing arbitrary test values
* like a user might supply. Displays the nonce or error on success. This
* should be called once per stream.
*
* The PALNonceRequest parameters set here are example parameters.
* You should set your parameters based on your own app characteristics.
*/
- (void)requestNonceManager {
PALNonceRequest *request = [[PALNonceRequest alloc] init];
request.continuousPlayback = PALFlagOff;
request.descriptionURL = [NSURL URLWithString:@"https://example.com/desc?key=val"];
request.iconsSupported = YES;
request.playerType = @"AwesomePlayer";
request.playerVersion = @"4.2.1";
request.PPID = @"123987456";
request.sessionID = @"Sample SID";
// Sample API framework integer. See reference docs for more details.
NSInteger SampleAPIFramework = 501;
request.supportedApiFrameworks = [NSMutableSet setWithArray:@[ SampleAPIFramework ]];
request.videoPlayerHeight = 480;
request.videoPlayerWidth = 640;
request.willAdAutoPlay = PALFlagOn;
request.willAdPlayMuted = PALFlagOff;
request.OMIDPartnerName = @"SamplePartner";
request.OMIDPartnerVersion = @"6.2.1";
if (self.nonceManager) {
// Detach the old nonce manager's gesture recognizer before destroying it.
[self.videoView removeGestureRecognizer:self.nonceManager.gestureRecognizer];
self.nonceManager = nil;
}
[self.nonceLoader loadNonceManagerWithRequest:request];
}
Lastly, populate the nonce loader delegates to log generated nonces:
#pragma mark - PALNonceLoaderDelegate methods
- (void)nonceLoader:(PALNonceLoader *)nonceLoader
withRequest:(PALNonceRequest *)request
didLoadNonceManager:(PALNonceManager *)nonceManager {
NSLog(@"Programmatic access nonce: %@", nonceManager.nonce);
// Capture the created nonce manager and attach its gesture recognizer to the video view.
self.nonceManager = nonceManager;
[self.videoView addGestureRecognizer:self.nonceManager.gestureRecognizer];
}
- (void)nonceLoader:(PALNonceLoader *)nonceLoader
withRequest:(PALNonceRequest *)request
didFailWithError:(NSError *)error {
NSLog(@"Error generating programmatic access nonce: %@", error);
}
When making your direct VAST call (DVC), set your nonce as the value on the
givn
parameter. The nonce is URL safe—you don't need to URL-encode it.
Lastly, you need to add methods to handle sending content playback session
information and clicks to the SDK. See the following example implementing the
methods sendPlaybackStart
, sendPlaybackEnd
, and sendAdClick
:
...
// Reports the start of playback for the current content session.
- (void)sendPlaybackStart {
[self.nonceManager sendPlaybackStart];
}
// Reports the end of playback for the current content session.
- (void)sendPlaybackEnd {
[self.nonceManager sendPlaybackEnd];
}
// Reports an ad click for the current nonce manager, if not nil.
- (void)sendAdClick {
[self.nonceManager sendAdClick];
}
In your implementation, sendPlaybackStart
should be called on "video player
start" as playback initiates for the first time, in response to either a
user-initiated action (click-to-play) or an app initiated action (autoplay),
sendPlaybackEnd
should be called when playback ends, and sendAdClick
should
be called each time the viewer clicks an ad.
(Optional) Send Google Ad Manager signals through third-party ad servers
Configure the third-party ad server's request for Ad Manager. After you complete the following steps, the nonce parameter propagates from the PAL SDK, through your intermediary servers, and then to Google Ad Manager. This enables better monetization through Google Ad Manager.
Configure your third-party ad server to include the nonce in the server's request to Ad Manager. Here's an example of an ad tag configured inside of the third-party ad server:
https://pubads.serverside.net/gampad/ads?givn=%%custom_key_for_google_nonce%%&...
For more details, see the Google Ad Manager Server-side implementation guide.
Ad Manager looks for givn=
to identify the nonce value. The third-party ad
server needs to support some macro of its own, such as
%%custom_key_for_google_nonce%%
, and replace it with the nonce query parameter
you provided in the previous step. More information on how to accomplish this
should be available in the third-party ad server's documentation.