Quảng cáo khi mở ứng dụng

Tài liệu hướng dẫn này dành cho các nhà xuất bản muốn tích hợp quảng cáo khi mở ứng dụng.

Quảng cáo khi mở ứng dụng là một định dạng quảng cáo đặc biệt dành cho những nhà xuất bản muốn kiếm tiền từ màn hình tải ứng dụng của họ. Người dùng có thể đóng quảng cáo khi mở ứng dụng bất cứ lúc nào. Quảng cáo khi mở ứng dụng có thể xuất hiện khi người dùng chạy ứng dụng của bạn trên nền trước.

Quảng cáo khi mở ứng dụng tự động hiển thị một vùng nhỏ chứa thông tin thương hiệu để người dùng biết họ đang mở ứng dụng của bạn. Dưới đây là một ví dụ về cách hiển thị của quảng cáo khi mở ứng dụng:

Cụ thể hơn, dưới đây là các bước bắt buộc để triển khai quảng cáo khi mở ứng dụng:

  1. Tạo một lớp trình quản lý sẽ tải quảng cáo trước khi bạn cần hiển thị quảng cáo đó.
  2. Hiển thị quảng cáo trong các sự kiện đưa ứng dụng lên nền trước.
  3. Xử lý lệnh gọi lại bản trình bày.

Điều kiện tiên quyết

Luôn thử nghiệm bằng quảng cáo thử nghiệm

Khi tạo và thử nghiệm ứng dụng, hãy nhớ sử dụng quảng cáo thử nghiệm thay vì quảng cáo đang chạy trong thực tế. Nếu không làm như vậy, tài khoản của bạn có thể bị tạm ngưng.

Cách dễ nhất để tải quảng cáo thử nghiệm là dùng mã đơn vị quảng cáo thử nghiệm chúng tôi dành riêng cho quảng cáo khi mở ứng dụng:

/21775744923/example/app-open

Mã này được định cấu hình đặc biệt để trả về quảng cáo thử nghiệm cho mọi yêu cầu và bạn có thể sử dụng mã này trong ứng dụng của mình khi lập trình, chạy thử nghiệm và gỡ lỗi. Bạn chỉ cần nhớ thay thế mã này bằng mã đơn vị quảng cáo của mình trước khi xuất bản ứng dụng.

Để biết thêm thông tin về cách hoạt động của quảng cáo thử nghiệm của SDK quảng cáo trên thiết bị di động, hãy xem bài viết Quảng cáo thử nghiệm.

Triển khai lớp trình quản lý

Quảng cáo của bạn cần phải nhanh chóng hiển thị. Do đó, tốt nhất là bạn nên tải quảng cáo trước khi cần hiển thị quảng cáo. Khi bạn làm như vậy, quảng cáo sẽ sẵn sàng hoạt động ngay khi người dùng truy cập vào ứng dụng của bạn. Hãy triển khai một lớp trình quản lý để thực hiện các yêu cầu quảng cáo trước khi bạn cần hiển thị quảng cáo.

Tạo một lớp singleton mới có tên là AppOpenAdManager và điền vào lớp đó như sau:

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

Tải quảng cáo

Bước tiếp theo là điền vào phương thức 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;
             }];
}

Hiển thị quảng cáo

Bước tiếp theo là điền vào phương thức showAdIfAvailable(). Nếu không có quảng cáo, phương thức này sẽ cố gắng tải quảng cáo.

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

Hiển thị quảng cáo trong các sự kiện đưa ứng dụng lên nền trước

Khi ứng dụng hoạt động, hãy gọi showAdIfAvailable() để hiển thị quảng cáo nếu có hoặc tải quảng cáo mới.

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

Xử lý lệnh gọi lại bản trình bày

Khi ứng dụng của bạn hiển thị quảng cáo khi mở ứng dụng, bạn nên dựa vào GADFullScreenContentDelegate để xử lý một số sự kiện nhất định về bản trình bày. Đặc biệt, bạn sẽ muốn yêu cầu quảng cáo khi mở ứng dụng tiếp theo khi quảng cáo đầu tiên hiển thị xong.

Trong lớp AppOpenAdManager, hãy thêm nội dung sau:

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

Xem xét thời hạn của quảng cáo

Để đảm bảo không hiển thị quảng cáo đã hết hạn, bạn có thể thêm một phương thức vào thực thể đại diện cho ứng dụng để kiểm tra khoảng thời gian kể từ khi tệp đối chiếu quảng cáo của bạn được tải.

Trong AppOpenAdManager, hãy thêm thuộc tính Date có tên là loadTime và đặt thuộc tính này khi quảng cáo của bạn tải. Sau đó, bạn có thể thêm một phương thức trả về true nếu số giờ trôi qua kể từ khi quảng cáo của bạn được tải thấp hơn một mức nhất định. Hãy nhớ kiểm tra tính hợp lệ của tệp tham chiếu quảng cáo trước khi cố gắng hiển thị quảng cáo.

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

Khởi động nguội và màn hình tải

Tài liệu này giả định rằng bạn chỉ hiển thị quảng cáo khi mở ứng dụng tại thời điểm người dùng đưa ứng dụng của bạn lên nền trước khi ứng dụng đang tạm ngưng trong bộ nhớ. Quy trình "Khởi động nguội" xảy ra khi người dùng chạy ứng dụng của bạn nhưng trước đó, ứng dụng không bị tạm ngưng trong bộ nhớ.

Một ví dụ về khởi động nguội là khi người dùng mở ứng dụng của bạn lần đầu tiên. Trong trường hợp khởi động nguội, quảng cáo khi mở ứng dụng chưa được tải trước lần nào nên chưa sẵn sàng để hiển thị ngay lập tức. Một tình huống có thể xảy ra trong khoảng thời gian từ khi bạn yêu cầu quảng cáo cho đến khi nhận được quảng cáo (gọi là độ trễ), đó là người dùng vừa mới sử dụng ứng dụng của bạn trong chốc lát thì một quảng cáo không phù hợp đột ngột xuất hiện khiến họ bị bất ngờ. Bạn nên tránh làm như vậy vì điều này sẽ tạo ra trải nghiệm kém cho người dùng.

Để sử dụng quảng cáo khi mở ứng dụng vào lúc khởi động nguội, cách tốt nhất là bạn nên dùng màn hình tải để tải các thành phần trò chơi hoặc ứng dụng và chỉ nên hiển thị quảng cáo trên màn hình tải. Bạn đừng hiển thị quảng cáo nếu ứng dụng đã tải xong và đã đưa người dùng đến nội dung chính của ứng dụng.

Các phương pháp hay nhất

Google tạo quảng cáo khi mở ứng dụng để giúp bạn kiếm tiền từ màn hình tải của ứng dụng, nhưng bạn nên áp dụng các phương pháp hay nhất để người dùng hài lòng khi sử dụng ứng dụng của bạn. Hãy nhớ:

  • Chờ người dùng sử dụng ứng dụng của bạn vài lần rồi mới hiển thị quảng cáo khi mở ứng dụng đầu tiên.
  • Hiển thị quảng cáo khi mở ứng dụng trong thời gian người dùng chờ ứng dụng của bạn tải.
  • Nếu bạn có màn hình tải trong quảng cáo khi mở ứng dụng và màn hình tải đó đã tải xong trước khi quảng cáo bị đóng, thì bạn nên đóng màn hình tải theo phương thức adDidDismissFullScreenContent.

Ví dụ hoàn chỉnh trên GitHub

Swift Objective-C

Các bước tiếp theo

Tìm hiểu thêm về quyền riêng tư của người dùng.