Os SDKs do IMA facilitam a integração de anúncios multimídia aos seus sites e apps. Os SDKs do IMA podem solicitar anúncios de qualquer servidor de anúncios compatível com VAST e gerenciar a reprodução de anúncios nos seus apps. Com os SDKs do lado do cliente do IMA, você mantém o controle da reprodução de vídeo de conteúdo, enquanto o SDK processa a reprodução de anúncios. Os anúncios são veiculados em um player de vídeo separado, posicionado acima do player de vídeo de conteúdo do app.
Este guia demonstra como integrar o SDK do IMA a um app de player de vídeo. Se você quiser ver ou acompanhar um exemplo de integração concluída, baixe o BasicExample do GitHub.
Visão geral do lado do cliente da IMA
A implementação do IMA do lado do cliente envolve quatro componentes principais do SDK, que são demonstrados neste guia:
IMAAdDisplayContainer: um objeto contêiner que especifica onde a IMA renderiza elementos da interface do anúncio e mede a visibilidade, incluindo o Active View e a Medição aberta.IMAAdsLoader: um objeto que solicita anúncios e processa eventos de respostas de solicitação de anúncios. Você só deve instanciar um carregador de anúncios, que pode ser reutilizado durante toda a vida útil do aplicativo.IMAAdsRequest: um objeto que define uma solicitação de anúncio. As solicitações de anúncios especificam o URL da tag de anúncio VAST e outros parâmetros, como dimensões do anúncio.IMAAdsManager: um objeto que contém a resposta à solicitação de anúncios, controla a reprodução de anúncios e detecta eventos de anúncio acionados pelo SDK.
Pré-requisitos
Antes de começar, os seguintes itens são necessários:
- Xcode 13 ou mais recente
- Gerenciador de pacotes do Swift, CocoaPods ou uma cópia baixada do SDK da IMA para tvOS
1. Criar um projeto do Xcode
No Xcode, crie um projeto do tvOS usando Objective-C ou Swift. Use BasicExample como o nome do projeto.
2. Adicionar o SDK do IMA ao projeto do Xcode
Instalar o SDK do IMA usando o Gerenciador de pacotes do Swift
O SDK do Interactive Media Ads é compatível com o Gerenciador de pacotes do Swift a partir da versão 4.8.2. Siga estas etapas para importar o pacote Swift.
No Xcode, instale o pacote Swift do SDK do IMA acessando Arquivo > Adicionar pacotes….
No comando que aparece, pesquise o repositório do GitHub do pacote Swift do SDK do IMA:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvosSelecione a versão do pacote Swift do SDK do IMA que você quer usar. Para novos projetos, recomendamos usar a opção Up to Next Major Version.
Depois disso, o Xcode resolve as dependências do pacote e faz o download delas em segundo plano. Para mais detalhes sobre como adicionar dependências de pacotes, consulte o artigo da Apple.
Instalar o SDK do IMA usando o CocoaPods
Para instalar o SDK do IMA, use o CocoaPods. Para mais informações sobre a instalação ou o uso do CocoaPods, consulte a documentação do CocoaPods. Depois de instalar o CocoaPods, faça o seguinte:
No mesmo diretório do arquivo BasicExample.xcodeproj, crie um arquivo de texto chamado Podfile e adicione a seguinte configuração:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '15' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.16.0' endNo diretório que contém o Podfile, execute
pod install --repo-updatePara verificar se a instalação foi bem-sucedida, abra o arquivo BasicExample.xcworkspace e confirme se ele contém dois projetos: BasicExample e Pods (as dependências instaladas pelo CocoaPods).
Fazer o download e instalar manualmente o SDK do IMA
Se você não quiser usar o CocoaPods, faça o download do SDK do IMA e adicione-o manualmente ao seu projeto.
3. Importar o SDK do IMA
Adicione o framework da IMA usando uma instrução de importação.
Objective-C
#import "ViewController.h"
#import <AVKit/AVKit.h>
@import GoogleInteractiveMediaAds;
Swift
import AVFoundation
import GoogleInteractiveMediaAds
import UIKit
4. Criar um player de vídeo e integrar o SDK do IMA
O exemplo a seguir inicializa o SDK do IMA:
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 () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdDisplayContainer *adDisplayContainer;
@property(nonatomic) IMAAdsManager *adsManager;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@property(nonatomic, getter=isAdBreakActive) BOOL adBreakActive;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self setupAdsLoader];
[self setupContentPlayer];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self requestAds];
}
// 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 resume events from the
// remote and play content underneath the ad.
[self.contentPlayerViewController willMoveToParentViewController:nil];
[self.contentPlayerViewController.view removeFromSuperview];
[self.contentPlayerViewController removeFromParentViewController];
}
Swift
class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
static let contentURLString =
"https://devstreaming-cdn.apple.com/videos/streaming/examples/"
+ "img_bipbop_adv_example_fmp4/master.m3u8"
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 adDisplayContainer: IMAAdDisplayContainer!
var adsManager: IMAAdsManager!
var contentPlayhead: IMAAVPlayerContentPlayhead?
var playerViewController: AVPlayerViewController!
var adBreakActive = false
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.black
setUpContentPlayer()
setUpAdsLoader()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
requestAds()
}
Neste exemplo, viewDidLoad() inicializa o IMAAdsLoader, e
viewDidAppear() solicita anúncios assim que a visualização fica visível. Os métodos auxiliares
showContentPlayer() e hideContentPlayer() alternam a visibilidade do conteúdo durante a
reprodução de anúncios.
Este exemplo usa a variável constante adTagURLString para definir a tag de anúncio VAST da solicitação de anúncio e os seguintes componentes para gerenciar o SDK do IMA:
adsLoader: processa solicitações e respostas de anúncios. Recomendamos usar uma única instância para o ciclo de vida do app.adDisplayContainer: especifica a visualização para renderizar anúncios.adsManager: gerencia a reprodução de anúncios e detecta eventos de anúncios.contentPlayhead: acompanha o progresso do conteúdo para acionar intervalos de anúncio intermediário.adBreakActive: indica se uma pausa para anúncio está sendo veiculada para evitar a busca sobre anúncios.
5. Implementar o rastreador de cabeça de reprodução de conteúdo e o observador de fim de stream
Para veicular anúncios intermediários, o SDK do IMA precisa rastrear a posição atual
do conteúdo de vídeo. Para fazer isso, crie uma classe que implemente
IMAContentPlayhead. Se você estiver usando um AVPlayer, como mostrado neste exemplo, o SDK vai fornecer a classe IMAAVPlayerContentPlayhead, que faz isso por você.
Se você não estiver usando AVPlayer, implemente IMAContentPlayhead em
uma classe própria.
Objective-C
- (void)setupContentPlayer {
// Create a content video player. Create a playhead to track content progress so the SDK knows
// when to play ads in a VMAP playlist.
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];
}
Swift
func setUpContentPlayer() {
// Load AVPlayer with path to our content.
let contentURL = URL(string: ViewController.contentURLString)!
let player = AVPlayer(url: contentURL)
playerViewController = AVPlayerViewController()
playerViewController.player = player
// Set up our 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()
}
Você também precisa informar ao SDK quando o conteúdo terminar de ser reproduzido para que ele possa
mostrar anúncios pós-vídeo. Para isso, chame contentComplete na
IMAAdsLoader usando AVPlayerItemDidPlayToEndTimeNotification.
Objective-C
- (void)contentDidFinishPlaying:(NSNotification *)notification {
// Notify the SDK that the postrolls should be played.
[self.adsLoader contentComplete];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Swift
@objc func contentDidFinishPlaying(_ notification: Notification) {
adsLoader.contentComplete()
}
6. Inicializar o carregador de anúncios e fazer uma solicitação de anúncios
Para solicitar um conjunto de anúncios, crie uma instância de IMAAdsLoader.
Esse carregador pode ser usado para processar objetos IMAAdsRequest associados a um
URL de tag de anúncio especificado.
Como prática recomendada, mantenha apenas uma instância de IMAAdsLoader durante todo o ciclo de vida do app. Para fazer outras solicitações de anúncio, crie um novo objeto IMAAdsRequest, mas reutilize o mesmo IMAAdsLoader. Para mais informações, consulte as Perguntas frequentes sobre o SDK do IMA.
Objective-C
- (void)setupAdsLoader {
self.adsLoader = [[IMAAdsLoader alloc] init];
self.adsLoader.delegate = self;
}
- (void)requestAds {
// Pass the main view as the container for ad display.
self.adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view
viewController:self];
IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString
adDisplayContainer:self.adDisplayContainer
contentPlayhead:self.contentPlayhead
userContext:nil];
[self.adsLoader requestAdsWithRequest:request];
}
Swift
func setUpAdsLoader() {
adsLoader = IMAAdsLoader(settings: nil)
adsLoader.delegate = self
}
func requestAds() {
// Create ad display container for ad rendering.
adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view, viewController: self)
// 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)
}
7. Configurar um delegado do carregador de anúncios
Em um evento de carregamento bem-sucedido, o IMAAdsLoader chama o método adsLoadedWithData do delegado atribuído, transmitindo uma instância de IMAAdsManager. Em seguida, você pode inicializar o gerenciador de anúncios, que carrega os anúncios individuais, conforme definido pela resposta ao URL da tag de anúncio.
Além disso, processe os erros que possam ocorrer durante o processo de carregamento. Se os anúncios não carregarem, verifique se a reprodução de mídia continua sem anúncios para não interferir na experiência do usuário.
Objective-C
#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.delegate = self;
[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];
}
Swift
func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
// Grab the instance of the IMAAdsManager and set ourselves as the delegate.
adsManager = adsLoadedData.adsManager
adsManager.delegate = self
adsManager.initialize(with: nil)
}
func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
print("Error loading ads: \(adErrorData.adError.message ?? "No error message available.")")
showContentPlayer()
playerViewController.player?.play()
}
8. Configurar um delegado do gerenciador de anúncios
Por fim, para gerenciar eventos e mudanças de estado, o gerenciador de anúncios precisa de um delegado próprio. O IMAAdManagerDelegate tem métodos para processar eventos e erros de anúncios,
além de métodos para acionar a reprodução e a pausa no conteúdo de vídeo.
Iniciando a reprodução
Há muitos eventos que podem ser processados com o método didReceiveAdEvent.
Neste exemplo básico, fique atento ao evento LOADED para informar ao gerenciador de anúncios que inicie a reprodução de conteúdo e anúncios. O SDK da IMA aciona o evento
ICON_FALLBACK_IMAGE_CLOSED quando o usuário fecha uma caixa de diálogo
de substituição de ícone depois de tocar em um ícone. Depois disso, a reprodução do anúncio é retomada.
Objective-C
#pragma mark - IMAAdsManagerDelegate
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
switch (event.type) {
case kIMAAdEvent_LOADED: {
// Play each ad once it has loaded.
[adsManager start];
break;
}
case kIMAAdEvent_ICON_FALLBACK_IMAGE_CLOSED: {
// Resume ad after user has closed dialog.
[adsManager resume];
break;
}
default:
break;
}
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
switch event.type {
case IMAAdEventType.LOADED:
// Play each ad once it has been loaded.
adsManager.start()
case IMAAdEventType.ICON_FALLBACK_IMAGE_CLOSED:
// Resume playback after the user has closed the dialog.
adsManager.resume()
default:
break
}
}
Como processar os erros
Adicione também um handler para erros de anúncio. Se ocorrer um erro, como na etapa anterior, retome a reprodução do conteúdo.
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];
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) {
// Fall back to playing content
print("AdsManager error: \(error.message ?? "No error message available.")")
showContentPlayer()
playerViewController.player?.play()
}
Acionar eventos de abrir e pausar
Os dois últimos métodos delegados que você precisa implementar são usados para acionar eventos de reprodução e pausa no conteúdo de vídeo subjacente, quando solicitado pelo SDK do IMA. Acionar a pausa e a reprodução quando solicitado evita que o usuário perca partes do conteúdo de vídeo quando os anúncios são exibidos.
Objective-C
- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
// Pause the content for the SDK to play ads.
[self.contentPlayerViewController.player pause];
[self hideContentPlayer];
// Trigger an update to send focus to the ad display container.
self.adBreakActive = YES;
[self setNeedsFocusUpdate];
}
- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
// Resume the content since the SDK is done playing ads (at least for now).
[self showContentPlayer];
[self.contentPlayerViewController.player play];
// Trigger an update to send focus to the content player.
self.adBreakActive = NO;
[self setNeedsFocusUpdate];
}
Swift
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
// Pause the content for the SDK to play ads.
playerViewController.player?.pause()
hideContentPlayer()
// Trigger an update to send focus to the ad display container.
adBreakActive = true
setNeedsFocusUpdate()
}
func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) {
// Resume the content since the SDK is done playing ads (at least for now).
showContentPlayer()
playerViewController.player?.play()
// Trigger an update to send focus to the content player.
adBreakActive = false
setNeedsFocusUpdate()
}
Pronto! Agora você está solicitando e mostrando anúncios com o SDK do IMA. Para saber mais sobre outros recursos do SDK, consulte os outros guias ou os exemplos no GitHub.
Próximas etapas
Para maximizar a receita de publicidade na plataforma tvOS, solicite a permissão de transparência e rastreamento de apps para usar o IDFA.