Get Started

Prerequisites

  • Xcode.
  • The iOS PAL SDK.
  • A new single-view application with the PAL Framework added as a linked framework and embedded binary. This guide uses the PAL iOS sample application as a template.

Generate a nonce

A "nonce" is a single encrypted string generated by PAL via the PALNonceLoader. The PAL SDK requires each new stream request to be accompanied by a newly generated nonce. However, nonces may 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;

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];
  self.nonceLoader = [[PALNonceLoader alloc] init];
  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 (sane) user
 * might supply. Displays the nonce or error on success. This should be called once per stream.
 */
- (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";
  request.videoPlayerHeight = 480;
  request.videoPlayerWidth = 640;
  request.willAdAutoPlay = PALFlagOn;
  request.willAdPlayMuted = PALFlagOff;
  request.OMIDPartnerName = @"SamplePartner";
  request.OMIDPartnerVersion = @"6.2.1";
  request.OMIDVersion = @"1.2.3";

  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 paln parameter. The nonce is URL safe—you don't need to URL-encode it.

Lastly, you will need to add methods to handle sending content playback session information and clicks to the SDK. In this case, we will implement 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” 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.g.doubleclick.net/gampad/ads?givn=%%custom_key_for_google_nonce%%&iu=/21775744923/external/single_ad_samples&sz=640x480'

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.