應用程式開啟頁面廣告

本指南適用於整合應用程式開啟頁面廣告的發布商。

應用程式開啟頁面廣告是一種特殊廣告格式,適合希望藉由應用程式載入畫面賺取收益的發布商。使用者隨時可以關閉應用程式開啟頁面廣告。應用程式開啟頁面廣告會在使用者將應用程式切換至前景時顯示。

應用程式開啟頁面廣告會自動保留一小塊畫面,向使用者顯示應用程式的品牌資訊。以下是應用程式開啟頁面廣告的示例:

以下概略說明導入應用程式開啟頁面廣告的必要步驟:

  1. 建立管理員類別,在您需要顯示廣告之前先載入廣告。
  2. 在應用程式前景事件期間顯示廣告。
  3. 處理簡報回呼。

必要條件

請務必使用測試廣告進行測試

建構及測試應用程式時,請務必使用測試廣告,而非實際的正式版廣告。否則可能導致帳戶停權。

如要載入測試廣告,最簡單的方法是使用專用測試廣告單元 ID 來開啟應用程式廣告:

ca-app-pub-3940256099942544/5575463023

這項廣告單元已特別設定為針對每項要求傳回測試廣告,您可以在編寫程式碼、測試及偵錯時,在自己的應用程式中自由使用這項廣告單元。只要在發布應用程式前,將其替換為自己的廣告單元 ID 即可。

如要進一步瞭解 Mobile Ads SDK 的測試廣告運作方式,請參閱「測試廣告」。

實作管理員類別

廣告應快速顯示,因此建議您在需要顯示廣告前先行載入。這樣一來,使用者一進入應用程式,廣告就會立即顯示。請實作管理員類別,在需要顯示廣告時提前發出廣告請求。

建立名為 AppOpenAdManager 的新單例類別,並按照下列方式填寫:

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

載入廣告

接下來,請填寫 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;
             }];
}

顯示廣告

接下來,請填寫 showAdIfAvailable() 方法。如果沒有可用的廣告,方法會嘗試載入廣告。

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

在應用程式前景事件期間顯示廣告

應用程式啟用時,請呼叫 showAdIfAvailable() 來顯示廣告 (如果有),或載入新的廣告。

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

處理簡報回呼

當應用程式顯示應用程式開啟頁面廣告時,您應使用 GADFullScreenContentDelegate 處理特定呈現事件。特別是,您需要在第一則廣告播放完畢後,要求下一個應用程式開啟廣告。

AppOpenAdManager 類別中加入以下內容:

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

考慮廣告效期

為避免顯示已失效的廣告,您可以在應用程式委派程式碼中新增方法,檢查廣告參照載入後的經過時間。

AppOpenAdManager 中,新增名為 loadTimeDate 屬性,並在廣告載入時設定該屬性。接著,您可以新增方法,在廣告載入後未超過特定小時數時,傳回 true。請務必先檢查廣告參照資料的有效性,再嘗試顯示廣告。

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

冷啟動和載入畫面

本文件假設您只會在使用者將應用程式從記憶體中暫停後,在前景顯示應用程式開啟頁面廣告。當應用程式啟動,但先前未在記憶體中暫停時,就會發生「冷啟動」。

舉例來說,使用者初次開啟應用程式就是冷啟動。在冷啟動期間,您不會有先前載入的應用程式開啟頁面廣告,因此無法立即顯示廣告。在您提出廣告請求和收到廣告回應之間,可能會出現延遲的情況,導致使用者在應用程式運作一段時間後,才會看到不相關的廣告。這會造成使用者體驗不佳,因此應避免採用。

在冷啟動時使用應用程式開啟頁面廣告的首選方式,是使用載入畫面載入遊戲或應用程式素材資源,並只在載入畫面中顯示廣告。如果應用程式已完成載入,並將使用者導向應用程式的主內容,請勿顯示廣告。

最佳做法

Google 建立了應用程式開啟廣告,協助您透過應用程式的載入畫面營利,但請務必遵循最佳做法,讓使用者能盡情享受應用程式。請務必:

  • 等使用者用過應用程式幾次之後,再放送第一則應用程式開啟頁面廣告。
  • 在使用者等待應用程式載入時,顯示應用程式開啟頁面廣告。
  • 如果載入畫面顯示在應用程式開啟頁面廣告的背景中,且載入畫面在廣告關閉前就完成載入,建議您利用 adDidDismissFullScreenContent 方法關閉載入畫面。

GitHub 上的完整範例

Swift Objective-C

後續步驟

進一步瞭解使用者隱私權