Cómo comenzar

Con los SDK de IMA, puedes integrar fácilmente anuncios multimedia en tus sitios web y apps. Los SDK de IMA pueden solicitar anuncios de cualquier servidor de anuncios compatible con VAST y administrar la reproducción de anuncios en tus apps. Con los SDK del cliente de IMA, mantienes el control de la reproducción de video del contenido, mientras que el SDK controla la reproducción de anuncios. Los anuncios se reproducen en un reproductor de video independiente ubicado sobre el reproductor de video de contenido de la app.

En esta guía, se muestra cómo integrar el SDK de IMA en una app de reproductor de video simple. Si deseas ver o seguir una integración de muestra completa, descarga BasicExample desde GitHub.

Descripción general de IMA del cliente

La implementación de IMA en el cliente implica cuatro componentes principales del SDK, que se muestran en esta guía:

  • IMAAdDisplayContainer: Es un objeto contenedor en el que se renderizan anuncios.
  • IMAAdsLoader: Es un objeto que solicita anuncios y controla eventos de las respuestas a solicitudes de anuncios. Solo debes crear una instancia de un cargador de anuncios, que se puede volver a usar durante la vida útil de la aplicación.
  • IMAAdsRequest: Es un objeto que define una solicitud de anuncios. Las solicitudes de anuncios especifican la URL para la etiqueta de anuncio de VAST y los parámetros adicionales, como las dimensiones del anuncio.
  • IMAAdsManager: Es un objeto que contiene la respuesta a la solicitud de anuncios, controla la reproducción de anuncios y escucha eventos de anuncios activados por el SDK.

Requisitos previos

Antes de comenzar, necesitas lo siguiente:

1. Crea un proyecto de Xcode nuevo

En Xcode, crea un proyecto de iOS nuevo con Objective-C o Swift. Usa BasicExample como el nombre del proyecto.

2. Agrega el SDK de IMA al proyecto de Xcode

CocoaPods es un administrador de dependencias para proyectos de Xcode y es el método recomendado para instalar el SDK de IMA. Para obtener más información sobre la instalación o el uso de CocoaPods, consulta la documentación de CocoaPods. Una vez que tengas instalado CocoaPods, usa las siguientes instrucciones para instalar el SDK de IMA:

  1. En el mismo directorio que tu archivo BasicExample.xcodeproj, crea un archivo de texto llamado Podfile y agrega la siguiente configuración:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '10'
    target "BasicExample" do
      pod 'GoogleAds-IMA-iOS-SDK', '~> 3.19.1'
    end
    
  2. Desde el directorio que contiene el Podfile, ejecuta pod install --repo-update.

  3. Verifica que la instalación se haya realizado correctamente. Para ello, abre el archivo BasicExample.xcworkspace y confirma que contiene dos proyectos: BasicExample y Pods (las dependencias instaladas por CocoaPods).

Instala el SDK con Swift Package Manager

El SDK de anuncios multimedia interactivos es compatible con Swift Package Manager a partir de la versión 3.18.4. Sigue los pasos que se indican a continuación para importar el paquete de Swift.

  1. En Xcode, instala el paquete de Swift del SDK de IMA. Para ello, navega a File > Add Packages....

  2. En el mensaje que aparece, busca el repositorio de GitHub del paquete Swift del SDK de IMA:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios
    
  3. Selecciona la versión del paquete de Swift del SDK de IMA que quieres usar. Para los proyectos nuevos, te recomendamos usar Hasta la siguiente versión principal.

Cuando termines, Xcode resolverá las dependencias de tus paquetes y las descarga en segundo plano. Para obtener más detalles sobre cómo agregar dependencias de paquetes, consulta el artículo de Apple.

Descarga e instala el SDK de forma manual

Si no quieres usar Swift Package Manager o CocoaPods, puedes descargar el SDK de IMA y agregarlo a tu proyecto de forma manual.

3. Cómo crear un reproductor de video simple

Primero, implementa un reproductor de video básico. Inicialmente, este reproductor no usa el SDK de IMA y aún no contiene ningún método para activar la reproducción.

ViewController.m

Objective‑C

#import "ViewController.h"

