Configurar o SDK do IMA

Selecione a plataforma: HTML5 Android iOS tvOS

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:

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.

  1. No Xcode, instale o pacote Swift do SDK do IMA acessando Arquivo > Adicionar pacotes….

  2. 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-tvos
    
  3. Selecione 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:

  1. 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'
    end
    
    
  2. No diretório que contém o Podfile, execute pod install --repo-update

  3. Para 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.