Annunci apertura app

Questa guida è rivolta ai publisher che integrano gli annunci apertura app.

Gli annunci apertura app sono un formato dell'annuncio speciale destinato ai publisher che vogliono monetizzare le schermate di caricamento delle app. Gli annunci apertura app possono essere chiusi dagli utenti in qualsiasi momento. Gli annunci apertura app possono essere mostrati quando gli utenti portano la tua app in primo piano.

Gli annunci apertura app mostrano automaticamente una piccola area di branding, in modo che gli utenti sappiano che si trovano nella tua app. Ecco un esempio di annuncio apertura app:

A livello generale, di seguito sono riportati i passaggi necessari per implementare gli annunci apertura app:

  1. Crea una classe gestore che carichi un annuncio prima che tu debba visualizzarlo.
  2. Mostra l'annuncio durante gli eventi di primo piano dell'app.
  3. Gestire i callback della presentazione.

Prerequisiti

Esegui sempre test con annunci di prova

Quando crei e test le tue app, assicurati di utilizzare annunci di prova anziché annunci di produzione pubblicati. In caso contrario, l'account potrebbe essere sospeso.

Il modo più semplice per caricare gli annunci di prova è utilizzare il nostro ID unità pubblicitaria di prova dedicato per gli annunci apertura app:

ca-app-pub-3940256099942544/5575463023

È stato configurato appositamente per restituire annunci di prova per ogni richiesta e puoi usarlo liberamente nelle tue app durante la codifica, il test e il debug. Assicurati di sostituirlo con il tuo ID unità pubblicitaria prima di pubblicare l'app.

Per ulteriori informazioni su come funzionano gli annunci di prova dell'SDK Mobile Ads, consulta Test Ads.

Implementare un corso gestore

Poiché l'annuncio viene pubblicato rapidamente, ti consigliamo di caricarlo prima di doverlo mostrare. In questo modo, l'annuncio sarà pronto non appena l'utente accede alla tua app. Implementa una classe manager per fare richieste di annunci prima del momento in cui devi mostrarlo.

Crea un nuovo corso singleton chiamato AppOpenAdManager e compilalo come 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

Carica un annuncio

Il passaggio successivo consiste nella compilazione del metodo 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: "ca-app-pub-3940256099942544/5575463023", request: GADRequest())
  } 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:@"ca-app-pub-3940256099942544/5575463023"
                       request:[GADRequest 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;
             }];
}

Mostra un annuncio

Il passaggio successivo consiste nella compilazione del metodo showAdIfAvailable(). Se non è disponibile alcun annuncio, il metodo tenta di caricare un annuncio.

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];
}

Mostrare l'annuncio durante gli eventi in primo piano dell'app

Quando l'applicazione diventa attiva, chiama showAdIfAvailable() per mostrare un annuncio se ne è disponibile uno o caricane uno nuovo.

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

Gestire i callback della presentazione

Quando la tua app mostra un annuncio apertura app, devi affidarti a GADFullScreenContentDelegate per gestire determinati eventi di presentazione. In particolare, ti consigliamo di richiedere il prossimo annuncio apertura app al termine della presentazione.

Nel tuo corso AppOpenAdManager, aggiungi quanto segue:

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: "ca-app-pub-3940256099942544/5575463023", request: GADRequest())
      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:@"ca-app-pub-3940256099942544/5575463023"
                       request:[GADRequest 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

Valuta la scadenza degli annunci

Per assicurarti di non mostrare un annuncio scaduto, puoi aggiungere al delegato dell'app un metodo che controlli il tempo trascorso dal caricamento del riferimento dell'annuncio.

In AppOpenAdManager aggiungi una proprietà Date denominata loadTime e impostala quando viene caricato l'annuncio. Puoi quindi aggiungere un metodo che restituisca true se sono trascorse meno di un determinato numero di ore dal caricamento dell'annuncio. Assicurati di verificare la validità del riferimento dell'annuncio prima di provare a pubblicarlo.

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: "ca-app-pub-3940256099942544/5575463023", request: GADRequest())
      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:@"ca-app-pub-3940256099942544/5575463023"
                       request:[GADRequest 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

Avvio a freddo e schermate di caricamento

La documentazione presuppone che mostri annunci apertura app solo quando gli utenti mettono in primo piano la tua app quando è sospesa in memoria. Gli "avvii a freddo" si verificano quando l'app viene avviata ma non è stata precedentemente sospesa in memoria.

Un esempio di avvio a freddo è quando un utente apre la tua app per la prima volta. Con gli avvii a freddo, non avrai un annuncio apertura app caricato in precedenza e pronto per essere mostrato immediatamente. Il ritardo tra il momento in cui richiedi un annuncio e la ricezione di un rimborso pubblicitario può creare una situazione in cui gli utenti sono in grado di utilizzare la tua app per un breve momento prima di essere sorpresi da un annuncio fuori contesto. Dovresti evitare questa situazione perché un'esperienza utente negativa.

Il modo migliore per utilizzare gli annunci apertura app con avvii a freddo è utilizzare una schermata di caricamento per caricare gli asset del gioco o dell'app e mostrare l'annuncio solo dalla schermata di caricamento. Se l'app ha completato il caricamento e ha indirizzato l'utente ai contenuti principali dell'app, non mostrare l'annuncio.

best practice

Google ha creato gli annunci apertura app per aiutarti a monetizzare la schermata di caricamento dell'app, ma è importante tenere a mente le best practice per fare in modo che gli utenti possano usare l'app. Assicurati di:

  • Attendi che venga mostrato l'annuncio della prima apertura dell'app finché gli utenti non l'hanno usata alcune volte.
  • Mostra gli annunci apertura app quando gli utenti aspetterebbero altrimenti il caricamento dell'app.
  • Se hai una schermata di caricamento sotto l'annuncio apertura app e questa viene completata prima che l'annuncio venga ignorato, ti consigliamo di chiudere la schermata di caricamento nel metodo adDidDismissFullScreenContent.

Esempio completo su GitHub

Swift Obiettivo-C

Passaggi successivi

Scopri di più sulla privacy dell'utente.