Anuncios de aplicación abierta

Selecciona la plataforma: Android iOS Unity Flutter

Esta guía está dirigida a los publicadores que integran anuncios de aplicación abierta.

Los anuncios de aplicación abierta son un formato especial diseñado para los publicadores que desean monetizar las pantallas de carga de sus aplicaciones. Tus usuarios pueden cerrar los anuncios de aplicación abierta en cualquier momento. Los anuncios de aplicación abierta se pueden mostrar cuando los usuarios llevan tu aplicación al primer plano.

Los anuncios de aplicación abierta muestran automáticamente un área de desarrollo de la marca pequeña para que los usuarios sepan que están en tu aplicación. A continuación, se muestra un ejemplo de cómo se ve un anuncio de aplicación abierta:

A grandes rasgos, estos son los pasos necesarios para implementar anuncios de aplicación abierta:

  1. Crea una clase de administrador que cargue un anuncio antes de que necesites mostrarlo.
  2. Mostrar el anuncio durante los eventos de primer plano de la app
  3. Controla las devoluciones de llamada de la presentación.

Requisitos previos

Realiza siempre pruebas con anuncios de prueba

Cuando compiles y pruebes tus apps, asegúrate de usar anuncios de prueba en vez de anuncios activos en fase de producción. De lo contrario, podría suspenderse tu cuenta.

La forma más sencilla de cargar anuncios de prueba es usar nuestro ID de unidad de anuncios de prueba exclusivo para los anuncios de apertura de la app:

ca-app-pub-3940256099942544/5575463023

Se configuró especialmente para devolver anuncios de prueba en cada solicitud, y puedes usarlo en tus propias apps mientras codificas, pruebas y depuras. Solo asegúrate de reemplazarlo por tu propio ID de bloque de anuncios antes de publicar tu app.

Consulta el artículo Anuncios de prueba para obtener más información sobre cómo funcionan los anuncios de prueba del SDK de anuncios para dispositivos móviles.

Implementa una clase de administrador

Tu anuncio debe mostrarse rápidamente, por lo que es mejor cargarlo antes de que necesites mostrarlo. De esa manera, tendrás un anuncio listo para mostrar en cuanto el usuario ingrese a tu app. Implementa una clase de administrador para realizar solicitudes de anuncios antes de que necesites mostrarlos.

Crea una nueva clase singleton llamada AppOpenAdManager:

Swift

class AppOpenAdManager: NSObject {
  /// The app open ad.
  var appOpenAd: AppOpenAd?
  /// Maintains a reference to the delegate.
  weak var appOpenAdManagerDelegate: AppOpenAdManagerDelegate?
  /// Keeps track of if an app open ad is loading.
  var isLoadingAd = false
  /// Keeps track of if an app open ad is showing.
  var isShowingAd = false
  /// Keeps track of the time when an app open ad was loaded to discard expired ad.
  var loadTime: Date?
  /// For more interval details, see https://support.google.com/admob/answer/9341964
  let timeoutInterval: TimeInterval = 4 * 3_600

  static let shared = AppOpenAdManager()

Objective-C

@interface AppOpenAdManager ()

/// The app open ad.
@property(nonatomic, strong, nullable) GADAppOpenAd *appOpenAd;
/// Keeps track of if an app open ad is loading.
@property(nonatomic, assign) BOOL isLoadingAd;
/// Keeps track of if an app open ad is showing.
@property(nonatomic, assign) BOOL isShowingAd;
/// Keeps track of the time when an app open ad was loaded to discard expired ad.
@property(nonatomic, strong, nullable) NSDate *loadTime;

@end

/// For more interval details, see https://support.google.com/admob/answer/9341964
static const NSInteger kTimeoutInterval = 4;

@implementation AppOpenAdManager

+ (nonnull AppOpenAdManager *)sharedInstance {
  static AppOpenAdManager *instance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    instance = [[AppOpenAdManager alloc] init];
  });
  return instance;
}

E implementa su protocolo AppOpenAdManagerDelegate:

Swift

protocol AppOpenAdManagerDelegate: AnyObject {
  /// Method to be invoked when an app open ad life cycle is complete (i.e. dismissed or fails to
  /// show).
  func appOpenAdManagerAdDidComplete(_ appOpenAdManager: AppOpenAdManager)
}

Objective-C

@protocol AppOpenAdManagerDelegate <NSObject>
/// Method to be invoked when an app open ad life cycle is complete (i.e. dismissed or fails to
/// show).
- (void)adDidComplete;
@end

Carga un anuncio

El siguiente paso es cargar un anuncio de apertura de la aplicación:

Swift

