开屏广告

本指南适用于植入开屏广告的发布商。

开屏广告是一种特殊的广告格式,适合希望通过应用加载屏幕获利的发布商。用户可以随时关闭开屏广告。开屏广告可以在用户将您的应用切换为在前台运行时展示。

开屏广告会自动显示一个较小的区域并在其中展示品牌信息,让用户知道他们在使用您的应用。以下是一个开屏广告示例:

概括来讲,植入开屏广告需要执行的步骤如下:

  1. 向您的 AppDelegate 添加方法,以加载并显示 GADAppOpenAd
  2. 检测应用前台事件。
  3. 处理展示回调。

前提条件

务必用测试广告进行测试

在构建和测试应用时,请确保使用的是测试广告,而不是实际投放的广告。否则,可能会导致您的帐号被暂停。

对于开屏广告,加载测试广告最简便的方法就是使用下面的测试专用广告单元 ID:

ca-app-pub-3940256099942544/5662855259

该测试广告单元 ID 已经过专门配置,可确保每个请求返回的都是测试广告。您可以在自己应用的编码、测试和调试过程中随意使用该测试广告单元 ID。只是一定要在发布应用前用您自己的广告单元 ID 替换该测试广告单元 ID。

如需详细了解移动广告 SDK 的测试广告如何运作,请参阅测试广告

修改应用代理

开屏广告会在您的应用启动时或用户将其切换为在前台运行时展示。为确保用户打开您的应用时有广告可以展示,您需要引用随时可用的广告。

这意味着,您必须先预加载一个 GADAppOpenAd,然后才能展示广告。这样一来,开屏广告就可以在下次用户打开应用时展示了。为便于对广告进行单次引用,请将以下属性和方法添加到 AppDelegate.h 中:

#import <GoogleMobileAds/GoogleMobileAds.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property(strong, nonatomic) UIWindow* window;
@property(nonatomic) GADAppOpenAd* appOpenAd;

- (void)requestAppOpenAd;
- (void)tryToPresentAd;

@end

请注意,您应将请求和展示方法设置为在 AppDelegate 类之外也可使用,以便可以在运行 iOS 13 及更高版本的设备上通过 UISceneDelegate 调用这些方法。稍后会对此做进一步说明。

AppDelegate.m 中添加 requestAppOpenAd 方法:

- (void)requestAppOpenAd {
  self.appOpenAd = nil;
  [GADAppOpenAd loadWithAdUnitID:@"ca-app-pub-3940256099942544/5662855259"
                         request:[GADRequest request]
                     orientation:UIInterfaceOrientationPortrait
               completionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {
                 if (error) {
                   NSLog(@"Failed to load app open ad: %@", error);
                   return;
                 }
                 self.appOpenAd = appOpenAd;
               }];
}

此方法会发出加载新的 GADAppOpenAd 的请求。如果成功,它会在 AppDelegate 上设置属性,以便在用户将您的应用切换为在前台运行时,有可以使用的广告。

需要设置屏幕方向。如果屏幕方向设置为 UIInterfaceOrientationUnknown,则 GADAppOpenAd 会假定屏幕方向为纵向。如果您想设计横向布局,请务必将 UIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRight 传递给请求方法,以指定您所需的屏幕方向为横向。

接下来,添加一种方法以展示 AppDelegate 中的广告。

- (void)tryToPresentAd {
  GADAppOpenAd *ad = self.appOpenAd;
  self.appOpenAd = nil;

  if (ad) {
    UIViewController *rootController = self.window.rootViewController;
    [ad presentFromRootViewController:rootController];

  } else {
    // If you don't have an ad ready, request one.
    [self requestAppOpenAd];
  }
}

此方法会检查广告是否存在,如果广告存在并且能够从您的根视图控制器中展示,该方法就会在您现有的内容之上展示广告。如果没有可展示的广告,该方法就会发出新的请求。

检测应用前台事件

当用户首次进入您的应用时,您不可能有可以使用的广告引用。相反,您应该使用上面定义的 tryToPresentAd 方法,该方法会展示广告(如果有),或者请求新的广告。每次您的应用进入前台运行时,都应调用此方法。您可以通过替换 AppDelegate 中的 applicationDidBecomeActive: 方法来完成此操作:

- (void)applicationDidBecomeActive:(UIApplication *)application {
  [self tryToPresentAd];
}

处理展示回调

当应用展示开屏广告时,您应借助 GADFullScreenContentDelegate 处理某些展示事件。在第一个广告展示完毕,需要请求下一个开屏广告时该方法尤其有用。

AppDelegate.h 文件进行以下更改:

#import <GoogleMobileAds/GoogleMobileAds.h>
#import <UIKit/UIKit.h>
@interface AppDelegate
    : UIResponder <UIApplicationDelegate, GADFullScreenContentDelegate>

@property(strong, nonatomic) UIWindow* window;
@property(nonatomic) GADAppOpenAd* appOpenAd;

- (void)requestAppOpenAd;
- (void)tryToPresentAd;

@end

