Começar

Com os SDKs do IMA, é fácil integrar anúncios multimídia aos seus sites e apps. Os SDKs do IMA podem solicitar anúncios de qualquer servidor compatível com VAST e gerenciar a reprodução de anúncios nos seus apps. Com os SDKs do IMA no lado do cliente, você controla a reprodução do conteúdo de vídeo, enquanto o SDK processa a reprodução dos anúncios. Os anúncios são reproduzidos em um player de vídeo separado, posicionado na parte superior do player de vídeo do conteúdo do app.

Este guia demonstra como integrar o SDK do IMA a um app de player de vídeo simples. Se você quiser visualizar ou acompanhar um exemplo de integração completo, faça o download do BasicExample no GitHub.

Visão geral do cliente do IMA

A implementação do IMA no lado do cliente envolve quatro componentes principais do SDK, que são demonstrados neste guia:

  • IMAAdDisplayContainer: um objeto de contêiner em que os anúncios são renderizados.
  • IMAAdsLoader: um objeto que solicita anúncios e processa eventos das respostas às solicitações de anúncios. Instancie apenas 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úncios. As solicitações de anúncios especificam o URL da tag de anúncio VAST, bem como outros parâmetros, como as 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 disparados pelo SDK.

Pré-requisitos

Antes de começar, os seguintes itens são necessários:

  • Xcode 13 ou mais recente
  • CocoaPods (preferencial), Gerenciador de pacotes do Swift ou uma cópia transferida por download do SDK do IMA para tvOS (em inglês)

1. Criar um novo projeto do Xcode

No Xcode, crie um novo projeto 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 usando CocoaPods (preferencial)

O CocoaPods é um gerenciador de dependências para projetos do Xcode e é o método recomendado para instalar o SDK do IMA. Para mais informações sobre como instalar ou usar o CocoaPods, consulte a documentação dele. Depois de instalar o CocoaPods, use as instruções a seguir para instalar o SDK do IMA:

  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, '14'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.13.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).

Instalar o SDK 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 as etapas abaixo para importar o pacote Swift.

  1. No Xcode, instale o pacote Swift do SDK do IMA acessando File > Add Packages....

  2. No prompt exibido, 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 Próxima versão principal.

Quando terminar, o Xcode vai resolver as dependências do pacote e fazer o download delas em segundo plano. Para ver mais detalhes sobre como adicionar dependências de pacote, consulte o artigo da Apple.

Como fazer o download e a instalação manual do SDK

Se você não quiser usar o CocoaPods, faça o download do SDK do IMA e adicione-o manualmente ao seu projeto.

3. Criar um player de vídeo simples

Primeiro, implemente um player de vídeo básico. Inicialmente, esse player não usa o SDK do IMA e ainda não contém nenhum método para acionar a reprodução.

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. Importar o SDK do IMA

Em seguida, adicione o framework do IMA usando uma instrução de importação abaixo das importações atuais.

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. Implementar um rastreador de marcador de conteúdo e observador de fim de transmissão

Para reproduzir anúncios intermediários, o SDK do IMA precisa rastrear a posição atual do conteúdo em vídeo. Para fazer isso, crie uma classe que implemente IMAContentPlayhead. Se você estiver usando um AVPlayer, como mostrado nesse exemplo, o SDK fornecerá a classe IMAAVPlayerContentPlayhead, que faz isso por você. Se você não estiver usando AVPlayer, implemente IMAContentPlayhead em uma classe própria.

Você também precisa informar ao SDK quando a reprodução do conteúdo terminar para que ele possa exibir anúncios finais. Para fazer isso, chame contentComplete no IMAAdsLoader usando 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. Inicializar o carregador de anúncios e fazer uma solicitação de anúncios

Para solicitar um conjunto de anúncios, você precisa criar 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úncios, crie um novo objeto IMAAdsRequest, mas reutilize o mesmo IMAAdsLoader. Para mais informações, consulte as Perguntas frequentes sobre o SDK do IMA.

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. 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, resolva quaisquer 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.

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. Configurar um delegado do gerenciador de anúncios

Por fim, para gerenciar eventos e alterações de estado, o gerenciador de anúncios precisa de um delegado próprio. O IMAAdManagerDelegate tem métodos para processar erros e eventos de anúncios, além de métodos para acionar a reprodução e pausa do conteúdo em vídeo.

Iniciando a reprodução

Há muitos eventos que podem ser usados com o método didReceiveAdEvent. No entanto, neste exemplo básico, basta detectar o evento LOADED para instruir o gerenciador de anúncios a iniciar a reprodução do conteúdo e dos anúncios.

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()
    }
  }

...
      

Como processar os erros

Adicione também um gerenciador para os erros do anúncio. Se ocorrer um erro, como na etapa anterior, retome a reprodução do conteúdo.

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()
  }
      

Como acionar eventos de reprodução e pausa

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 solicitados pelo SDK do IMA. Acionar a pausa e a reprodução quando solicitado impede que o usuário perca partes do conteúdo de vídeo quando os anúncios são exibidos.

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()
  }
}
      

Pronto! Agora você solicita e exibe anúncios com o SDK do IMA. Para saber mais sobre outros recursos do SDK, consulte os outros guias ou os exemplos no GitHub (link em inglês).

Próximas etapas

Para maximizar a receita de publicidade na plataforma tvOS, solicite a permissão de transparência e rastreamento do app para usar o IDFA.