начали монетизировать свой видеоконтент с помощью рекламы.
Пакеты IMA SDK упрощают интеграцию мультимедийной рекламы в ваши веб-сайты и приложения. Пакеты IMA SDK могут запрашивать рекламу с любого рекламного сервера , совместимого с VAST, и управлять её воспроизведением в ваших приложениях. Клиентские пакеты IMA SDK позволяют вам контролировать воспроизведение видеоконтента, в то время как SDK управляет воспроизведением рекламы. Реклама воспроизводится в отдельном видеоплеере, расположенном поверх видеоплеера приложения.
В этом руководстве показано, как интегрировать IMA SDK в простое приложение видеоплеера. Если вы хотите просмотреть готовый пример интеграции или следовать ему, скачайте BasicExample с GitHub.
Обзор клиентской части IMA
Реализация IMA на стороне клиента включает четыре основных компонента SDK, которые продемонстрированы в этом руководстве:
-
IMAAdDisplayContainer
: объект-контейнер, который указывает, где IMA отображает элементы пользовательского интерфейса рекламы и измеряет видимость, включая Active View и Open Measurement . -
IMAAdsLoader
: объект, который запрашивает рекламу и обрабатывает события, возникающие при ответах на запросы рекламы. Следует создать только один экземпляр загрузчика рекламы, который можно использовать повторно на протяжении всего жизненного цикла приложения. -
IMAAdsRequest
: объект, определяющий запрос на рекламу. Запросы на рекламу содержат URL-адрес тега VAST, а также дополнительные параметры, такие как размеры объявления. -
IMAAdsManager
: объект, который содержит ответ на запрос рекламы, управляет воспроизведением рекламы и прослушивает события рекламы, запускаемые SDK.
Предпосылки
Прежде чем начать, вам понадобится следующее:
- Xcode 13 или более поздняя версия
- CocoaPods (предпочтительно), Swift Package Manager или загруженная копия IMA SDK для iOS
1. Создайте новый проект Xcode.
В Xcode создайте новый iOS-проект на Objective-C или Swift. Используйте BasicExample в качестве имени проекта.
2. Добавьте IMA SDK в проект Xcode.
Установить SDK с помощью CocoaPods (рекомендуется)
CocoaPods — это менеджер зависимостей для проектов Xcode, рекомендуемый метод установки IMA SDK. Подробнее об установке и использовании CocoaPods см. в документации CocoaPods . После установки CocoaPods следуйте следующим инструкциям для установки IMA SDK:
В том же каталоге, где находится файл BasicExample.xcodeproj , создайте текстовый файл с именем Podfile и добавьте следующую конфигурацию:
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '14' target "BasicExample" do pod 'GoogleAds-IMA-iOS-SDK', '~> 3.26.1' end
Из каталога, содержащего Podfile, выполните команду
pod install --repo-update
Убедитесь, что установка прошла успешно, открыв файл BasicExample.xcworkspace и убедившись, что он содержит два проекта: BasicExample и Pods (зависимости, установленные CocoaPods).
Установите SDK с помощью Swift Package Manager
Interactive Media Ads SDK поддерживает Swift Package Manager, начиная с версии 3.18.4. Чтобы импортировать пакет Swift, выполните следующие действия.
В Xcode установите пакет IMA SDK Swift, перейдя в Файл > Добавить пакеты... .
В появившемся окне найдите репозиторий GitHub IMA SDK Swift Package:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios
Выберите нужную версию пакета IMA SDK Swift. Для новых проектов мы рекомендуем использовать версию Up to Next Major Version .
После завершения Xcode определит зависимости пакетов и загрузит их в фоновом режиме. Подробнее о добавлении зависимостей пакетов см. в статье Apple .
Загрузите и установите SDK вручную
Если вы не хотите использовать Swift Package Manager или CocoaPods, вы можете загрузить IMA SDK и вручную добавить его в свой проект.
3. Создайте простой видеоплеер
Для начала реализуем базовый видеоплеер. Изначально этот плеер не использует IMA SDK и пока не содержит методов для запуска воспроизведения.
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
Быстрый
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
Затем добавьте фреймворк IMA, используя оператор импорта под существующим импортом.
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";
Быстрый
import AVFoundation import GoogleInteractiveMediaAds import UIKit class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"
5. Реализуйте отслеживание точки воспроизведения контента и наблюдение за окончанием трансляции.
Для воспроизведения рекламы в середине ролика IMA SDK необходимо отслеживать текущее положение видеоконтента. Для этого создайте класс, реализующий IMAContentPlayhead
. Если вы используете AVPlayer
, как показано в этом примере, SDK предоставляет класс IMAAVPlayerContentPlayhead
, который делает это автоматически. Если вы не используете AVPlayer
, вам потребуется реализовать IMAContentPlayhead
в собственном классе.
Вам также необходимо сообщить SDK о завершении воспроизведения контента, чтобы он мог показывать рекламу после показа. Это делается вызовом contentComplete
в IMAAdsLoader
с использованием 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
Быстрый
... 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. Инициализируйте загрузчик рекламы и сделайте запрос на рекламу.
Чтобы запросить набор объявлений, необходимо создать экземпляр IMAAdsLoader
. Этот загрузчик можно использовать для обработки объектов IMAAdsRequest
, связанных с указанным URL-адресом тега объявления.
Рекомендуется поддерживать только один экземпляр IMAAdsLoader
на протяжении всего жизненного цикла приложения. Для дополнительных запросов рекламы создайте новый объект IMAAdsRequest
, но используйте тот же IMAAdsLoader
. Подробнее см. в разделе часто задаваемых вопросов по 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
Быстрый
... 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 our 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. Настройте делегата загрузчика рекламы
При успешной загрузке IMAAdsLoader
вызывает метод adsLoadedWithData
назначенного ему делегата, передавая ему экземпляр IMAAdsManager
. Затем можно инициализировать менеджер объявлений, который загружает отдельные объявления, как определено в ответе на URL-адрес тега объявления.
Кроме того, обязательно обработайте все ошибки, которые могут возникнуть во время загрузки. Если реклама не загружается, убедитесь, что воспроизведение медиафайлов продолжается без рекламы, чтобы не мешать пользователю.
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
Быстрый
... 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. Настройте делегата менеджера по рекламе
Наконец, для управления событиями и изменениями состояния менеджеру объявлений необходим собственный делегат. IMAAdManagerDelegate
содержит методы для обработки событий и ошибок рекламы, а также методы для запуска и приостановки воспроизведения видеоконтента.
Начало воспроизведения
Существует множество событий, для обработки которых можно использовать метод didReceiveAdEvent
, но в этом простом примере просто прослушивайте событие LOADED
, чтобы сообщить менеджеру объявлений о необходимости начать воспроизведение контента и рекламы.
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]; } } ...
Быстрый
... 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() } } ...
Обработка ошибок
Добавьте также обработчик ошибок рекламы. Если возникла ошибка, как на предыдущем шаге, возобновите воспроизведение контента.
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
Быстрый
... func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) { // Fall back to playing content print("AdsManager error: " + error.message) showContentPlayer() playerViewController.player?.play() }
Запуск событий воспроизведения и паузы
Последние два метода делегата, которые необходимо реализовать, используются для запуска событий воспроизведения и паузы базового видеоконтента по запросу IMA SDK. Запуск паузы и воспроизведения по запросу предотвращает пропуск пользователем фрагментов видеоконтента при показе рекламы.
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
Быстрый
... 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() } }
Вот и всё! Теперь вы запрашиваете и показываете рекламу с помощью IMA SDK. Чтобы узнать о дополнительных функциях SDK, ознакомьтесь с другими руководствами или примерами на GitHub .
Следующие шаги
Чтобы максимизировать доход от рекламы на платформе iOS, запросите разрешение на прозрачность и отслеживание приложений для использования IDFA .