Anúncios de abertura do app

Este guia é destinado a editores que estão integrando anúncios de abertura do app.

Os anúncios de abertura do app são um formato especial destinado a editores que querem gerar receita com as telas de carregamento do app. Os anúncios de abertura de app podem ser fechados pelos usuários a qualquer momento. Os anúncios de abertura do app podem ser exibidos quando os usuários colocam seu app em primeiro plano.

Os anúncios de abertura do app mostram automaticamente uma pequena área de branding para os usuários saberem que estão neles seu app. Confira um exemplo de anúncio de abertura do app:

Confira as etapas necessárias para implementar os anúncios de abertura do app:

  1. Crie uma classe de administrador que carregue um anúncio antes que você precise exibi-lo.
  2. Mostre o anúncio durante os eventos em primeiro plano do app.
  3. Processar callbacks de apresentações.

Pré-requisitos

Sempre teste com anúncios de teste

Ao criar e testar seus apps, use anúncios de teste em vez de anúncios de produção ativos. Sua conta poderá ser suspensa se isso não for feito.

A maneira mais fácil de carregar anúncios de teste é usando nosso ID de bloco de anúncios de teste dedicado para apps. abrir anúncios:

/21775744923/example/app-open

Ele foi configurado especialmente para retornar anúncios de teste para cada solicitação, e você pode usá-lo nos seus próprios apps durante a programação, o teste e a depuração. Basta substituí-lo pelo seu próprio ID de bloco de anúncios antes de publicar o app.

Para mais informações sobre como funcionam os anúncios de teste do SDK dos anúncios para dispositivos móveis, consulte Testar Google Ads.

Implementar uma classe de administrador

Seu anúncio deve ser exibido rapidamente, por isso é melhor carregá-lo antes de precisar exibi-la. Dessa forma, você terá um anúncio pronto para exibição assim que o usuário inserir seu app. Implemente uma classe de administrador para fazer solicitações de anúncios antes de quando precisar para mostrar o anúncio.

Crie uma nova classe de singleton com o nome AppOpenAdManager e a preencha como segue:

Swift

class AppOpenAdManager: NSObject {
  var appOpenAd: GADAppOpenAd?
  var isLoadingAd = false.
  var isShowingAd = false

  static let shared = AppOpenAdManager()

  private func loadAd() async {
    // TODO: Implement loading an ad.
  }

  func showAdIfAvailable() {
    // TODO: Implement showing an ad.
  }

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

Objective-C

@interface AppOpenAdManager ()
@property(nonatomic, strong) GADAppOpenAd *appOpenAd;
@property(nonatomic, assign) BOOL isLoadingAd;
@property(nonatomic, assign) BOOL isShowingAd;

@end

@implementation AppOpenAdManager

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

- (void)loadAd {
  // TODO: Implement loading an ad.
}

// Add this method to the .h file.
- (void)showAdIfAvailable {
  // TODO: Implement showing an ad.
}

- (BOOL)isAdAvailable {
  // Check if ad exists and can be shown.
  return self.appOpenAd != nil;
}

@end

Carregar um anúncio

A próxima etapa é preencher o método loadAd().

Swift

private 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 GADAppOpenAd.load(
      withAdUnitID: "/21775744923/example/app-open", request: GAMRequest())
  } catch {
    print("App open ad failed to load with error: \(error.localizedDescription)")
  }
  isLoadingAd = false
}

Objective-C

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

  [GADAppOpenAd loadWithAdUnitID:@"/21775744923/example/app-open"
                       request:[GAMRequest request]
             completionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {
               self.isLoadingAd = NO;
               if (error) {
                 NSLog(@"Failed to load app open ad: %@", error);
                 return;
               }
               self.appOpenAd = appOpenAd;
             }];
}

Mostrar um anúncio

A próxima etapa é preencher o método showAdIfAvailable(). Se nenhum anúncio for disponível, o método tenta carregar um anúncio.

Swift

