מודעות בפתיחת האפליקציה

המדריך הזה מיועד לבעלי אפליקציות שמשלבים מודעות בפתיחת האפליקציה.

מודעות בפתיחת האפליקציה הן פורמט מודעה מיוחד שמיועד לבעלי אפליקציות שרוצים לייצר הכנסות ממסכי הטעינה של האפליקציה. המשתמשים יכולים לסגור את המודעות בפתיחת האפליקציה בכל שלב. מודעות בפתיחת האפליקציה יכולות להופיע כשהמשתמשים מעבירים את האפליקציה לחזית.

במודעות בפתיחת האפליקציה מוצג באופן אוטומטי אזור מיתוג קטן, כדי שהמשתמשים ידעו שהם נמצאים באפליקציה שלכם. הנה דוגמה למודעה בפתיחת האפליקציה:

ככלל, אלה השלבים הנדרשים כדי להטמיע מודעות בפתיחת האפליקציה:

  1. יוצרים מחלקת מנהל שטוענת מודעה לפני שצריך להציג אותה.
  2. הצגת המודעה במהלך אירועים של אפליקציה שפועלת בחזית.
  3. טיפול בקריאות חוזרות (callbacks) של המצגת.

דרישות מוקדמות

תמיד צריך לבדוק באמצעות מודעות בדיקה

כשאתם מפתחים ובודקים את האפליקציות, חשוב להשתמש במודעות בדיקה ולא במודעות פעילות. אחרת, אנחנו עלולים להשעות את החשבון.

הדרך הכי קלה לטעון מודעות לבדיקה היא להשתמש במזהה יחידת המודעות הייעודי לבדיקה של מודעות בפתיחת האפליקציה:

/21775744923/example/app-open

הוא הוגדר במיוחד כדי להחזיר מודעות בדיקה לכל בקשה, ואתם יכולים להשתמש בו באפליקציות שלכם בזמן התכנות, הבדיקה וניפוי הבאגים. רק חשוב להחליף אותו במזהה יחידת המודעות שלכם לפני שמפרסמים את האפליקציה.

מידע נוסף על אופן הפעולה של מודעות בדיקה ב-Google 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];
}

טיפול בקריאות חוזרות (callbacks) של המצגת

כדי לקבל התראות על אירועי הצגה, צריך להקצות את 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];
}

כדאי להביא בחשבון את תפוגת התוקף של המודעות

כדי לוודא שלא תוצג מודעה שפג תוקפה, אפשר להוסיף ל-app delegate שיטה שבודקת את הזמן שחלף מאז שנטען קובץ העזר של המודעה.

ב-AppOpenAdManager, מוסיפים מאפיין Date בשם loadTime ומגדירים את המאפיין כשהמודעה נטענת. לאחר מכן, אפשר להוסיף שיטה שמחזירה את הערך 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];
}

הפעלות במצב התחלתי (cold start) ומסכי טעינה

ההנחה במסמכי התיעוד היא שאתם מציגים מודעות בפתיחת האפליקציה רק כשמשתמשים מעבירים את האפליקציה לחזית כשהיא מושהית בזיכרון. "הפעלות קרות" מתרחשות כשהאפליקציה מופעלת אבל לא הושעתה קודם בזיכרון.

דוגמה להפעלה במצב התחלתי היא כשמשתמש פותח את האפליקציה בפעם הראשונה. בהפעלה במצב התחלתי, אין מודעה בפתיחת האפליקציה שנטענה מראש ומוכנה להצגה מיידית. העיכוב בין שליחת הבקשה להצגת מודעה לבין קבלת המודעה בחזרה יכול ליצור מצב שבו המשתמשים יכולים להשתמש באפליקציה לזמן קצר, ואז פתאום מופיעה מודעה שלא קשורה להקשר. כדאי להימנע מכך כי זה פוגע בחוויית המשתמש.

הדרך המועדפת להשתמש במודעות בפתיחת האפליקציה בהפעלות קרות היא להשתמש במסך טעינה כדי לטעון את נכסי המשחק או האפליקציה, ולהציג את המודעה רק ממסך הטעינה. אם האפליקציה סיימה להיטען והמשתמש הועבר לתוכן הראשי שלה, אל תציגו את המודעה.

שיטות מומלצות

Google פיתחה את המודעות בפתיחת האפליקציה כדי לעזור לכם לייצר הכנסות ממסך הטעינה של האפליקציה, אבל חשוב לפעול לפי השיטות המומלצות כדי שהמשתמשים ייהנו מהשימוש באפליקציה. הקפידו:

  • מומלץ להמתין עם הצגת המודעה הראשונה בפתיחת האפליקציה עד שהמשתמשים ישתמשו באפליקציה כמה פעמים.
  • כדאי להציג מודעות בפתיחת האפליקציה בזמנים שבהם המשתמשים ממתינים שהאפליקציה תיטען.
  • אם יש לכם מסך טעינה מתחת למודעה בפתיחת האפליקציה, והטעינה של מסך הטעינה מסתיימת לפני שהמודעה נסגרת, יכול להיות שתרצו לסגור את מסך הטעינה ב-method‏ adDidDismissFullScreenContent.

דוגמה פתורה ב-GitHub

Swift Objective-C

השלבים הבאים

מידע נוסף על פרטיות המשתמשים