Mit IMA SDKs lassen sich Multimedia-Anzeigen ganz einfach in Websites und Apps einbinden. Mit IMA SDKs können Anzeigen von jedem VAST-kompatiblen Ad-Server angefordert und die Anzeigenwiedergabe in Ihren Apps verwaltet werden. Mit clientseitigen IMA SDKs behalten Sie die Kontrolle über die Videowiedergabe von Inhalten, während das SDK die Anzeigenwiedergabe übernimmt. Anzeigen werden in einem separaten Videoplayer wiedergegeben, der über dem Videoplayer der App angezeigt wird.
In dieser Anleitung wird gezeigt, wie du das IMA SDK in eine einfache Videoplayer-App einbindest. Wenn du dir eine fertige Beispielintegration ansehen oder ansehen möchtest, lade das BasicExample von GitHub herunter.
IMA-Client – Übersicht
Die clientseitige Implementierung von IMA umfasst vier Haupt-SDK-Komponenten, die in diesem Leitfaden veranschaulicht werden:
IMAAdDisplayContainer
: Containerobjekt, in dem Anzeigen gerendert werden.IMAAdsLoader
: Ein Objekt, das Anzeigen anfordert und Ereignisse aus Antworten auf Anzeigenanfragen verarbeitet. Sie sollten nur einen Anzeigen-Lademechanismus instanziieren, der während der gesamten Lebensdauer der Anwendung wiederverwendet werden kann.IMAAdsRequest
: Ein Objekt, das eine Google Ads-Anfrage definiert. In Anzeigenanfragen werden die URL für das VAST-Anzeigen-Tag sowie zusätzliche Parameter wie Anzeigendimensionen angegeben.IMAAdsManager
: Objekt, das die Antwort auf die Anzeigenanfrage enthält, die Anzeigenwiedergabe steuert und vom SDK ausgelöste Anzeigenereignisse überwacht
Vorbereitung
Für den Start ist Folgendes erforderlich:
- Xcode 13 oder höher
- CocoaPods (bevorzugt), Swift Package Manager oder eine heruntergeladene Kopie des IMA SDK für tvOS
1. Neues Xcode-Projekt erstellen
Erstellen Sie in Xcode ein neues tvOS-Projekt mit Objective-C oder Swift. Verwenden Sie BasicExample als Projektnamen.
2. IMA SDK zum Xcode-Projekt hinzufügen
SDK mit CocoaPods installieren (bevorzugt)
CocoaPods ist ein Abhängigkeitsmanager für Xcode-Projekte und wird für die Installation des IMA SDK empfohlen. Weitere Informationen zum Installieren oder Verwenden von CocoaPods finden Sie in der CocoaPods-Dokumentation. Nachdem du CocoaPods installiert hast, kannst du das IMA SDK mithilfe dieser Anleitung installieren:
Erstellen Sie im selben Verzeichnis wie die Datei BasicExample.xcodeproj eine Textdatei namens Podfile und fügen Sie die folgende Konfiguration hinzu:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '14' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.13.0' end
Führen Sie im Verzeichnis mit der Podfile
pod install --repo-update
aus.Prüfen Sie, ob die Installation erfolgreich war, indem Sie die Datei BasicExample.xcworkspace öffnen und prüfen, ob sie zwei Projekte enthält: BasicExample und Pods (die von CocoaPods installierten Abhängigkeiten).
SDK mit dem Swift Package Manager installieren
Das Interactive Media Ads SDK unterstützt ab Version 4.8.2 den Swift Package Manager. Führen Sie die folgenden Schritte aus, um das Swift-Paket zu importieren.
Installiere das IMA SDK-Swift-Paket in Xcode. Gehe dazu zu File > Add Packages… (Datei > Pakete hinzufügen…).
Suche in der angezeigten Aufforderung nach dem GitHub-Repository für das IMA SDK-Swift-Paket:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
Wähle die Version des IMA SDK Swift-Pakets aus, die du verwenden möchtest. Für neue Projekte empfehlen wir die Option Bis zur nächsten Hauptversion.
Sobald Sie fertig sind, löst Xcode Ihre Paketabhängigkeiten auf und lädt sie im Hintergrund herunter. Weitere Informationen zum Hinzufügen von Paketabhängigkeiten finden Sie im Artikel von Apple.
SDK manuell herunterladen und installieren
Wenn Sie CocoaPods nicht verwenden möchten, können Sie das IMA SDK herunterladen und Ihrem Projekt manuell hinzufügen.
3. Einfachen Videoplayer erstellen
Implementieren Sie zuerst einen einfachen Videoplayer. Dieser Player verwendet anfangs nicht das IMA SDK und enthält noch keine Methode zum Auslösen der Wiedergabe.
ViewController.m
Objective-C
#import "ViewController.h" #import <AVKit/AVKit.h> NSString *const kContentURLString = @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"; @interface ViewController () @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = UIColor.blackColor; [self setupContentPlayer]; } - (void)setupContentPlayer { // Create a content video player. NSURL *contentURL = [NSURL URLWithString:kContentURLString]; AVPlayer *player = [AVPlayer playerWithURL:contentURL]; self.contentPlayerViewController = [[AVPlayerViewController alloc] init]; self.contentPlayerViewController.player = player; self.contentPlayerViewController.view.frame = self.view.bounds; // Attach content video player to view hierarchy. [self showContentPlayer]; } // Add the content video player as a child view controller. - (void)showContentPlayer { [self addChildViewController:self.contentPlayerViewController]; self.contentPlayerViewController.view.frame = self.view.bounds; [self.view insertSubview:self.contentPlayerViewController.view atIndex:0]; [self.contentPlayerViewController didMoveToParentViewController:self]; } // Remove and detach the content video player. - (void)hideContentPlayer { // The whole controller needs to be detached so that it doesn't capture events from the remote. [self.contentPlayerViewController willMoveToParentViewController:nil]; [self.contentPlayerViewController.view removeFromSuperview]; [self.contentPlayerViewController removeFromParentViewController]; } @end
Swift
import AVFoundation import UIKit class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4" var playerViewController: AVPlayerViewController! override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black; setUpContentPlayer() } func setUpContentPlayer() { // Load AVPlayer with path to your content. let contentURL! = URL(string: ViewController.ContentURLString) let player = AVPlayer(url: contentURL) playerViewController = AVPlayerViewController() playerViewController.player = player showContentPlayer() } func showContentPlayer() { self.addChild(playerViewController) playerViewController.view.frame = self.view.bounds self.view.insertSubview(playerViewController.view, at: 0) playerViewController.didMove(toParent:self) } func hideContentPlayer() { // The whole controller needs to be detached so that it doesn't capture events from the remote. playerViewController.willMove(toParent:nil) playerViewController.view.removeFromSuperview() playerViewController.removeFromParent() } }
4. IMA SDK importieren
Fügen Sie als Nächstes das IMA-Framework mit einer Importanweisung unter den vorhandenen Importen hinzu.
ViewController.m
Objective-C
#import "ViewController.h" #import <AVKit/AVKit.h> #import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h> NSString *const kContentURLString = @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";
Swift
import AVFoundation import GoogleInteractiveMediaAds import UIKit class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"
5. Inhalts-Playhead-Tracker und End-of-Stream-Beobachter implementieren
Damit Mid-Roll-Anzeigen wiedergegeben werden können, muss das IMA SDK die aktuelle Position deiner Videoinhalte erfassen. Dazu erstellen Sie eine Klasse, die IMAContentPlayhead
implementiert. Wenn du ein AVPlayer
verwendest, wie in diesem Beispiel gezeigt, stellt das SDK die Klasse IMAAVPlayerContentPlayhead
bereit, die das für dich erledigt.
Wenn Sie AVPlayer
nicht verwenden, müssen Sie IMAContentPlayhead
in einer eigenen Klasse implementieren.
Außerdem musst du dem SDK mitteilen, wenn deine Inhalte abgespielt sind, damit Post-Roll-Anzeigen ausgeliefert werden können. Dazu wird contentComplete
über AVPlayerItemDidPlayToEndTimeNotification
auf IMAAdsLoader
aufgerufen.
ViewController.m
Objective-C
... @interface ViewController () @property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead; @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end ... - (void)setupContentPlayer { // Create a content video player. NSURL *contentURL = [NSURL URLWithString:kContentURLString]; AVPlayer *player = [AVPlayer playerWithURL:contentURL]; self.contentPlayerViewController = [[AVPlayerViewController alloc] init]; self.contentPlayerViewController.player = player; self.contentPlayerViewController.view.frame = self.view.bounds; self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayerViewController.player]; // Track end of content. AVPlayerItem *contentPlayerItem = self.contentPlayerViewController.player.currentItem; [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(contentDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:contentPlayerItem]; // Attach content video player to view hierarchy. [self showContentPlayer]; } ... - (void)contentDidFinishPlaying:(NSNotification *)notification {} - (void)dealloc { [NSNotificationCenter.defaultCenter removeObserver:self]; } @end
Swift
... class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4" var contentPlayhead: IMAAVPlayerContentPlayhead? var playerViewController: AVPlayerViewController! deinit { NotificationCenter.default.removeObserver(self) } ... func setUpContentPlayer() { // Load AVPlayer with path to your content. let contentURL! = URL(string: ViewController.ContentURLString) let player = AVPlayer(url: contentURL) playerViewController = AVPlayerViewController() playerViewController.player = player // Set up your content playhead and contentComplete callback. contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: player) NotificationCenter.default.addObserver( self, selector: #selector(ViewController.contentDidFinishPlaying(_:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem); showContentPlayer() } ... @objc func contentDidFinishPlaying(_ notification: Notification) { adsLoader.contentComplete() } }
6. Anzeigen-Ladeprogramm initialisieren und Anzeigenanfrage stellen
Wenn Sie Anzeigen anfordern möchten, müssen Sie eine IMAAdsLoader
-Instanz erstellen.
Mit diesem Lader können IMAAdsRequest
-Objekte verarbeitet werden, die mit einer bestimmten Anzeigen-Tag-URL verknüpft sind.
Es empfiehlt sich, für den gesamten Lebenszyklus Ihrer App nur eine Instanz von IMAAdsLoader
zu verwenden. Wenn Sie zusätzliche Anzeigenanfragen stellen möchten, erstellen Sie ein neues IMAAdsRequest
-Objekt, verwenden Sie aber dieselbe IMAAdsLoader
. Weitere Informationen finden Sie in den häufig gestellten Fragen zum IMA SDK.
ViewController.m
Objective-C
... NSString *const kContentURLString = @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"; NSString *const kAdTagURLString = @"https://pubads.g.doubleclick.net/gampad/ads?" @"iu=/21775744923/external/vmap_ad_samples&sz=640x480&" @"cust_params=sample_ar%3Dpremidpostlongpod&" @"ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&" @"env=vp&impl=s&cmsid=496&vid=short_onecue&correlator="; @interface ViewController () @property(nonatomic) IMAAdsLoader *adsLoader; @property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead; @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = UIColor.blackColor; [self setupContentPlayer]; [self setupAdsLoader]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self requestAds]; } - (void)setupAdsLoader { self.adsLoader = [[IMAAdsLoader alloc] init]; } - (void)requestAds { // Pass the main view as the container for ad display. IMAAdDisplayContainer *adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view]; IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString adDisplayContainer:adDisplayContainer contentPlayhead:self.contentPlayhead userContext:nil]; [self.adsLoader requestAdsWithRequest:request]; } ... - (void)contentDidFinishPlaying:(NSNotification *)notification { // Notify the SDK that the postrolls should be played. [self.adsLoader contentComplete]; } ... @end
Swift
... class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4" static let AdTagURLString = "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&impl=s&correlator=" var adsLoader: IMAAdsLoader! var contentPlayhead: IMAAVPlayerContentPlayhead? var playerViewController: AVPlayerViewController! ... override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black; setUpContentPlayer() setUpAdsLoader() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated); requestAds() } ... func setUpAdsLoader() { adsLoader = IMAAdsLoader(settings: nil) } func requestAds() { // Create ad display container for ad rendering. let adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view) // Create an ad request with your ad tag, display container, and optional user context. let request = IMAAdsRequest( adTagUrl: ViewController.AdTagURLString, adDisplayContainer: adDisplayContainer, contentPlayhead: contentPlayhead, userContext: nil) adsLoader.requestAds(with: request) } @objc func contentDidFinishPlaying(_ notification: Notification) { adsLoader.contentComplete() } }
7. Anzeigenlade-Delegierten einrichten
Bei einem erfolgreichen Ladeereignis ruft IMAAdsLoader
die Methode adsLoadedWithData
des zugewiesenen Delegaten auf und übergibt ihr eine Instanz von IMAAdsManager
. Anschließend können Sie den Anzeigenmanager initialisieren, über den die einzelnen Anzeigen gemäß der Antwort auf die Anzeigen-Tag-URL geladen werden.
Außerdem müssen Sie alle Fehler behandeln, die während des Ladevorgangs auftreten können. Wenn Anzeigen nicht geladen werden, muss die Medienwiedergabe ohne Anzeigen fortgesetzt werden, damit die Nutzererfahrung nicht beeinträchtigt wird.
ViewController.m
Objective-C
... @interface ViewController () <IMAAdsLoaderDelegate> @property(nonatomic) IMAAdsLoader *adsLoader; @property(nonatomic) IMAAdsManager *adsManager; @property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead; @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end @implementation ViewController ... - (void)setupAdsLoader { self.adsLoader = [[IMAAdsLoader alloc] init]; self.adsLoader.delegate = self; } ... #pragma mark - IMAAdsLoaderDelegate - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { // Initialize and listen to the ads manager loaded for this request. self.adsManager = adsLoadedData.adsManager; [self.adsManager initializeWithAdsRenderingSettings:nil]; } - (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData { // Fall back to playing content. NSLog(@"Error loading ads: %@", adErrorData.adError.message); [self.contentPlayerViewController.player play]; } @end
Swift
... class ViewController: UIViewController, IMAAdsLoaderDelegate { ... var adsLoader: IMAAdsLoader! var adsManager: IMAAdsManager! var contentPlayhead: IMAAVPlayerContentPlayhead? var playerViewController: AVPlayerViewController! ... func setUpAdsLoader() { adsLoader = IMAAdsLoader(settings: nil) adsLoader.delegate = self } ... // MARK: - IMAAdsLoaderDelegate func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) { adsManager = adsLoadedData.adsManager adsManager.initialize(with: nil) } func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) { print("Error loading ads: " + adErrorData.adError.message) showContentPlayer() playerViewController.player?.play() } }
8. Ad Manager-Delegierten einrichten
Außerdem benötigt der Anzeigenmanager einen eigenen Bevollmächtigten, um Ereignisse und Statusänderungen zu verwalten. Der IMAAdManagerDelegate
bietet Methoden zum Umgang mit Anzeigenereignissen und -fehlern sowie zum Starten und Pausieren der Videoinhalte.
Wiedergabe starten
Es gibt viele Ereignisse, die mit der didReceiveAdEvent
-Methode verarbeitet werden können. In diesem einfachen Beispiel wird jedoch nur das Ereignis LOADED
überwacht, um dem Anzeigenmanager zu signalisieren, dass die Wiedergabe von Inhalten und Anzeigen gestartet werden soll.
ViewController.m
Objective-C
@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate> ... - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { // Initialize and listen to the ads manager loaded for this request. self.adsManager = adsLoadedData.adsManager; self.adsManager.delegate = self; [self.adsManager initializeWithAdsRenderingSettings:nil]; } ... #pragma mark - IMAAdsManagerDelegate - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event { // Play each ad once it has loaded. if (event.type == kIMAAdEvent_LOADED) { [adsManager start]; } } ...
Swift
... class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { ... func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) { // Grab the instance of the IMAAdsManager and set yourself as the delegate. adsManager = adsLoadedData.adsManager adsManager.delegate = self adsManager.initialize(with: nil) } ... // MARK: - IMAAdsManagerDelegate func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) { // Play each ad once it has been loaded if event.type == IMAAdEventType.LOADED { adsManager.start() } } ...
Fehlerbehebung
Fügen Sie auch einen Handler für Anzeigenfehler hinzu. Wenn ein Fehler auftritt, fahren Sie wie im vorherigen Schritt fort.
ViewController.m
Objective-C
... - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error { // Fall back to playing content. NSLog(@"AdsManager error: %@", error.message); [self showContentPlayer]; [self.contentPlayerViewController.player play]; } @end
Swift
... func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) { // Fall back to playing content print("AdsManager error: " + error.message) showContentPlayer() playerViewController.player?.play() }
Wiedergabe- und Pausenereignisse auslösen
Mit den letzten beiden Delegationsmethoden, die Sie implementieren müssen, werden für den zugrunde liegenden Videocontent Wiedergabe- und Pausenereignisse ausgelöst, wenn dies vom IMA SDK angefordert wird. Wenn die Videowiedergabe auf Wunsch pausiert und fortgesetzt wird, verpasst der Nutzer keine Teile des Videocontents, wenn Anzeigen eingeblendet werden.
ViewController.m
Objective-C
... - (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager { // Pause the content for the SDK to play ads. [self.contentPlayerViewController.player pause]; [self hideContentPlayer]; } - (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager { // Resume the content since the SDK is done playing ads (at least for now). [self showContentPlayer]; [self.contentPlayerViewController.player play]; } @end
Swift
... func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) { // Pause the content for the SDK to play ads. playerViewController.player?.pause() hideContentPlayer() } func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) { // Resume the content since the SDK is done playing ads (at least for now). showContentPlayer() playerViewController.player?.play() } }
Fertig! Sie fordern jetzt Anzeigen über das IMA SDK an und schalten sie. Informationen zu zusätzlichen SDK-Funktionen finden Sie in den anderen Leitfäden oder in den Beispielen auf GitHub.
Nächste Schritte
Wenn Sie die Werbeeinnahmen auf der tvOS-Plattform maximieren möchten, fordern Sie die Berechtigung „App-Transparenz und -Tracking“ zur Verwendung von IDFA an.