func showAdIfAvailable() {
  // If the app open ad is already showing, do not show the ad again.
  guard !isShowingAd else { return }

  // If the app open ad is not available yet but is supposed to show, load
  // a new ad.
  if !isAdAvailable() {
    Task {
      await loadAd()
    }
    return
  }

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

Objective-C

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

  // If the app open ad is not available yet but is supposed to show, load a
  // new ad.
  if (![self isAdAvailable]) {
    [self loadAd];
    return;
  }

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

Mostrar o anúncio durante eventos em primeiro plano do app

Quando o aplicativo ficar ativo, chame showAdIfAvailable() para exibir um anúncio se um está disponível ou carrega um novo.

Swift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  // ...

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

Objective-C

@implementation AppDelegate
// ...

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

@end

Processar callbacks de apresentações

Quando seu app mostra um anúncio de abertura do app, você deve confiar no GADFullScreenContentDelegate para lidar com determinados eventos de apresentação. Em solicite o próximo anúncio de abertura do app assim que o primeiro termine de apresentar.

Na classe AppOpenAdManager, adicione o seguinte:

Swift

class AppOpenAdManager: NSObject, GADFullScreenContentDelegate {
  // ...

  private 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 GADAppOpenAd.load(
        withAdUnitID: "/21775744923/example/app-open", request: GAMRequest())
      appOpenAd?.fullScreenContentDelegate = self
    } catch {
      print("App open ad failed to load with error: \(error.localizedDescription)")
    }
    isLoadingAd = false
  }

  // ...

  // MARK: - GADFullScreenContentDelegate methods

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

  func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
    appOpenAd = nil
    isShowingAd = false
    // Reload an ad.
    Task {
      await loadAd()
    }
  }

  func ad(
    _ ad: GADFullScreenPresentingAd,
    didFailToPresentFullScreenContentWithError error: Error
  ) {
    appOpenAd = nil
    isShowingAd = false
    // Reload an ad.
    Task {
      await loadAd()
    }
  }
}

Objective-C

@interface AppOpenAdManager () <GADFullScreenContentDelegate>
@property(nonatomic, strong) GADAppOpenAd *appOpenAd
@property(nonatomic, assign) BOOL isLoadingAd;
@property(nonatomic, assign) BOOL isShowingAd;

@end

@implementation AppOpenAdManager

// ...

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

  [GADAppOpenAd loadWithAdUnitID:@"/21775744923/example/app-open"
                       request:[GAMRequest request]
             completionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {
              self.isLoadingAd = NO;
               if (error) {
                 NSLog(@"Failed to load app open ad: %@", error);
                 return;
               }
               self.appOpenAd = appOpenAd;
               self.appOpenAd.fullScreenContentDelegate = self;
             }];
}

- (BOOL)isAdAvailable {
  // Check if ad exists and can be shown.
  return self.appOpenAd != nil;
}

// ...

#pragma mark - GADFullScreenContentDelegate methods

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

- (void)adDidDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
  self.appOpenAd = nil;
  self.isShowingAd = NO;
  // Reload an ad.
  [self loadAd];
}

- (void)ad:(nonnull id<GADFullScreenPresentingAd>)ad
    didFailToPresentFullScreenContentWithError:(nonnull NSError *)error {
  self.appOpenAd = nil;
  self.isShowingAd = NO;
  // Reload an ad.
  [self loadAd];
}

@end

Considerar a validade dos anúncios

Para garantir que anúncios expirados não sejam veiculados, adicione um método ao delegado do app. que verifica o tempo decorrido desde o carregamento da referência de anúncio.

No AppOpenAdManager, adicione uma propriedade Date com o nome loadTime e defina o quando o anúncio for carregado. Você pode adicionar um método que retorna true se menos do que um determinado número de horas se passaram desde que o anúncio foi carregado. Confirme se verifique a validade da referência do anúncio antes de tentar exibir o anúncio.

Swift

class AppOpenAdManager: NSObject, GADFullScreenContentDelegate {
  var appOpenAd: GADAppOpenAd?
  var isLoadingAd = false.
  var isShowingAd = false
  var loadTime: Date?
  let fourHoursInSeconds = TimeInterval(3600 * 4)

