IMA SDK memudahkan integrasi iklan multimedia ke dalam situs dan aplikasi Anda. IMA SDK dapat meminta iklan dari server iklan yang sesuai dengan VAST dan mengelola pemutaran iklan di aplikasi Anda. Dengan SDK sisi klien IMA, Anda mempertahankan kontrol pemutaran video konten, sementara SDK menangani pemutaran iklan. Iklan diputar di pemutar video terpisah yang diposisikan di atas pemutar video konten aplikasi.
Panduan ini menunjukkan cara mengintegrasikan IMA SDK ke dalam aplikasi pemutar video sederhana. Jika Anda ingin melihat atau mengikuti integrasi contoh yang telah selesai, download BasicExample dari GitHub.
Ringkasan sisi klien IMA
Mengimplementasikan sisi klien IMA melibatkan empat komponen SDK utama, yang didemonstrasikan dalam panduan ini:
IMAAdDisplayContainer
: Objek penampung tempat iklan dirender.IMAAdsLoader
: Objek yang meminta iklan dan menangani peristiwa dari respons permintaan iklan. Anda hanya boleh membuat instance satu loader iklan, yang dapat digunakan kembali selama masa aktif aplikasi.IMAAdsRequest
: Objek yang menentukan permintaan iklan. Permintaan iklan menentukan URL untuk tag iklan VAST, serta parameter tambahan, seperti dimensi iklan.IMAAdsManager
: Objek yang berisi respons terhadap permintaan iklan, mengontrol pemutaran iklan, dan memproses peristiwa iklan yang diaktifkan oleh SDK.
Prasyarat
Sebelum memulai, Anda memerlukan hal berikut:
- Xcode 13 atau yang lebih baru
- CocoaPods (lebih disukai), Swift Package Manager, atau salinan IMA SDK untuk tvOS yang didownload
1. Membuat project Xcode baru
Di Xcode, buat project tvOS baru menggunakan Objective-C atau Swift. Gunakan BasicExample sebagai nama project.
2. Menambahkan IMA SDK ke project Xcode
Menginstal SDK menggunakan CocoaPods (lebih disarankan)
CocoaPods adalah pengelola dependensi untuk project Xcode dan merupakan metode yang direkomendasikan untuk menginstal IMA SDK. Untuk informasi selengkapnya tentang cara menginstal atau menggunakan CocoaPods, lihat dokumentasi CocoaPods. Setelah menginstal CocoaPods, gunakan petunjuk berikut untuk menginstal IMA SDK:
Di direktori yang sama dengan file BasicExample.xcodeproj, buat file teks bernama Podfile, lalu tambahkan konfigurasi berikut:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '14' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.13.0' end
Dari direktori yang berisi Podfile, jalankan
pod install --repo-update
Verifikasi bahwa penginstalan berhasil dengan membuka file BasicExample.xcworkspace dan mengonfirmasi bahwa file tersebut berisi dua project: BasicExample dan Pods (dependensi yang diinstal oleh CocoaPods).
Menginstal SDK menggunakan Swift Package Manager
Interactive Media Ads SDK mendukung Swift Package Manager mulai versi 4.8.2. Ikuti langkah-langkah di bawah untuk mengimpor paket Swift.
Di Xcode, instal Paket Swift IMA SDK dengan membuka File > Add Packages....
Pada perintah yang muncul, telusuri repositori GitHub Paket Swift IMA SDK:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
Pilih versi Paket Swift IMA SDK yang ingin Anda gunakan. Untuk project baru, sebaiknya gunakan Sampai Versi Utama Berikutnya.
Setelah selesai, Xcode akan me-resolve dependensi paket Anda dan mendownloadnya di latar belakang. Untuk mengetahui detail selengkapnya tentang cara menambahkan dependensi paket, lihat artikel Apple.
Mendownload dan menginstal SDK secara manual
Jika tidak ingin menggunakan CocoaPods, Anda dapat mendownload IMA SDK dan menambahkannya secara manual ke project.
3. Membuat pemutar video sederhana
Pertama, terapkan pemutar video dasar. Awalnya, pemutar ini tidak menggunakan IMA SDK dan belum berisi metode apa pun untuk memicu pemutaran.
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. Mengimpor IMA SDK
Selanjutnya, tambahkan framework IMA menggunakan pernyataan impor di bawah impor yang ada.
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. Mengimplementasikan pelacak playhead konten dan observer akhir streaming
Untuk memutar iklan mid-roll, IMA SDK perlu melacak posisi konten video Anda saat ini. Untuk melakukannya, buat class yang mengimplementasikan
IMAContentPlayhead
. Jika Anda menggunakan AVPlayer
, seperti yang ditunjukkan dalam contoh ini,
SDK akan menyediakan class IMAAVPlayerContentPlayhead
yang melakukannya untuk Anda.
Jika tidak menggunakan AVPlayer
, Anda harus mengimplementasikan IMAContentPlayhead
di
class Anda sendiri.
Anda juga perlu memberi tahu SDK saat konten selesai diputar agar dapat
menampilkan iklan post-roll. Hal ini dilakukan dengan memanggil contentComplete
di
IMAAdsLoader
, menggunakan 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. Melakukan inisialisasi loader iklan dan membuat permintaan iklan
Untuk meminta kumpulan iklan, Anda perlu membuat instance IMAAdsLoader
.
Loader ini dapat digunakan untuk memproses objek IMAAdsRequest
yang terkait dengan URL tag iklan yang ditentukan.
Sebagai praktik terbaik, hanya pertahankan satu instance IMAAdsLoader
untuk seluruh
siklus proses aplikasi Anda. Untuk membuat permintaan iklan tambahan, buat objek
IMAAdsRequest
baru, tetapi gunakan kembali IMAAdsLoader
yang sama. Untuk informasi
selengkapnya, lihat FAQ 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. Menyiapkan delegasi loader iklan
Pada peristiwa pemuatan yang berhasil, IMAAdsLoader
memanggil metode adsLoadedWithData
dari delegasi yang ditetapkan, dengan meneruskan instance IMAAdsManager
. Kemudian, Anda
dapat melakukan inisialisasi pengelola iklan, yang memuat setiap iklan, seperti yang ditentukan
oleh respons terhadap URL tag iklan.
Selain itu, pastikan untuk menangani error apa pun yang mungkin terjadi selama proses pemuatan. Jika iklan tidak dimuat, pastikan pemutaran media berlanjut, tanpa iklan, agar tidak mengganggu pengalaman pengguna.
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. Menyiapkan delegasi Ad Manager
Terakhir, untuk mengelola peristiwa dan perubahan status, pengelola iklan memerlukan delegasi
sendiri. IMAAdManagerDelegate
memiliki metode untuk menangani peristiwa dan error iklan,
serta metode untuk memicu pemutaran dan jeda pada konten video Anda.
Memulai pemutaran
Ada banyak peristiwa yang dapat ditangani dengan metode didReceiveAdEvent
,
tetapi untuk contoh dasar ini, cukup dengarkan peristiwa LOADED
untuk memberi tahu pengelola
iklan agar memulai pemutaran konten dan iklan.
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() } } ...
Menangani error
Tambahkan juga pengendali untuk error iklan. Jika terjadi error, seperti pada langkah sebelumnya, lanjutkan pemutaran konten.
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() }
Memicu peristiwa putar dan jeda
Dua metode delegasi terakhir yang perlu Anda terapkan digunakan untuk memicu peristiwa putar dan jeda pada konten video yang mendasarinya, saat diminta oleh IMA SDK. Memicu jeda dan putar saat diminta akan mencegah pengguna melewatkan bagian konten video saat iklan ditampilkan.
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() } }
Selesai. Sekarang Anda meminta dan menampilkan iklan dengan IMA SDK. Untuk mempelajari fitur SDK tambahan, lihat panduan lain atau contoh di GitHub.
Langkah Berikutnya
Untuk memaksimalkan pendapatan iklan di platform tvOS, minta izin App Transparency dan Tracking untuk menggunakan IDFA.