如果發布商有意整合應用程式開啟頁面廣告,歡迎參閱本指南。
應用程式開啟頁面廣告是一種特殊廣告格式,可以幫助開發人員利用應用程式載入畫面賺取收益。這類廣告可能在使用者將應用程式切換至前景時出現,使用者可以隨時關閉。
應用程式開啟頁面廣告會在一小塊區域自動顯示品牌資訊,讓使用者知道他們仍在您的應用程式中。以下是這類廣告的外觀:
導入應用程式開啟頁面廣告的大致步驟如下:
- 建立管理器類別,用來預先載入需要顯示的廣告。
- 在應用程式進入前景時顯示廣告。
- 處理顯示事件回呼。
前置作業
請務必使用測試廣告進行測試
建構及測試應用程式時,請務必使用測試廣告,而非實際的正式廣告;若未遵守此規定,可能導致帳戶遭到停權。
載入測試廣告最簡單的方法,是使用應用程式開啟頁面廣告專用的測試廣告單元 ID:
/21775744923/example/app-open
這個 ID 經過特別設定,每次請求都會傳回測試廣告。在編寫程式碼、測試及偵錯階段,您可以在應用程式中自由使用,但發布前記得要換成自己的廣告單元 ID。
如要進一步瞭解 Mobile Ads SDK 測試廣告的運作方式,請參閱「測試廣告」。
實作管理器類別
為了讓廣告快速顯示,建議提前載入廣告,讓使用者一進入應用程式就能立即看到。您可以實作管理器類別來預先發出廣告請求,確保廣告在需要顯示時已準備就緒。
建立名為 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/admanager/answer/9351867
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/admanager/answer/9351867
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;
}
實作相應的 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
載入廣告
下一步是載入應用程式開啟頁面廣告:
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: "/21775744923/example/app-open", request: AdManagerRequest())
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:@"/21775744923/example/app-open"
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];
}];
}
顯示廣告
下一步是顯示應用程式開啟頁面廣告。如果目前沒有可用廣告,則嘗試載入新廣告。
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 {
print("App open ad will be displayed.")
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;
}
在應用程式進入前景時顯示廣告
在應用程式進入前景時,呼叫 showAdIfAvailable()
即可檢查是否有廣告可用;若已有廣告,會立即顯示,否則會載入新的廣告。
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];
}
處理顯示事件回呼
為了接收廣告顯示事件的通知,必須將 GADFullScreenContentDelegate
指派給傳回廣告的 fullScreenContentDelegate 屬性:
Swift
appOpenAd?.fullScreenContentDelegate = self
Objective-C
self.appOpenAd.fullScreenContentDelegate = self;
具體來說,當第一則應用程式開啟頁面廣告展示完成後,您需要請求下一則廣告。以下是 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];
}
考慮廣告效期
為避免顯示過期廣告,您可以在應用程式委派物件中新增方法,用來檢查廣告物件載入後經過的時間。
請在 AppOpenAdManager
中新增名為 loadTime
的 Date
屬性,並在廣告載入時設定該屬性。接著,您可以新增方法,用來檢查廣告載入後是否未超過指定的時間範圍,若未超過則回傳 true
。在顯示廣告前,務必確認廣告物件仍然有效。
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 self.appOpenAd && [self wasLoadTimeLessThanNHoursAgo:kTimeoutInterval];
}
冷啟動和載入畫面
本文假設應用程式開啟頁面廣告出現的時機,只有在使用者將處於暫停狀態 (但仍在記憶體中) 的應用程式切換至前景時。若應用程式不是從暫停狀態恢復,而是全新啟動,則稱為「冷啟動」。
舉例來說,使用者第一次開啟應用程式時,就是冷啟動。 在這個情況下,您不會有先前載入的應用程式開啟頁面廣告,因此無法立即顯示。在您要求廣告與接收到廣告的延遲期間,使用者可能得以短暫使用您的應用程式,接著才會突然看到與內容無關的廣告。這種情況會造成使用者體驗不佳,建議避免。
如要在冷啟動時放送應用程式開啟頁面廣告,建議將廣告放在載入畫面,並同時載入遊戲或應用程式的素材資源。若應用程式已載入完畢並進入主要內容頁面,則不應再顯示廣告。
最佳做法
Google 特別打造應用程式開啟頁面廣告,協助您利用應用程式的載入畫面營利。不過,為了確保使用者享有良好體驗,請務必遵循以下最佳做法:
- 等使用者操作您的應用程式數次後,再顯示第一則應用程式開啟頁面廣告。
- 在使用者等待應用程式載入的期間,顯示應用程式開啟頁面廣告。
- 如果載入畫面是在應用程式開啟頁面廣告的背景執行,而且在廣告關閉前已載入完畢,建議使用
adDidDismissFullScreenContent
方法關閉載入畫面。
GitHub 完整範例程式碼
後續步驟
進一步瞭解使用者隱私。