IMA SDK облегчают интеграцию мультимедийной рекламы в ваши веб-сайты и приложения. IMA SDK могут запрашивать рекламу с любого совместимого с VAST сервера объявлений и управлять воспроизведением рекламы в ваших приложениях. С клиентскими SDK IMA вы сохраняете контроль над воспроизведением видеоконтента, в то время как 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
. Для получения дополнительной информации см. 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&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 .