#import <AVKit/AVKit.h>

NSString *const kContentURLString =
    @"https://storage.googleapis.com/interactive-media-ads/media/bipbop.m3u8";

@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/bipbop.m3u8"

  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. Importa el SDK de IMA

A continuación, agrega el framework de IMA con una instrucción de importación debajo de las importaciones existentes.

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/bipbop.m3u8";
      

Swift

import AVFoundation
import GoogleInteractiveMediaAds
import UIKit

class ViewController: UIViewController {
  static let ContentURLString = "https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"
      

5. Cómo implementar el seguimiento del cabezal de reproducción de contenido y un observador del final de la transmisión

Para reproducir anuncios durante el video, el SDK de IMA debe hacer un seguimiento de la posición actual de tu contenido de video. Para ello, crea una clase que implemente IMAContentPlayhead. Si usas un AVPlayer, como se muestra en este ejemplo, el SDK proporciona la clase IMAAVPlayerContentPlayhead que lo hace por ti. Si no usas AVPlayer, deberás implementar IMAContentPlayhead en una clase propia.

También debes informarle al SDK cuándo termina de reproducirse tu contenido para que pueda mostrar anuncios al final del video. Para ello, se debe llamar a contentComplete en el IMAAdsLoader mediante 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://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"

  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. Cómo inicializar el cargador de anuncios y realizar una solicitud de anuncios

Para solicitar un conjunto de anuncios, debes crear una instancia de IMAAdsLoader. Este cargador se puede usar para procesar objetos IMAAdsRequest asociados con la URL de una etiqueta de anuncio especificada.

Como práctica recomendada, mantén solo una instancia de IMAAdsLoader durante todo el ciclo de vida de tu app. Para realizar solicitudes de anuncios adicionales, crea un objeto IMAAdsRequest nuevo, pero vuelve a usar el mismo IMAAdsLoader. Para obtener más información, consulta las Preguntas frecuentes sobre el SDK de IMA.

ViewController.m

Objective‑C

...

NSString *const kContentURLString =
    @"https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/"
    @"master.m3u8";
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://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&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 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. Cómo configurar un delegado del cargador de anuncios

En un evento de carga exitoso, IMAAdsLoader llama al método adsLoadedWithData de su delegado asignado y le pasa una instancia de IMAAdsManager. Luego, puedes inicializar el administrador de anuncios, que carga los anuncios individuales, según lo que se define en la respuesta a la URL de la etiqueta de anuncio.

Además, asegúrate de solucionar cualquier error que pueda ocurrir durante el proceso de carga. Si los anuncios no se cargan, asegúrate de que la reproducción de contenido multimedia continúe, sin anuncios, para que no interfiera en la experiencia del usuario.

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. Cómo configurar un delegado de Google Ads Manager

Por último, para administrar los eventos y los cambios de estado, el administrador de anuncios necesita un delegado propio. IMAAdManagerDelegate tiene métodos para controlar eventos y errores de anuncios, así como métodos para activar la reproducción y la pausa en el contenido de video.

Iniciando reproducción

Hay muchos eventos que se puede usar para controlar el método didReceiveAdEvent, pero para este ejemplo básico, solo debes escuchar el evento LOADED a fin de indicarle al administrador de anuncios que comience a reproducir contenido y anuncios.

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

...
      

Maneja los errores

Agrega también un controlador para los errores de anuncios. Si se produce un error, como en el paso anterior, reanuda la reproducción de contenido.

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

Cómo activar eventos de reproducción y pausa

Los últimos dos métodos delegados que debes implementar se usan para activar eventos de reproducción y pausa en el contenido de video subyacente, cuando el SDK de IMA lo solicita. Activar la pausa y la reproducción cuando se solicita evita que el usuario falte partes del contenido de video cuando se muestran anuncios.

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

Listo. Ahora solicita y muestra anuncios con el SDK de IMA. Para obtener información sobre funciones adicionales del SDK, consulta las otras guías o las muestras en GitHub.

Próximos pasos

Si desea maximizar los ingresos publicitarios en la plataforma de iOS, solicite el permiso de seguimiento y transparencia de la aplicación para usar el IDFA.