Get Started

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.

  1. In Xcode, install the PAL SDK Swift Package by navigating to File > Add Packages....

  2. 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 
     
    
  3. 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.

  1. Download and extract the PAL SDK for iOS
  2. 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.