接下来,在您的 AppDelegate.m 文件中添加以下几行代码:

- (void)requestAppOpenAd {
  self.appOpenAd = nil;
  [GADAppOpenAd loadWithAdUnitID:@"ca-app-pub-3940256099942544/5662855259"
                         request:[GADRequest request]
                     orientation:UIInterfaceOrientationPortrait
               completionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {
                 if (error) {
                   NSLog(@"Failed to load app open ad: %@", error);
                   return;
                 }
                 self.appOpenAd = appOpenAd;
                 self.appOpenAd.fullScreenContentDelegate = self;
               }];
}

#pragma mark - GADFullScreenContentDelegate

/// Tells the delegate that the ad failed to present full screen content.
- (void)ad:(nonnull id<GADFullScreenPresentingAd>)ad
    didFailToPresentFullScreenContentWithError:(nonnull NSError *)error {
  NSLog(@"didFailToPresentFullSCreenCContentWithError");
  [self requestAppOpenAd];

}

/// Tells the delegate that the ad presented full screen content.
- (void)adDidPresentFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
  NSLog(@"adDidPresentFullScreenContent");
}

/// Tells the delegate that the ad dismissed full screen content.
- (void)adDidDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
  NSLog(@"adDidDismissFullScreenContent");
  [self requestAppOpenAd];
}
...

这些回调会处理开屏广告生命周期中的各种事件。

考虑广告有效期

为确保您不会展示过期的广告,您可以在应用代理中添加一个方法,该方法会检查您的广告引用加载后经过的时间。

在您的 AppDelegate.h 中,添加一个 NSDate 属性:

#import <GoogleMobileAds/GoogleMobileAds.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property(strong, nonatomic) UIWindow* window;
@property(nonatomic) GADAppOpenAd* appOpenAd;
@property(weak, nonatomic) NSDate *loadTime;

- (void)requestAppOpenAd;
- (void)tryToPresentAd;

@end

然后,您可以添加一个方法,该方法会在广告加载后经过的时间少于一定的小时数时返回 true

AppDelegate.m 中添加以下方法:

- (BOOL)wasLoadTimeLessThanNHoursAgo:(int)n {
  NSDate *now = [NSDate date];
  NSTimeInterval timeIntervalBetweenNowAndLoadTime = [now timeIntervalSinceDate:self.loadTime];
  double secondsPerHour = 3600.0;
  double intervalInHours = timeIntervalBetweenNowAndLoadTime / secondsPerHour;
  return intervalInHours < n;
}

下一步是在广告加载时设置 loadTime 属性:

- (void)requestAppOpenAd {
  self.appOpenAd = nil;
  [GADAppOpenAd loadWithAdUnitID:@"ca-app-pub-3940256099942544/5662855259"
                         request:[GADRequest request]
                     orientation:UIInterfaceOrientationPortrait
               completionHandler:^(GADAppOpenAd *_Nullable appOpenAd, NSError *_Nullable error) {
                 if (error) {
                   NSLog(@"Failed to load app open ad: %@", error);
                   return;
                 }
                 self.appOpenAd = appOpenAd;
                 self.appOpenAd.fullScreenContentDelegate = self;
                 self.loadTime = [NSDate date];
               }];
}

最后,请务必先检查广告引用的有效性,然后再尝试展示广告:

- (void)tryToPresentAd {
  GADAppOpenAd *ad = self.appOpenAd;
  self.appOpenAd = nil;
  if (ad && [self wasLoadTimeLessThanNHoursAgo:4]) {
    UIViewController *rootController = self.window.rootViewController;
    [ad presentFromRootViewController:rootController];

  } else {
    // If you don't have an ad ready, request one.
    [self requestAppOpenAd];
  }
}

冷启动和加载屏幕

上述文档内容都假定您仅在以下情况下展示开屏广告:用户将在内存中挂起的应用切换为在前台运行。用户启动您的应用,但该应用之前未在内存中挂起,这种情况就称为“冷启动”。

例如,用户首次打开您的应用便属于冷启动。对于冷启动,您没有之前已加载的开屏广告可供立即展示。请求广告和收到相应广告之间的延迟会导致出现以下情况:用户能够暂时使用您的应用,然后突然看到一条无关广告。应避免出现这种情况,因为这会导致用户体验不佳。

在冷启动时使用开屏广告的首选方法是,使用加载屏幕来加载游戏或应用素材资源,并且仅在加载屏幕展示广告。如果您的应用已加载完毕,并且用户已经访问应用的主要内容,则不要展示广告。

最佳做法

借助 Google 打造的开屏广告,您可以通过应用的加载屏幕获利,不过,还请务必考虑一些最佳做法,以便用户喜欢使用您的应用。请务必遵循以下做法:

  • 等待用户使用几次您的应用后,再展示第一个开屏广告。
  • 在用户等待您的应用加载时展示开屏广告。
  • 如果开屏广告位于加载屏幕上,并且加载屏幕在用户关闭广告之前已加载完毕,您可能需要通过 adDidDismissFullScreenContent 方法关闭加载屏幕。