func loadAd() async {
  // Do not load ad if there is an unused ad or one is already loading.
  if isLoadingAd || isAdAvailable() {
    return
  }
  isLoadingAd = true

  do {
    appOpenAd = try await AppOpenAd.load(
      with: "ca-app-pub-3940256099942544/5575463023", request: Request())
    appOpenAd?.fullScreenContentDelegate = self
    loadTime = Date()
  } catch {
    print("App open ad failed to load with error: \(error.localizedDescription)")
    appOpenAd = nil
    loadTime = nil
  }
  isLoadingAd = false
}

Objective-C

- (void)loadAd {
  // Do not load ad if there is an unused ad or one is already loading.
  if ([self isAdAvailable] || self.isLoadingAd) {
    return;
  }
  self.isLoadingAd = YES;

  [GADAppOpenAd loadWithAdUnitID:@"ca-app-pub-3940256099942544/5575463023"
                         request:[GADRequest request]
               completionHandler:^(GADAppOpenAd * _Nullable appOpenAd, NSError * _Nullable error) {
    self.isLoadingAd = NO;
    if (error) {
      NSLog(@"App open ad failed to load with error: %@", error);
      self.appOpenAd = nil;
      self.loadTime = nil;
      return;
    }
    self.appOpenAd = appOpenAd;
    self.appOpenAd.fullScreenContentDelegate = self;
    self.loadTime = [NSDate date];
  }];
}

Mostrar un anuncio

El siguiente paso es mostrar un anuncio de apertura de la app. Si no hay anuncios disponibles, intenta cargar uno nuevo.

Swift

func showAdIfAvailable() {
  // If the app open ad is already showing, do not show the ad again.
  if isShowingAd {
    return print("App open ad is already showing.")
  }

  // If the app open ad is not available yet but is supposed to show, load
  // a new ad.
  if !isAdAvailable() {
    print("App open ad is not ready yet.")
    // The app open ad is considered to be complete in this example.
    appOpenAdManagerDelegate?.appOpenAdManagerAdDidComplete(self)
    // Load a new ad.
    return
  }

  if let appOpenAd {
    appOpenAd.present(from: nil)
    isShowingAd = true
  }
}

Objective-C

- (void)showAdIfAvailable {
  // If the app open ad is already showing, do not show the ad again.
  if (self.isShowingAd) {
    NSLog(@"App open ad is already showing.");
    return;
  }

  // If the app open ad is not available yet but is supposed to show, load
  // a new ad.
  if (![self isAdAvailable]) {
    NSLog(@"App open ad is not ready yet.");
    // The app open ad is considered to be complete in this example.
    [self adDidComplete];
    // Load a new ad.
    return;
  }

  [self.appOpenAd presentFromRootViewController:nil];
  self.isShowingAd = YES;
}

Mostrar el anuncio durante los eventos en primer plano de la app

Cuando la aplicación se activa, llama a showAdIfAvailable() para mostrar un anuncio si hay uno disponible o carga uno nuevo.

Swift

func applicationDidBecomeActive(_ application: UIApplication) {
  // Show the app open ad when the app is foregrounded.
  AppOpenAdManager.shared.showAdIfAvailable()
}

Objective-C

- (void) applicationDidBecomeActive:(UIApplication *)application {
  // Show the app open ad when the app is foregrounded.
  [AppOpenAdManager.sharedInstance showAdIfAvailable];
}

Cómo controlar las devoluciones de llamada de la presentación

Para recibir notificaciones de eventos de presentación, debes asignar GADFullScreenContentDelegate a la propiedad fullScreenContentDelegate del anuncio devuelto:

Swift

appOpenAd?.fullScreenContentDelegate = self

Objective-C

self.appOpenAd.fullScreenContentDelegate = self;

En particular, querrás solicitar el siguiente anuncio de apertura de la app una vez que finalice la presentación del primero. En el siguiente código, se muestra cómo implementar el protocolo en tu archivo AppOpenAdManager:

Swift

func adDidRecordImpression(_ ad: FullScreenPresentingAd) {
  print("App open ad recorded an impression.")
}

func adDidRecordClick(_ ad: FullScreenPresentingAd) {
  print("App open ad recorded a click.")
}

func adWillDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
  print("App open ad will be dismissed.")
}

func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) {
  print("App open ad will be presented.")
}

func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
  print("App open ad was dismissed.")
  appOpenAd = nil
  isShowingAd = false
  appOpenAdManagerDelegate?.appOpenAdManagerAdDidComplete(self)
  Task {
    await loadAd()
  }
}

func ad(
  _ ad: FullScreenPresentingAd,
  didFailToPresentFullScreenContentWithError error: Error
) {
  print("App open ad failed to present with error: \(error.localizedDescription)")
  appOpenAd = nil
  isShowingAd = false
  appOpenAdManagerDelegate?.appOpenAdManagerAdDidComplete(self)
  Task {
    await loadAd()
  }
}

Objective-C

