Pakiety IMA SDK ułatwiają integrację reklam multimedialnych z witrynami i aplikacjami. Pakiety IMA SDK mogą wysyłać żądania reklam do dowolnego serwera reklam zgodnego z VAST i zarządzać odtwarzaniem reklam w aplikacjach. Dzięki pakietom IMA SDK po stronie klienta zachowujesz kontrolę nad odtwarzaniem treści wideo, a pakiet SDK obsługuje odtwarzanie reklam. Reklamy są odtwarzane w osobnym odtwarzaczu wideo umieszczonym nad odtwarzaczem wideo z treściami aplikacji.
W tym przewodniku pokazujemy, jak zintegrować pakiet IMA SDK z prostą aplikacją odtwarzacza wideo. Jeśli chcesz zobaczyć gotową przykładową integrację lub z niej skorzystać, pobierz BasicExample z GitHub.
Omówienie IMA po stronie klienta
Wdrażanie pakietu IMA SDK po stronie klienta obejmuje 4 główne komponenty SDK, które są opisane w tym przewodniku:
IMAAdDisplayContainer
: obiekt kontenera, który określa, gdzie IMA renderuje elementy interfejsu reklamy i mierzy widoczność, w tym Widok aktywny i Open Measurement.IMAAdsLoader
: obiekt, który wysyła żądania reklam i obsługuje zdarzenia z odpowiedzi na żądania reklam. Powinieneś utworzyć tylko jeden moduł wczytywania reklam, którego można używać przez cały okres działania aplikacji.IMAAdsRequest
: obiekt, który definiuje żądanie reklamy. Żądania reklam określają adres URL tagu reklamy VAST, a także dodatkowe parametry, takie jak wymiary reklamy.IMAAdsManager
: Obiekt, który zawiera odpowiedź na żądanie reklamy, kontroluje odtwarzanie reklam i nasłuchuje zdarzeń reklamowych wywoływanych przez pakiet SDK.
Wymagania wstępne
Zanim zaczniesz, musisz mieć:
- Xcode 13 lub nowszy
- CocoaPods (zalecane), Swift Package Manager lub pobrana kopia pakietu IMA SDK na tvOS
1. Tworzenie nowego projektu Xcode
W Xcode utwórz nowy projekt tvOS w języku Objective-C lub Swift. Użyj nazwy projektu BasicExample.
2. Dodawanie pakietu IMA SDK do projektu w Xcode
Instalowanie pakietu SDK za pomocą CocoaPods (zalecane)
CocoaPods to menedżer zależności dla projektów Xcode. Jest to zalecana metoda instalowania pakietu IMA SDK. Więcej informacji o instalowaniu i używaniu CocoaPods znajdziesz w dokumentacji CocoaPods. Po zainstalowaniu CocoaPods wykonaj te instrukcje, aby zainstalować pakiet IMA SDK:
W tym samym katalogu, w którym znajduje się plik BasicExample.xcodeproj, utwórz plik tekstowy o nazwie Podfile i dodaj tę konfigurację:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '14' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.15.1' end
W katalogu zawierającym plik Podfile uruchom
pod install --repo-update
Sprawdź, czy instalacja się powiodła. W tym celu otwórz plik BasicExample.xcworkspace i upewnij się, że zawiera 2 projekty: BasicExample i Pods (zależności zainstalowane przez CocoaPods).
Instalowanie pakietu SDK za pomocą menedżera pakietów Swift
Pakiet SDK do wyświetlania interaktywnych reklam medialnych obsługuje Swift Package Manager od wersji 4.8.2. Aby zaimportować pakiet Swift, wykonaj czynności opisane poniżej.
W Xcode zainstaluj pakiet IMA SDK Swift, klikając File > Add Packages... (Plik > Dodaj pakiety...).
W wyświetlonym oknie wyszukaj repozytorium pakietu IMA SDK Swift Package GitHub:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
Wybierz wersję pakietu IMA SDK Swift Package, której chcesz używać. W przypadku nowych projektów zalecamy używanie opcji Do następnej wersji głównej.
Gdy skończysz, Xcode przetworzy zależności pakietu i pobierze je w tle. Więcej informacji o dodawaniu zależności pakietów znajdziesz w artykule Apple.
Ręczne pobieranie i instalowanie pakietu SDK
Jeśli nie chcesz używać CocoaPods, możesz pobrać pakiet IMA SDK i dodać go ręcznie do projektu.
3. Tworzenie prostego odtwarzacza wideo
Najpierw wdróż podstawowy odtwarzacz wideo. Początkowo ten odtwarzacz nie korzysta z pakietu IMA SDK i nie zawiera jeszcze żadnej metody wywoływania odtwarzania.
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. Zaimportuj pakiet IMA SDK
Następnie dodaj platformę IMA za pomocą instrukcji importu pod istniejącymi importami.
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. Wdrożenie narzędzia do śledzenia pozycji odtwarzania treści i obserwatora końca transmisji
Aby odtwarzać reklamy w trakcie filmu, pakiet IMA SDK musi śledzić bieżącą pozycję treści wideo. Aby to zrobić, utwórz klasę, która implementuje interfejs IMAContentPlayhead
. Jeśli używasz AVPlayer
, jak pokazano w tym przykładzie, pakiet SDK udostępnia klasę IMAAVPlayerContentPlayhead
, która wykonuje to za Ciebie.
Jeśli nie używasz AVPlayer
, musisz zaimplementować IMAContentPlayhead
w klasie własnej.
Musisz też poinformować pakiet SDK, kiedy odtwarzanie treści się zakończy, aby mógł wyświetlić reklamy po filmie. W tym celu wywołaj funkcję contentComplete
na obiekcie IMAAdsLoader
, używając AVPlayerItemDidPlayToEndTimeNotification
.
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. Zainicjuj moduł wczytywania reklam i wyślij żądanie reklamy
Aby poprosić o zestaw reklam, musisz utworzyć instancję IMAAdsLoader
.
Ten moduł wczytujący może służyć do przetwarzania obiektów IMAAdsRequest
powiązanych z określonym adresem URL tagu reklamy.
Zalecamy utrzymywanie tylko 1 instancji IMAAdsLoader
przez cały cykl życia aplikacji. Aby wysłać dodatkowe żądania reklamy, utwórz nowy obiekt IMAAdsRequest
, ale użyj tego samego obiektu IMAAdsLoader
. Więcej informacji znajdziesz w odpowiedziach na najczęstsze pytania dotyczące pakietu 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&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&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. Konfigurowanie delegata modułu wczytywania reklam
Po pomyślnym załadowaniu zdarzenia IMAAdsLoader
wywołuje metodę adsLoadedWithData
przypisanego delegata, przekazując mu instancję IMAAdsManager
. Następnie możesz zainicjować menedżera reklam, który wczytuje poszczególne reklamy zgodnie z odpowiedzią na adres URL tagu reklamy.
Pamiętaj też, aby obsługiwać wszelkie błędy, które mogą wystąpić podczas wczytywania. Jeśli reklamy się nie ładują, upewnij się, że odtwarzanie multimediów jest kontynuowane bez reklam, aby nie zakłócać wrażeń użytkownika.
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. Konfigurowanie delegata menedżera reklam
Na koniec, aby zarządzać zdarzeniami i zmianami stanu, menedżer reklam potrzebuje własnego delegata. Interfejs IMAAdManagerDelegate
ma metody obsługi zdarzeń i błędów związanych z reklamami, a także metody uruchamiania i wstrzymywania odtwarzania treści wideo.
Rozpoczynanie odtwarzania
Metoda didReceiveAdEvent
może obsługiwać wiele zdarzeń, ale w tym podstawowym przykładzie wystarczy nasłuchiwać zdarzenia LOADED
, aby poinformować menedżera reklam o rozpoczęciu odtwarzania treści i reklam.
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() } } ...
Obsługa błędów
Dodaj też moduł obsługi błędów reklam. Jeśli wystąpi błąd, tak jak w poprzednim kroku, wznow odtwarzanie treści.
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() }
Wywoływanie zdarzeń odtwarzania i wstrzymywania
Ostatnie 2 metody delegowania, które musisz zaimplementować, służą do wywoływania zdarzeń odtwarzania i wstrzymywania w bazowych treściach wideo, gdy zażąda tego pakiet IMA SDK. Wstrzymywanie i odtwarzanie na żądanie zapobiega pomijaniu przez użytkownika fragmentów treści wideo podczas wyświetlania reklam.
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() } }
Znakomicie. Żądania reklam i ich wyświetlanie odbywa się teraz za pomocą pakietu IMA SDK. Więcej informacji o dodatkowych funkcjach pakietu SDK znajdziesz w innych przewodnikach lub przykładach w GitHubie.
Następne kroki
Aby zmaksymalizować przychody z reklam na platformie tvOS, poproś o uprawnienia do przejrzystości i śledzenia aplikacji, aby używać identyfikatora IDFA.