  // ...

  private 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 GADAppOpenAd.load(
        withAdUnitID: "/21775744923/example/app-open", request: GAMRequest())
      appOpenAd?.fullScreenContentDelegate = self
      loadTime = Date()
    } catch {
      print("App open ad failed to load with error: \(error.localizedDescription)")
    }
    isLoadingAd = false
  }

  private func wasLoadTimeLessThanFourHoursAgo() -> Bool {
    guard let loadTime = loadTime else { return false }
    // Check if ad was loaded more than four hours ago.
    return Date().timeIntervalSince(loadTime) < fourHoursInSeconds
  }

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

Objective-C

static NSTimeInterval const fourHoursInSeconds = 3600 * 4;

@interface AppOpenAdManager () <GADFullScreenContentDelegate>
@property(nonatomic, strong) GADAppOpenAd *appOpenAd
@property(nonatomic, assign) BOOL isLoadingAd;
@property(nonatomic, assign) BOOL isShowingAd;
@property(weak, nonatomic) NSDate *loadTime;

@end

@implementation AppOpenAdManager

// ...

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

  [GADAppOpenAd loadWithAdUnitID:@"/21775744923/example/app-open"
                       request:[GAMRequest request]
             completionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {
              self.isLoadingAd = NO;
               if (error) {
                 NSLog(@"Failed to load app open ad: %@", error);
                 return;
               }
               self.appOpenAd = appOpenAd;
               self.appOpenAd.fullScreenContentDelegate = self;
               self.loadTime = [NSDate date];
             }];
}

- (BOOL)wasLoadTimeLessThanFourHoursAgo {
  // Check if ad was loaded more than four hours ago.
  return [[NSDate Date] timeIntervalSinceDate:self.loadTime] < fourHoursInSeconds;
}

- (BOOL)isAdAvailable {
  // Check if ad exists and can be shown.
  return self.appOpenAd != nil && [self wasLoadTimeLessThanFourHoursAgo];
}

@end

Telas de carregamento e inicializações a frio

A documentação pressupõe que você só exibe anúncios de abertura do app quando os usuários seu app em primeiro plano quando ele está suspenso na memória. As "inicializações a frio" ocorrem quando o app é iniciado, mas não foi suspenso anteriormente na memória.

Um exemplo de inicialização a frio é quando um usuário abre o app pela primeira vez. Com as inicializações a frio, você não terá um anúncio de abertura de app carregado anteriormente que esteja pronto para ser mostrado imediatamente. É o atraso entre a solicitação e o recebimento de um anúncio pode criar uma situação em que os usuários podem usar o app brevemente antes ser surpreendido por um anúncio fora de contexto. Isso deve ser evitado, porque é um uma experiência ruim do usuário.

A maneira preferencial de usar anúncios de abertura do app em inicializações a frio é usar uma tela de carregamento para carregar os recursos do jogo ou app e mostrar o anúncio apenas na tela de carregamento. Se o carregamento do app for concluído e o usuário for enviado ao conteúdo principal do app, não mostre o anúncio.

Práticas recomendadas

O Google criou anúncios de abertura do app para ajudar você a gerar receita na tela de carregamento, mas é importante ter em mente as práticas recomendadas para que seus usuários gostem de usar seu app. Faça o seguinte:

  • Aguarde para exibir seu primeiro anúncio de abertura do app até que os usuários tenham usado o algumas vezes.
  • Veicule anúncios de abertura do app nos momentos em que os usuários estariam esperando para o app carregar.
  • Se você tem uma tela de carregamento abaixo do anúncio de abertura do app e sua tela de carregamento concluir o carregamento antes de o anúncio ser dispensado, você pode querer tela de carregamento no método adDidDismissFullScreenContent.

Exemplo completo no GitHub

Swift Objective-C

Próximas etapas

Saiba mais sobre a privacidade do usuário.