If you're interested in an iOS video player with the SDK pre-integrated, check out the Google Media Framework.
Prerequisites
Before you begin, you'll need the following:
- Read through our compatibility page to make sure your intended use case is supported.
- Xcode 6
- CocoaPods (preferred) or the IMA SDK zip
- The Sample Video Player App to add the IMA implementation yourself
Download SampleVideoPlayer.zip View on GitHub
Adding the SDK to the Xcode project
Streamlined, using CocoaPods (Preferred)
If you don't have CocoaPods installed on your machine, see the CocoaPods documentation. To use CocoaPods, create a Podfile in the directory containing the SampleVideoPlayer.xcodeproj directory. For the IMA SDK, the Podfile should look like this:
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '9.0' pod 'GoogleAds-IMA-iOS-SDK', '~> 3.0.beta.16'
With that file created, run pod install
in the same directory to automatically download the IMA SDK. Once that command completes, open the .xcworkspace file in Xcode. Inside the Xcode Workspace, you'll see two projects - one for the SampleVideoPlayer, and the other for the dependencies installed by CocoaPods.

Your first ads request
- Import the IMA SDK
To start, we're going to import the IMA framework. To do so, navigate to ViewController.m and add the following beneath your imports list:
Objective-C
ViewController.m#import "ViewController.h" @import GoogleInteractiveMediaAds; @interface ViewController () ...
Swift
ViewController.swiftimport AVFoundation import UIKit import GoogleInteractiveMediaAds class ViewController: UIViewcontroller { ...
- Define a Content Playhead Tracker
In order to play mid-rolls, the SDK needs to track the current position of your video content. For it to do this you'll need to create a class that implements
IMAContentPlayhead
. If you're using anAVPlayer
, the SDK provides theIMAAVPlayerContentPlayhead
class which does this for you. If you're not using AVPlayer, you'll need to implementIMAContentPlayhead
on a class of your own. The below snippet shows how to set up a playhead tracker for an implementation that is using anAVPlayer
.You'll also need to let the SDK know when your content is done playing so it can display post-rolls. This is done by calling
contentComplete
on theIMAAdsLoader
. We do this below usingAVPlayerItemDidPlayToEndTimeNotification
.Objective-C
ViewController.m#import "ViewController.h" @import GoogleInteractiveMediaAds; @interface ViewController () ... @property(nonatomic, strong) IMAAVPlayerContentPlayhead *contentPlayhead; ... @end ... - (void)createContentPlayhead { self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.contentPlayer currentItem]]; } - (void)contentDidFinishPlaying:(NSNotification *)notification { // Make sure we don't call contentComplete as a result of an ad completing. if (notification.object == self.contentPlayer.currentItem) { // NOTE: This line will cause an error until the next step, "Request Ads". [self.adsLoader contentComplete]; } }
Swift
ViewController.swiftimport AVFoundation import UIKit import GoogleInteractiveMediaAds class ViewController: UIViewController { ... var contentPlayhead: IMAAVPlayerContentPlayhead? ... func createContentPlayhead() { contentPlayhead = IMAAVPlayerContentPlayhead(AVPlayer: contentPlayer) NSNotificationCenter.defaultCenter().addObserver( self, selector: "contentDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: contentPlayer!.currentItem); } func contentDidFinishPlaying(notification: NSNotification) { // Make sure we don't call contentComplete as a result of an ad completing. if ((notification.object as! AVPlayerItem) == contentPlayer!.currentItem) { // NOTE: This line will cause an error until the next step, "Request Ads". adsLoader!.contentComplete() } } }
- Request Ads
Now that you've defined your ad display container, rendering settings, and content playhead, you're ready to make an ads request. To request ads, you'll need an instance of
IMAAdsLoader
, an ad tag, and the ad display container you defined earlier. You'll also need to change some existing code to make sure ads get requested when the user clicks the play button.Objective-C
ViewController.m@interface ViewController () ... @property(nonatomic, strong) IMAAdsLoader *adsLoader; ... @end ... NSString *const kTestAppAdTagUrl = @"http://pubads.g.doubleclick.net/gampad/ads?sz=640x360&" @"iu=/6062/iab_vast_samples/skippable&ciu;_szs=300x250,728x90&impl;=s&" @"gdfp_req=1&env;=vp&output;=vast&unviewed;_position_start=1&" @"url=[referrer_url]&correlator;=[timestamp]"; - (void)viewdidLoad { [super viewDidLoad]; self.playButton.layer.zPosition = MAXFLOAT; [self setUpContentPlayer]; [self setupAdsLoader]; } - (IBAction)onPlayButtonTouch:(id)sender { //[self.contentPlayer play]; [self requestAds]; self.playButton.hidden = YES; } - (void)setupAdsLoader { // Re-use this IMAAdsLoader instance for the entire lifecycle of your app. self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil]; // NOTE: This line will cause a warning until the next step, "Get the Ads Manager". self.adsLoader.delegate = self; } - (void)requestAds { // Create an ad display container for ad rendering. IMAAdDisplayContainer *adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView companionSlots:nil]; // Create an ad request with our ad tag, display container, and optional user context. IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kTestAppAdTagUrl adDisplayContainer:adDisplayContainer userContext:nil]; [self.adsLoader requestAdsWithRequest:request]; }
Swift
ViewController.swiftclass ViewController: UIViewController { ... var adsLoader: IMAAdsLoader? let kTestAppAdTagUrl = "http://pubads.g.doubleclick.net/gampad/ads?sz=640x360" + "&iu;=/6062/iab_vast_samples/skippable&ciu;_szs=300x250,728x90&impl;=s&gdfp;_req=1&env;=vp&" + "output=vast&unviewed;_position_start=1&url;=[referrer_url]&correlator;=[timestamp]"; ... override func viewDidLoad() { super.viewDidLoad() playButton.layer.zPosition = CGFloat.AX setUpContentPlayer() setUpAdsLoader() } @IBAction func onPlayButtonTouch(sender: AnyObject) { //contentPlayer!.play() requestAds() playButton.hidden = true } func setUpAdsLoader() { adsLoader = IMAAdsLoader(settings: nil) // NOTE: This line will cause an error until the next step, "Get the Ads Manager". adsLoader!.delegate = self } func requestAds() { // Create an ad display container for ad rendering. var adDisplayContainer = IMAAdDisplayContainer(adContainer: videoView, companionSlots: nil) // Create an ad request with our ad tag, display container, and optional user context. var request = IMAAdsRequest( adTagUrl: kTestAppAdTagUrl, adDisplayContainer: adDisplayContainer, userContext: nil) adsLoader!.requestAdsWithRequest(request) } }
At this point you're requesting ads and should be getting a response from the ad server, but no ads will play. To show and play ads, you'll need to work with the IMAAdsManager.
- Get the Ads Manager
If your ads requests is successful, the SDK will create an ads manager for you, and pass it to you in the
adsLoader:adsLoadedWithData
method. Once you have your instance of the ads manager, you'll provide it with the ads rendering settings and content playhead you defined earlier.Objective-C
ViewController.m@interface ViewController () <IMAAdsLoaderDelegate> ... @property(nonatomic, strong) IMAAdsManager *adsManager; ... @end ... - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { // Grab the instance of the IMAAdsManager and set ourselves as the delegate. self.adsManager = adsLoadedData.adsManager; // NOTE: This line will cause a warning until the next step, "Display Ads". self.adsManager.delegate = self; // Create ads rendering settings and tell the SDK to use the in-app browser. IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init]; adsRenderingSettings.webOpenerPresentingController = self; // Create a content playhead so the SDK can track our content for VMAP and ad rules. [self createContentPlayhead]; // Initialize the ads manager. [self.adsManager initializeWithContentPlayhead:self.contentPlayhead adsRenderingSettings:adsRenderingSettings]; } - (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData { // Something went wrong loading ads. Log the error and play the content. NSLog(@"Error loading ads: %@", adErrorData.adError.message); [self.contentPlayer play]; }
Swift
ViewController.swiftclass ViewController: UIViewController, IMAAdsLoaderDelegate { ... var adsManager: IMAAdsManager? ... func adsLoader(loader: IMAAdsLoader!, adsLoadedWithData adsLoadedData: IMAAdsLoadedData!) { // Grab the instance of the IMAAdsManager and set ourselves as the delegate adsManager = adsLoadedData.adsManager adsManager!.delegate = self // Create ads rendering settings and tell the SDK to use the in-app browser. var adsRenderingSettings = IMAAdsRenderingSettings() adsRenderingSettings.webOpenerPresentingController = self // Create a content playhead so the SDK can track our content for VMAP and ad rules. createContentPlayhead() // Initialize the ads manager. adsManager!.initializeWithContentPlayhead( contentPlayhead, adsRenderingSettings: adsRenderingSettings) } func adsLoader(loader: IMAAdsLoader!, failedWithErrorData adErrorData: IMAAdLoadingErrorData!) { NSLog("Error loading ads: \(adErrorData.adError.message)") contentPlayer!.play() } }
- Display Ads
Now that you have an instance of the
AdsManager
, you can display ads. To do this you'll need to implement theAdsManagerDelegate
methods as follows:Objective-C
ViewController.m@interface ViewController () <IMAAdsLoaderDelegate
, IMAAdsManagerDelegate> ... @end ... - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event { if (event.type == kIMAAdEvent_LOADED) { // When the SDK notifies us that ads have been loaded, play them. [adsManager start]; } } - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error { // Something went wrong with the ads manager after ads were loaded. Log the error and play the // content. NSLog(@"AdsManager error: %@", error.message); [self.contentPlayer play]; } - (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager { // The SDK is going to play ads, so pause the content. [self.contentPlayer pause]; } - (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager { // The SDK is done playing ads (at least for now), so resume the content. [self.contentPlayer play]; } Swift
ViewController.swiftclass ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { ... func adsManager(adsManager: IMAAdsManager!, didReceiveAdEvent event: IMAAdEvent!) { if (event.type == IMAAdEventType.LOADED) { // When the SDK notifies us that ads have been loaded, play them. adsManager.start() } } func adsManager(adsManager: IMAAdsManager!, didReceiveAdError error: IMAAdError!) { // Something went wrong with the ads manager after ads were loaded. Log the // error and play the content. NSLog("AdsManager error: \(error.message)") contentPlayer!.play() } func adsManagerDidRequestContentPause(adsManager: IMAAdsManager!) { // The SDK is going to play ads, so pause the content. contentPlayer!.pause() } func adsManagerDidRequestContentResume(adsManager: IMAAdsManager!) { // The SDK is done playing ads (at least for now), so resume the content. contentPlayer!.play() } }
That's it! You're now requesting and displaying your first ads. For more info on fine-tuning your implementation, check out advanced topics.
Full source
Objective-C
Viewcontroller.m#import <AVFoundation/AVFoundation.h> #import "ViewController.h" @import GoogleInteractiveMediaAds; @interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate> /// Content video player. @property(nonatomic, strong) AVPlayer *contentPlayer; // SDK /// Entry point for the SDK. Used to make ad requests. @property(nonatomic, strong) IMAAdsLoader *adsLoader; // Playhead used by the SDK to track content video progress and insert mid-rolls. @property(nonatomic, strong) IMAAVPlayerContentPlayhead *contentPlayhead; /// Main point of interaction with the SDK. Created by the SDK as the result of an ad request. @property(nonatomic, strong) IMAAdsManager *adsManager; @end @implementation ViewController // The content URL to play. NSString *const kTestAppContentUrl_MP4 = @"http://rmcdn.2mdn.net/Demo/html5/output.mp4"; // Ad tag NSString *const kTestAppAdTagUrl = @"http://pubads.g.doubleclick.net/gampad/ads?sz=640x360&" @"iu=/6062/iab_vast_samples/skippable&ciu_szs=300x250,728x90&impl=s&" @"gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&" @"url=[referrer_url]&correlator=[timestamp]"; - (void)viewDidLoad { [super viewDidLoad]; self.playButton.layer.zPosition = MAXFLOAT; [self setupAdsLoader]; [self setUpContentPlayer]; } - (IBAction)onPlayButtonTouch:(id)sender { [self requestAds]; self.playButton.hidden = YES; } #pragma mark Content Player Setup - (void)setUpContentPlayer { // Load AVPlayer with path to our content. NSURL *contentURL = [NSURL URLWithString:kTestAppContentUrl_MP4]; self.contentPlayer = [AVPlayer playerWithURL:contentURL]; // Create a player layer for the player. AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.contentPlayer]; // Size, position, and display the AVPlayer. playerLayer.frame = self.videoView.layer.bounds; [self.videoView.layer addSublayer:playerLayer]; } #pragma mark SDK Setup - (void)setupAdsLoader { self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil]; self.adsLoader.delegate = self; } - (void)requestAds { // Create an ad display container for ad rendering. IMAAdDisplayContainer *adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView companionSlots:nil]; // Create an ad request with our ad tag, display container, and optional user context. IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kTestAppAdTagUrl adDisplayContainer:adDisplayContainer userContext:nil]; [self.adsLoader requestAdsWithRequest:request]; } - (void)createContentPlayhead { self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.contentPlayer currentItem]]; } - (void)contentDidFinishPlaying:(NSNotification *)notification { // Make sure we don't call contentComplete as a result of an ad completing. if (notification.object == self.contentPlayer.currentItem) { [self.adsLoader contentComplete]; } } #pragma mark AdsLoader Delegates - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { // Grab the instance of the IMAAdsManager and set ourselves as the delegate. self.adsManager = adsLoadedData.adsManager; self.adsManager.delegate = self; // Create ads rendering settings to tell the SDK to use the in-app browser. IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init]; adsRenderingSettings.webOpenerPresentingController = self; // Create a content playhead so the SDK can track our content for VMAP and ad rules. [self createContentPlayhead]; // Initialize the ads manager. [self.adsManager initializeWithContentPlayhead:self.contentPlayhead adsRenderingSettings:adsRenderingSettings]; } - (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData { // Something went wrong loading ads. Log the error and play the content. NSLog(@"Error loading ads: %@", adErrorData.adError.message); [self.contentPlayer play]; } #pragma mark AdsManager Delegates - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event { // When the SDK notified us that ads have been loaded, play them. if (event.type == kIMAAdEvent_LOADED) { [adsManager start]; } } - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error { // Something went wrong with the ads manager after ads were loaded. Log the error and play the // content. NSLog(@"AdsManager error: %@", error.message); [self.contentPlayer play]; } - (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager { // The SDK is going to play ads, so pause the content. [_contentPlayer pause]; } - (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager { // The SDK is done playing ads (at least for now), so resume the content. [_contentPlayer play]; } @end
Swift
ViewController.swift// // ViewController.swift // BasicExample // // Created by Shawn Busolits on 5/4/15. // import AVFoundation import UIKit import GoogleInteractiveMediaAds class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { let kTestAppContentUrl_MP4 = "http://rmcdn.2mdn.net/Demo/html5/output.mp4" @IBOutlet weak var playButton: UIButton! @IBOutlet weak var videoView: UIView! var contentPlayer: AVPlayer? var contentPlayhead: IMAAVPlayerContentPlayhead? var adsLoader: IMAAdsLoader? var adsManager: IMAAdsManager? let kTestAppAdTagUrl = "http://pubads.g.doubleclick.net/gampad/ads?sz=640x360" + "&iu=/6062/iab_vast_samples/skippable&ciu_szs=300x250,728x90&impl=s&gdfp_req=1&env=vp&" + "output=vast&unviewed_position_start=1&url=[referrer_url]&correlator=[timestamp]"; override func viewDidLoad() { super.viewDidLoad() playButton.layer.zPosition = CGFloat.max setUpContentPlayer() setUpAdsLoader() } @IBAction func onPlayButtonTouch(sender: AnyObject) { //contentPlayer!.play() requestAds() playButton.hidden = true } func setUpContentPlayer() { // Load AVPlayer with path to our content. var contentURL = NSURL(string: kTestAppContentUrl_MP4) contentPlayer = AVPlayer(URL: contentURL) // Create a player layer for the player. var playerLayer = AVPlayerLayer(player: contentPlayer) // Size, position, and display the AVPlayer. playerLayer.frame = self.videoView.layer.bounds videoView.layer.addSublayer(playerLayer) } func createContentPlayhead() { contentPlayhead = IMAAVPlayerContentPlayhead(AVPlayer: contentPlayer) NSNotificationCenter.defaultCenter().addObserver( self, selector: "contentDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: contentPlayer!.currentItem); } func contentDidFinishPlaying(notification: NSNotification) { // Make sure we don't call contentComplete as a result of an ad completing. if ((notification.object as! AVPlayerItem) == contentPlayer!.currentItem) { adsLoader!.contentComplete() } } func setUpAdsLoader() { adsLoader = IMAAdsLoader(settings: nil) adsLoader!.delegate = self } func requestAds() { // Create ad display container for ad rendering. var adDisplayContainer = IMAAdDisplayContainer(adContainer: videoView, companionSlots: nil) // Create an ad request with our ad tag, display container, and optional user context. var request = IMAAdsRequest( adTagUrl: kTestAppAdTagUrl, adDisplayContainer: adDisplayContainer, userContext: nil) adsLoader!.requestAdsWithRequest(request) } func adsLoader(loader: IMAAdsLoader!, adsLoadedWithData adsLoadedData: IMAAdsLoadedData!) { // Grab the instance of the IMAAdsManager and set ourselves as the delegate. adsManager = adsLoadedData.adsManager adsManager!.delegate = self // Create ads rendering settings and tell the SDK to use the in-app browser. var adsRenderingSettings = IMAAdsRenderingSettings() adsRenderingSettings.webOpenerPresentingController = self // Create a content playhead so the SDK can track our content for VMAP and ad rules. createContentPlayhead() // Initialize the ads manager. adsManager!.initializeWithContentPlayhead( contentPlayhead, adsRenderingSettings: adsRenderingSettings) } func adsLoader(loader: IMAAdsLoader!, failedWithErrorData adErrorData: IMAAdLoadingErrorData!) { NSLog("Error loading ads: \(adErrorData.adError.message)") contentPlayer!.play() } func adsManager(adsManager: IMAAdsManager!, didReceiveAdEvent event: IMAAdEvent!) { if (event.type == IMAAdEventType.LOADED) { // When the SDK notifies us that ads have been loaded, play them. adsManager.start() } } func adsManager(adsManager: IMAAdsManager!, didReceiveAdError error: IMAAdError!) { // Something went wrong with the ads manager after ads were loaded. Log the error and play the // content. NSLog("AdsManager error: \(error.message)") contentPlayer!.play() } func adsManagerDidRequestContentPause(adsManager: IMAAdsManager!) { // The SDK is going to play ads, so pause the content. contentPlayer!.pause() } func adsManagerDidRequestContentResume(adsManager: IMAAdsManager!) { // The SDK is done playing ads (at least for now), so resume the content. contentPlayer!.play() } }