Set up the IMA SDK
Stay organized with collections
Save and categorize content based on your preferences.
Page Summary
-
IMA SDKs simplify the integration of multimedia ads into websites and apps, capable of requesting and managing ads from VAST-compliant ad servers.
-
Implementing IMA client-side primarily involves four components:
IMAAdDisplayContainer,IMAAdsLoader,IMAAdsRequest, andIMAAdsManager. -
Prerequisites for this integration include Xcode 13 or later and a method for adding the IMA SDK to your project (CocoaPods, Swift Package Manager, or manual download).
-
To ensure proper ad playback, it is necessary to create a video player, import the IMA SDK, implement a content playhead tracker, and initialize the ads loader to make ad requests.
-
Setting up delegates for the ads loader and ads manager is crucial for handling ad loading events, errors, and controlling content playback (pausing/resuming) as requested by the SDK.
IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can request ads from any VAST-compliant ad server and manage ad playback in your apps. With IMA client-side SDKs, you maintain control of content video playback, while the SDK handles ad playback. Ads play in a separate video player positioned on top of the app's content video player.
This guide demonstrates how to integrate the IMA SDK into a video player app. To view or follow along with a completed sample integration, download the BasicExample from GitHub.
IMA client-side overview
Implementing IMA client-side involves four main SDK components, which this guide demonstrates:
IMAAdDisplayContainer: A container object that specifies where IMA renders ad UI elements and measures viewability, including Active View and Open Measurement.IMAAdsLoader: An object that requests ads and handles events from ads request responses. You should only instantiate one ads loader, which can be reused throughout the life of the application.IMAAdsRequest: An object that defines an ads request. Ads requests specify the URL for the VAST ad tag, as well as additional parameters, such as ad dimensions.IMAAdsManager: An object that contains the response to the ads request, controls ad playback, and listens for ad events fired by the SDK.
Prerequisites
Before you begin, you need the following:
- Xcode 13 or later
- Method for installing the IMA SDK:
- Swift Package Manager (preferred)
- CocoaPods
- A downloaded copy of IMA SDK for iOS
1. Create a new Xcode project
In Xcode, create a new iOS project using Objective-C or Swift. Use BasicExample as the project name.
2. Add the IMA SDK to the Xcode project
To install IMA SDK, choose a preferred method.
Recommended: Install the SDK using Swift Package Manager
The Interactive Media Ads SDK supports Swift Package Manager starting in version 3.18.4. To import the Swift package, complete the following steps:
In Xcode, install the IMA SDK Swift Package by navigating to File > Add Package Dependencies....
In the prompt, search for the IMA iOS SDK Swift Package GitHub repository:
swift-package-manager-google-interactive-media-ads-ios.Select the version of the IMA 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.
Install the SDK using CocoaPods
CocoaPods is a dependency manager for Xcode projects and is the recommended method to install the IMA SDK. For more information on installing or using CocoaPods, see the CocoaPods documentation. Once you have CocoaPods installed, use the following instructions to install the IMA SDK:
In the same directory as your BasicExample.xcodeproj file, create a text file called Podfile, and add the following configuration:
platform:ios,'15' target"BasicExample"do pod'GoogleAds-IMA-iOS-SDK','~> 3.32.0' endFrom the directory that contains the Podfile, run
pod install --repo-update.Verify that the installation was successful by opening the BasicExample.xcworkspace file and confirming it contains two projects: BasicExample and Pods (the dependencies CocoaPods installed).
Manually download and install the SDK
If you don't want to use Swift Package Manager, download and manually add IMA SDK to your project.
Show/hide instructions
- From the iOS IMA Download page, download and extract the latest version of the iOS IMA SDK.
- Open BasicExample.xcodeproj.
- In the left pane, click the project name.
Image showing where to click the project name in the left pane of Xcode - In the center pane, click Build Phases.
Image showing where to click Build Phases in the center pane of Xcode - Expand the Link Binary With Libraries section.
- At the bottom of the libraries list, click the plus icon [+].
- Click Add Other.
- In the directory where you extracted the downloaded SDK, select GoogleInteractiveMediaAds.framework and click Open.
- At the bottom of the libraries list, click the plus icon [+] again.
- In the Status column, verify that
GoogleInteractiveMediaAds.frameworkis set toRequired. - Include the
-ObjClinker flag in your build settings. For more information, see Apple QA1490.
3. Create a video player
First, implement a video player. Initially, this player does not use the IMA SDK and doesn't contain any method to trigger playback.
Objective-C
Import the player dependencies:
#import "ViewController.h"
@importAVFoundation;
Set up the player variables:
@interface ViewController()<IMAAdsLoaderDelegate,IMAAdsManagerDelegate>
/// Content video player.
@property(nonatomic,strong)AVPlayer*contentPlayer;
/// Play button.
@property(nonatomic,weak)IBOutletUIButton*playButton;
/// UIView in which we will render our AVPlayer for content.
@property(nonatomic,weak)IBOutletUIView*videoView;
Initiate the video player when the view loads:
@implementation ViewController
// The content URL to play.
NSString*constkTestAppContentUrl_MP4=
@"https://storage.googleapis.com/gvabox/media/samples/stock.mp4";
// Ad tag
NSString*constkTestAppAdTagUrl=@"https://pubads.g.doubleclick.net/gampad/ads?"
@"iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&"
@"ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&"
@"correlator=";
- (void)viewDidLoad{
[superviewDidLoad];
self.playButton.layer.zPosition=MAXFLOAT;
[selfsetupAdsLoader];
[selfsetUpContentPlayer];
}
#pragma mark Content Player Setup
- (void)setUpContentPlayer{
// Load AVPlayer with path to our content.
NSURL*contentURL=[NSURLURLWithString:kTestAppContentUrl_MP4];
self.contentPlayer=[AVPlayerplayerWithURL:contentURL];
// Create a player layer for the player.
AVPlayerLayer*playerLayer=[AVPlayerLayerplayerLayerWithPlayer:self.contentPlayer];
// Size, position, and display the AVPlayer.
playerLayer.frame=self.videoView.layer.bounds;
[self.videoView.layeraddSublayer:playerLayer];
// Set up our content playhead and contentComplete callback.
self.contentPlayhead=[[IMAAVPlayerContentPlayheadalloc]initWithAVPlayer:self.contentPlayer];
[[NSNotificationCenterdefaultCenter]addObserver:self
selector:@selector(contentDidFinishPlaying:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.contentPlayer.currentItem];
}
- (IBAction)onPlayButtonTouch:(id)sender{
[selfrequestAds];
self.playButton.hidden=YES;
}
Swift
Import the player dependencies:
importAVFoundation
Set up the player variables:
classPlayerContainerViewController:UIViewController,IMAAdsLoaderDelegate,IMAAdsManagerDelegate{
staticletcontentURL=URL(
string:"https://storage.googleapis.com/gvabox/media/samples/stock.mp4")!
privatevarcontentPlayer=AVPlayer(url:PlayerContainerViewController.contentURL)
privatelazyvarplayerLayer:AVPlayerLayer={
AVPlayerLayer(player:contentPlayer)
}()
Initiate the video player when the view loads:
privatelazyvarvideoView:UIView={
letvideoView=UIView()
videoView.translatesAutoresizingMaskIntoConstraints=false
view.addSubview(videoView)
NSLayoutConstraint.activate([
videoView.bottomAnchor.constraint(
equalTo:view.safeAreaLayoutGuide.bottomAnchor),
videoView.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor),
videoView.trailingAnchor.constraint(equalTo:view.safeAreaLayoutGuide.trailingAnchor),
videoView.leadingAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leadingAnchor),
])
returnvideoView
}()
// MARK: - View controller lifecycle methods
overridefuncviewDidLoad(){
super.viewDidLoad()
videoView.layer.addSublayer(playerLayer)
adsLoader.delegate=self
NotificationCenter.default.addObserver(
self,
selector:#selector(contentDidFinishPlaying(_:)),
name:.AVPlayerItemDidPlayToEndTime,
object:contentPlayer.currentItem)
}
overridefuncviewDidAppear(_animated:Bool){
super.viewDidAppear(animated)
playerLayer.frame=videoView.layer.bounds
}
overridefuncviewWillTransition(
tosize:CGSize,withcoordinator:UIViewControllerTransitionCoordinator
){
coordinator.animate{_in
// do nothing
}completion:{_in
self.playerLayer.frame=self.videoView.layer.bounds
}
}
// MARK: - Public methods
funcplayButtonPressed(){
requestAds()
}
4. Import the IMA SDK
To import the IMA SDK, do the following:
Objective-C
Import the IMA SDK:
@importGoogleInteractiveMediaAds;Create variables for the
IMAAdsLoader,IMAAVPlayerContentPlayhead, andIMAAdsManagerclasses used in the app:// 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;
Swift
Import the IMA SDK:
importGoogleInteractiveMediaAdsCreate variables for the
IMAAdsLoader,IMAAVPlayerContentPlayhead, andIMAAdsManagerclasses used in the app:staticletadTagURLString= "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/" +"single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&" +"gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&correlator=" privateletadsLoader=IMAAdsLoader() privatevaradsManager:IMAAdsManager? privatelazyvarcontentPlayhead:IMAAVPlayerContentPlayhead={ IMAAVPlayerContentPlayhead(avPlayer:contentPlayer) }()
5. Implement content playhead tracker and end-of-stream observer
In order to play mid-roll ads, the IMA SDK needs to track the current position
of your video content. To do this, create a class that implements
IMAContentPlayhead. If you're using an AVPlayer, as shown in this example,
the SDK provides the IMAAVPlayerContentPlayhead class which does this for you.
If you're not using AVPlayer, you need to implement IMAContentPlayhead on
a class of your own.
You also need to let the SDK know when your content is done playing so it can
display post-roll ads. Do this by calling the
contentComplete
method on the IMAAdsLoader, using AVPlayerItemDidPlayToEndTimeNotification.
Objective-C
Create the IMAAVPlayerContentPlayhead instance in the player setup:
// Set up our content playhead and contentComplete callback.
self.contentPlayhead=[[IMAAVPlayerContentPlayheadalloc]initWithAVPlayer:self.contentPlayer];
[[NSNotificationCenterdefaultCenter]addObserver:self
selector:@selector(contentDidFinishPlaying:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.contentPlayer.currentItem];
Create the contentDidFinishPlaying() method to call
IMAAdsLoader.contentComplete() when the content finishes playing:
- (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.adsLoadercontentComplete];
}
}
Swift
Create the content ended observer in the player setup:
NotificationCenter.default.addObserver(
self,
selector:#selector(contentDidFinishPlaying(_:)),
name:.AVPlayerItemDidPlayToEndTime,
object:contentPlayer.currentItem)
Create the contentDidFinishPlaying() method to call
IMAAdsLoader.contentComplete() when the content finishes playing:
@objcfunccontentDidFinishPlaying(_notification:Notification){
// Make sure we don't call contentComplete as a result of an ad completing.
ifnotification.objectas?AVPlayerItem==contentPlayer.currentItem{
adsLoader.contentComplete()
}
}
6. Initialize the ads loader and make an ads request
In order to request a set of ads, you need to create an IMAAdsLoader instance.
This loader processes IMAAdsRequest objects associated with a
specified ad tag URL.
As a best practice, only maintain one instance of IMAAdsLoader for the entire
lifecycle of your app. To make additional ad requests, create a new
IMAAdsRequest object, but re-use the same IMAAdsLoader. For more
information, see the IMA SDK FAQ.
Objective-C
- (void)setupAdsLoader{
self.adsLoader=[[IMAAdsLoaderalloc]initWithSettings:nil];
self.adsLoader.delegate=self;
}
- (void)requestAds{
// Create an ad display container for ad rendering.
IMAAdDisplayContainer*adDisplayContainer=
[[IMAAdDisplayContaineralloc]initWithAdContainer:self.videoView
viewController:self
companionSlots:nil];
// Create an ad request with our ad tag, display container, and optional user context.
IMAAdsRequest*request=[[IMAAdsRequestalloc]initWithAdTagUrl:kTestAppAdTagUrl
adDisplayContainer:adDisplayContainer
contentPlayhead:self.contentPlayhead
userContext:nil];
[self.adsLoaderrequestAdsWithRequest:request];
}
Swift
privatefuncrequestAds(){
// Create ad display container for ad rendering.
letadDisplayContainer=IMAAdDisplayContainer(
adContainer:videoView,viewController:self,companionSlots:nil)
// Create an ad request with our ad tag, display container, and optional user context.
letrequest=IMAAdsRequest(
adTagUrl:PlayerContainerViewController.adTagURLString,
adDisplayContainer:adDisplayContainer,
contentPlayhead:contentPlayhead,
userContext:nil)
adsLoader.requestAds(with:request)
}
7. Set up an ads loader delegate
On a successful load event, the IMAAdsLoader calls the
adsLoadedWithData
method of its assigned delegate, passing it an instance of IMAAdsManager. You
can then initialize the ads manager, which loads the individual ads, as defined
by the response to the ad tag URL.
In addition, be sure to handle any errors that may occur during the loading process. If ads don't load, make sure that media playback continues, without ads, so as to not interfere with the user's experience.
Objective-C
- (void)adsLoader:(IMAAdsLoader*)loaderadsLoadedWithData:(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=[[IMAAdsRenderingSettingsalloc]init];
adsRenderingSettings.linkOpenerPresentingController=self;
// Initialize the ads manager.
[self.adsManagerinitializeWithAdsRenderingSettings:adsRenderingSettings];
}
- (void)adsLoader:(IMAAdsLoader*)loaderfailedWithErrorData:(IMAAdLoadingErrorData*)adErrorData{
// Something went wrong loading ads. Log the error and play the content.
NSLog(@"Error loading ads: %@",adErrorData.adError.message);
[self.contentPlayerplay];
}
Swift
funcadsLoader(_loader:IMAAdsLoader,adsLoadedWithadsLoadedData: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.
letadsRenderingSettings=IMAAdsRenderingSettings()
adsRenderingSettings.linkOpenerPresentingController=self
// Initialize the ads manager.
adsManager?.initialize(with:adsRenderingSettings)
}
funcadsLoader(_loader:IMAAdsLoader,failedWithadErrorData:IMAAdLoadingErrorData){
ifletmessage=adErrorData.adError.message{
print("Error loading ads: \(message)")
}
contentPlayer.play()
}
8. Set up an ads manager delegate
Lastly, to manage events and state changes, the ads manager needs a delegate of
its own. The IMAAdManagerDelegate has methods to handle ad events and errors,
as well as methods to trigger play and pause on your video content.
Start playback
Listen for the LOADED event to start playback of content and ads. For more
details, see
didReceiveAdEvent.
Objective-C
- (void)adsManager:(IMAAdsManager*)adsManagerdidReceiveAdEvent:(IMAAdEvent*)event{
// When the SDK notified us that ads have been loaded, play them.
if(event.type==kIMAAdEvent_LOADED){
[adsManagerstart];
}
}
Swift
funcadsManager(_adsManager:IMAAdsManager,didReceiveevent:IMAAdEvent){
// When the SDK notifies us the ads have been loaded, play them.
ifevent.type==IMAAdEventType.LOADED{
adsManager.start()
}
}
Handle errors
Add a handler for ad errors as well. If an error occurs, like in the previous step, resume content playback.
Objective-C
- (void)adsManager:(IMAAdsManager*)adsManagerdidReceiveAdError:(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.contentPlayerplay];
}
Swift
funcadsManager(_adsManager:IMAAdsManager,didReceiveerror:IMAAdError){
// Something went wrong with the ads manager after ads were loaded.
// Log the error and play the content.
ifletmessage=error.message{
print("AdsManager error: \(message)")
}
contentPlayer.play()
}
Listen for play and pause events
The last two delegate methods you need to implement trigger play and pause events on the underlying video content when the IMA SDK requests them. Triggering pause and play when requested prevents the user from missing portions of the video content when ads display.
Objective-C
- (void)adsManagerDidRequestContentPause:(IMAAdsManager*)adsManager{
// The SDK is going to play ads, so pause the content.
[self.contentPlayerpause];
}
- (void)adsManagerDidRequestContentResume:(IMAAdsManager*)adsManager{
// The SDK is done playing ads (at least for now), so resume the content.
[self.contentPlayerplay];
}
Swift
funcadsManagerDidRequestContentPause(_adsManager:IMAAdsManager){
// The SDK is going to play ads, so pause the content.
contentPlayer.pause()
}
funcadsManagerDidRequestContentResume(_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 ads with the IMA SDK. To learn about additional SDK features, see the other guides or the samples on GitHub.
Next Steps
To maximize ad revenue on the iOS platform, request App Transparency and Tracking permission to use IDFA.