- (void)adDidRecordImpression:(nonnull id<GADFullScreenPresentingAd>)ad {
  NSLog(@"App open ad recorded an impression.");
}

- (void)adDidRecordClick:(nonnull id<GADFullScreenPresentingAd>)ad {
  NSLog(@"App open ad recorded a click.");
}

- (void)adWillPresentFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
  NSLog(@"App open ad will be presented.");
}

- (void)adWillDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
  NSLog(@"App open ad will be dismissed.");
}

- (void)adDidDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
  NSLog(@"App open ad was dismissed.");
  self.appOpenAd = nil;
  self.isShowingAd = NO;
  [self adDidComplete];
  [self loadAd];
}

- (void)ad:(nonnull id<GADFullScreenPresentingAd>)ad
    didFailToPresentFullScreenContentWithError:(nonnull NSError *)error {
  NSLog(@"App open ad failed to present with error: %@", error.localizedDescription);
  self.appOpenAd = nil;
  self.isShowingAd = NO;
  [self adDidComplete];
  [self loadAd];
}

Ten en cuenta el vencimiento de los anuncios

Para asegurarte de no mostrar un anuncio vencido, puedes agregar un método al delegado de la app que verifique el tiempo transcurrido desde que se cargó la referencia del anuncio.

En tu AppOpenAdManager, agrega una propiedad Date llamada loadTime y configúrala cuando se cargue tu anuncio. Luego, puedes agregar un método que devuelva true si transcurrió menos de una cierta cantidad de horas desde que se cargó tu anuncio. Asegúrate de verificar la validez de la referencia del anuncio antes de intentar mostrarlo.

Swift

private func wasLoadTimeLessThanNHoursAgo(timeoutInterval: TimeInterval) -> Bool {
  // Check if ad was loaded more than n hours ago.
  if let loadTime = loadTime {
    return Date().timeIntervalSince(loadTime) < timeoutInterval
  }
  return false
}

private func isAdAvailable() -> Bool {
  // Check if ad exists and can be shown.
  return appOpenAd != nil && wasLoadTimeLessThanNHoursAgo(timeoutInterval: timeoutInterval)
}

Objective-C

- (BOOL)wasLoadTimeLessThanNHoursAgo:(int)n {
  // Check if ad was loaded more than n hours ago.
  NSDate *now = [NSDate date];
  NSTimeInterval timeIntervalBetweenNowAndLoadTime = [now timeIntervalSinceDate:self.loadTime];
  double secondsPerHour = 3600.0;
  double intervalInHours = timeIntervalBetweenNowAndLoadTime / secondsPerHour;
  return intervalInHours < n;
}

- (BOOL)isAdAvailable {
  // Check if ad exists and can be shown.
  return _appOpenAd && [self wasLoadTimeLessThanNHoursAgo:kTimeoutInterval];
}

Inicios en frío y pantallas de carga

En la documentación, se supone que solo muestras anuncios de aplicación abierta cuando los usuarios ponen tu app en primer plano mientras está suspendida en la memoria. Los "inicios en frío" se producen cuando se inicia tu app, pero no se había suspendido previamente en la memoria.

Un ejemplo de inicio en frío es cuando un usuario abre tu app por primera vez. Con los inicios en frío, no tendrás un anuncio de aplicación abierta cargado previamente que esté listo para mostrarse de inmediato. La demora entre el momento en que solicitas un anuncio y el momento en que lo recibes puede generar una situación en la que los usuarios puedan usar brevemente tu app antes de sorprenderse con un anuncio fuera de contexto. Esto se debe evitar porque genera una mala experiencia del usuario.

La mejor manera de usar anuncios de aplicación abierta en inicios en frío es usar una pantalla de carga para cargar los recursos de tu juego o aplicación, y mostrar el anuncio solo desde la pantalla de carga. Si tu app terminó de cargarse y envió al usuario al contenido principal, no muestres el anuncio.

Prácticas recomendadas

Google creó los anuncios de apertura de la aplicación para ayudarte a monetizar la pantalla de carga de tu aplicación, pero es importante que tengas en cuenta las prácticas recomendadas para que los usuarios disfruten de tu aplicación. Asegúrate de hacer lo siguiente:

  • Espera a mostrar tu primer anuncio de aplicación abierta hasta que los usuarios hayan utilizado tu aplicación unas cuantas veces.
  • Muestra anuncios de aplicación abierta en los momentos en que tus usuarios estarían esperando a que se cargue tu aplicación.
  • Si tienes una pantalla de carga debajo del anuncio de aplicación abierta y esta termina de cargarse antes de que se descarte el anuncio, te recomendamos descartarla en el método adDidDismissFullScreenContent.

Ejemplo completo en GitHub

Swift Objective-C

Próximos pasos

Obtén más información sobre la privacidad del usuario.