Get Started

Prerequisites

  • Xcode.
  • The tvOS PAL SDK.
  • A new single-view application with the PAL Framework added as a linked framework and embedded binary.

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.

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;

  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 ad impressions and clicks to the SDK. In this case, we will implement the methods sendAdView and sendAdClick:

...

/** Reports an ad view for the current nonce manager, if not nil. */
- (void)sendAdView {
  [self.nonceManager sendAdImpression];
}

/** Reports an ad click for the current nonce manager, if not nil. */
- (void)sendAdClick {
  [self.nonceManager sendAdClick];
}

In your implementation, sendAdView should be called each time the first frame of an ad is made visible. sendAdClick should be called each time the viewer clicks an ad.