Stay organized with collectionsSave and categorize content based on your preferences.
The IMA DAI SDK and the IMA client-side SDK have been merged in version 4,
and have been reworked as an exact subset of the iOS SDK. This significantly
reduces the learning curve for iOS developers. As a result, some of the code
required for DAI users has changed to be more consistent with our other SDKs.
This guide walks through the process required to upgrade an existing v3
implementation to the new v4 SDK.
If in doubt, consult theiOS DAI samplesthe
tvOS v4 API is the same (except for companions and PIP, which are unavailable on
tvOS).
Change the module name
To match the iOS SDK, we've changed the module name fromInteractiveMediaAdstoGoogleInteractiveMediaAds.
Implement IMAAdsLoaderDelegate for stream initialization
These functions have been renamed and modified to be consistent with the iOS
SDK. The relationship between stream manager and stream has also changed. In the
v3 SDK, a single stream manager could be used to manage multiple streams. In v4,
each stream manager can only manage a single stream.
Changes
Old
-(void)streamManager:(IMAStreamManager*)streamManagerdidInitializeStream:(NSString*)streamID{NSLog(@"Stream initialized with streamID: %@",streamID);}-(void)streamManager:(IMAStreamManager*)streamManagerdidReceiveError:(NSError*)error{NSLog(@"Error: %@",error);[selfplayBackupStream];}
New
-(void)adsLoader:(IMAAdsLoader*)loaderadsLoadedWithData:(IMAAdsLoadedData*)adsLoadedData{self.streamManager=adsLoadedData.streamManager;self.streamManager.delegate=self;[self.streamManagerinitializeWithAdsRenderingSettings:nil];NSLog(@"Stream initialized with streamID: %@",self.streamManager.streamId);}-(void)adsLoader:(IMAAdsLoader*)loaderfailedWithErrorData:(IMAAdLoadingErrorData*)adErrorData{NSLog(@"Error: %@",adErrorData.adError);[selfplayBackupStream];}
Implement IMAStreamManagerDelegate
For consistency with the iOS SDKs, the tvOS SDK now provides a single stream
manager delegate,IMAStreamManagerDelegate, for handling stream events. You
now need to use a switch statement within that delegate to manage specific
events.
-(void)streamManager:(IMAStreamManager*)streamManagerdidReceiveAdEvent:(IMAAdEvent*)event{NSLog(@"StreamManager event (%@).",event.typeString);switch(event.type){casekIMAAdEvent_AD_BREAK_STARTED:{NSLog(@"Ad break started");self.playerViewController.requiresLinearPlayback=YES;break;}casekIMAAdEvent_AD_BREAK_ENDED:{NSLog(@"Ad break ended");self.playerViewController.requiresLinearPlayback=NO;break;}// And so on for other events.default:break;}}
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-20 UTC."],[[["\u003cp\u003eThe IMA DAI SDK v4 for tvOS is now an exact subset of the iOS SDK, simplifying development for iOS developers working on tvOS.\u003c/p\u003e\n"],["\u003cp\u003eUpgrading to v4 requires changing the module name to \u003ccode\u003eGoogleInteractiveMediaAds\u003c/code\u003e, creating an \u003ccode\u003eIMAAdDisplayContainer\u003c/code\u003e, and passing it along with \u003ccode\u003eIMAVideoDisplay\u003c/code\u003e to the stream request.\u003c/p\u003e\n"],["\u003cp\u003eInstead of \u003ccode\u003eIMAStreamManager\u003c/code\u003e, use \u003ccode\u003eIMAAdsLoader\u003c/code\u003e to request streams and implement \u003ccode\u003eIMAAdsLoaderDelegate\u003c/code\u003e for stream initialization.\u003c/p\u003e\n"],["\u003cp\u003eHandle stream events through the unified \u003ccode\u003eIMAStreamManagerDelegate\u003c/code\u003e using a switch statement to manage specific events like ad breaks.\u003c/p\u003e\n"]]],["Version 4 merges the IMA DAI and client-side SDKs, aligning with the iOS SDK. Key changes include: renaming the module to `GoogleInteractiveMediaAds`, creating an `IMAAdDisplayContainer` for ad management, and passing it with `IMAVideoDisplay` to `IMAStreamRequest`. The `IMAAdsLoader` replaces direct stream management, using `IMAAdsLoaderDelegate` for initialization and `IMAStreamManagerDelegate` for events, requiring a switch statement for specific events. Each stream manager now handles only one stream.\n"],null,["# Upgrade from v3 to v4\n\nThe IMA DAI SDK and the IMA client-side SDK have been merged in version 4,\nand have been reworked as an exact subset of the iOS SDK. This significantly\nreduces the learning curve for iOS developers. As a result, some of the code\nrequired for DAI users has changed to be more consistent with our other SDKs.\n\nThis guide walks through the process required to upgrade an existing v3\nimplementation to the new v4 SDK.\n\nIf in doubt, consult the\n[iOS DAI samples](//github.com/googleads/googleads-ima-ios-dai)---the\ntvOS v4 API is the same (except for companions and PIP, which are unavailable on\ntvOS).\n\nChange the module name\n----------------------\n\nTo match the iOS SDK, we've changed the module name from `InteractiveMediaAds`\nto `GoogleInteractiveMediaAds`.\n\n| Changes ||\n|-----|-------------------------------------------------------------------------------|\n| Old | ```python #import \u003cInteractiveMediaAds/InteractiveMediaAds.h\u003e ``` |\n| New | ```python #import \u003cGoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h\u003e ``` |\n| Old | ```python @import InteractiveMediaAds; ``` |\n| New | ```python @import GoogleInteractiveMediaAds; ``` |\n\nCreate the new ad container\n---------------------------\n\nThe `IMAAdDisplayContainer` is responsible for managing the ad container view and\ncompanion ad slots used for ad playback.\n\n| Changes ||\n|-----|------------------------------------------------------------------------------------------------------------------|\n| Old | There is no prior equivalent. |\n| New | ```objective-c self.adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView]; ``` |\n\nPass the IMAVideoDisplay and IMAAdDisplayContainer into the IMAStreamRequest\n----------------------------------------------------------------------------\n\nNow that you have a video display and `IMAAdDisplayContainer,` you need to pass\nthem to the stream request so that the IMA DAI SDK can manage them.\n\n| Changes ||\n|-----|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Old | ```objective-c IMALiveStreamRequest *streamRequest = [[IMALiveStreamRequest alloc] initWithAssetKey:kAssetKey]; IMAVODStreamRequest *streamRequest = [[IMAVODStreamRequest alloc] initWithContentSourceID:kContentSourceID videoID:kVideoID]; ``` |\n| New | ```objective-c IMALiveStreamRequest *streamRequest = [[IMALiveStreamRequest alloc] initWithAssetKey:kAssetKey adDisplayContainer:self.adDisplayContainer videoDisplay:self.videoDisplay]; IMAVODStreamRequest *streamRequest = [[IMAVODStreamRequest alloc] initWithContentSourceId:kContentSourceID videoId:kVideoID adDisplayContainer:self.adDisplayContainer videoDisplay:self.videoDisplay]; ``` |\n\nRequest with an IMAAdsLoader\n----------------------------\n\n| Changes ||\n|-----|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Old | ```objective-c self.streamManager = [[IMAStreamManager alloc] initWithVideoDisplay:self.videoDisplay]; self.streamManager.delegate = self; [self.streamManager requestStream:streamRequest]; ``` |\n| New | \u003cbr /\u003e ```objective-c self.adsLoader = [[IMAAdsLoader alloc] init]; self.adsLoader.delegate = self; [self.adsLoader requestStreamWithRequest:streamRequest]; ``` |\n\nImplement IMAAdsLoaderDelegate for stream initialization\n--------------------------------------------------------\n\nThese functions have been renamed and modified to be consistent with the iOS\nSDK. The relationship between stream manager and stream has also changed. In the\nv3 SDK, a single stream manager could be used to manage multiple streams. In v4,\neach stream manager can only manage a single stream.\n\n| Changes ||\n|-----|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Old | ```objective-c - (void)streamManager:(IMAStreamManager *)streamManager didInitializeStream:(NSString *)streamID { NSLog(@\"Stream initialized with streamID: %@\", streamID); } - (void)streamManager:(IMAStreamManager *)streamManager didReceiveError:(NSError *)error { NSLog(@\"Error: %@\", error); [self playBackupStream]; } ``` |\n| New | ```objective-c - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { self.streamManager = adsLoadedData.streamManager; self.streamManager.delegate = self; [self.streamManager initializeWithAdsRenderingSettings:nil]; NSLog(@\"Stream initialized with streamID: %@\", self.streamManager.streamId); } - (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData { NSLog(@\"Error: %@\", adErrorData.adError); [self playBackupStream]; } ``` |\n\nImplement IMAStreamManagerDelegate\n----------------------------------\n\nFor consistency with the iOS SDKs, the tvOS SDK now provides a single stream\nmanager delegate, `IMAStreamManagerDelegate`, for handling stream events. You\nnow need to use a switch statement within that delegate to manage specific\nevents.\n\n| Changes ||\n|-----|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Old | ```objective-c - (void)streamManager:(IMAStreamManager *)streamManager adBreakDidStart:(IMAAdBreakInfo *)adBreakInfo { NSLog(@\"Ad break started\"); self.playerViewController.requiresLinearPlayback = YES; } - (void)streamManager:(IMAStreamManager *)streamManager adBreakDidEnd:(IMAAdBreakInfo *)adBreakInfo { NSLog(@\"Ad break ended\"); self.playerViewController.requiresLinearPlayback = NO; } ``` |\n| New | ```objective-c - (void)streamManager:(IMAStreamManager *)streamManager didReceiveAdEvent:(IMAAdEvent *)event { NSLog(@\"StreamManager event (%@).\", event.typeString); switch (event.type) { case kIMAAdEvent_AD_BREAK_STARTED: { NSLog(@\"Ad break started\"); self.playerViewController.requiresLinearPlayback = YES; break; } case kIMAAdEvent_AD_BREAK_ENDED: { NSLog(@\"Ad break ended\"); self.playerViewController.requiresLinearPlayback = NO; break; } // And so on for other events. default: break; } } ``` |"]]