الإعلانات بمكافأة

الإعلانات التي تضم مكافآت هي إعلانات يمكن للمستخدمين التفاعل معها في مقابل حصولهم على مكافآت داخل التطبيق. يوضّح لك هذا الدليل كيفية دمج الإعلانات التي تضم مكافآت من AdMob في تطبيق iOS. اطّلِع على بعض قصص نجاح العملاء: دراسة الحالة 1، دراسة الحالة 2.

المتطلبات الأساسية

  • الإصدار 8.0.0 من حزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة أو إصدار أحدث
  • أكمِل دليل البدء.

إجراء الاختبار دائمًا باستخدام الإعلانات الاختبارية

عند إنشاء تطبيقاتك واختبارها، احرص على استخدام إعلانات اختبارية بدلاً من الإعلانات المنشورة. وقد يؤدي عدم إجراء ذلك إلى تعليق حسابك.

إنّ الطريقة الأسهل لتحميل الإعلانات التجريبية هي استخدام رقم تعريف الوحدة الإعلانية الاختبارية المخصّص للإعلانات التي تضم مكافآت على نظام التشغيل iOS:

ca-app-pub-3940256099942544/1712485313

تم إعداده خصيصًا لعرض إعلانات اختبارية لكل طلب، ويمكنك استخدامه في تطبيقاتك أثناء الترميز والاختبار وتحديد الأخطاء وإصلاحها. ما عليك سوى التأكّد من استبداله بمعرّف وحدتك الإعلانية قبل نشر تطبيقك.

لمزيد من المعلومات عن آلية عمل الإعلانات الاختبارية في حزمة "SDK لإعلانات Google على الأجهزة الجوّالة"، اطّلِع على الإعلانات الاختبارية.

التنفيذ

في ما يلي الخطوات الأساسية لدمج الإعلانات التي تضم مكافآت:

  • تحميل إعلان
  • [اختياري] التحقّق من صحة عمليات ردّ الاتصال في عملية "التحقّق من جانب الخادم"
  • التسجيل لتلقّي مكالمات من فريق الدعم
  • عرض الإعلان والتعامل مع حدث المكافأة

تحميل إعلان

يتم تحميل الإعلان باستخدام الطريقة load(adUnitID:request) في فئة GADRewardedAd.

Swift

import GoogleMobileAds
import UIKit

class ViewController: UIViewController {

  private var rewardedAd: GADRewardedAd?

  func loadRewardedAd() async {
    do {
      rewardedAd = try await GADRewardedAd.load(
        withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
    } catch {
      print("Rewarded ad failed to load with error: \(error.localizedDescription)")
    }
  }
}

SwiftUI

import GoogleMobileAds

class RewardedViewModel: NSObject, ObservableObject, GADFullScreenContentDelegate {
  @Published var coins = 0
  private var rewardedAd: GADRewardedAd?

  func loadAd() async {
    do {
      rewardedAd = try await GADRewardedAd.load(
        withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
      rewardedAd?.fullScreenContentDelegate = self
    } catch {
      print("Failed to load rewarded ad with error: \(error.localizedDescription)")
    }
  }

Objective-C

@import GoogleMobileAds;
@import UIKit;

@interface ViewController ()

@property(nonatomic, strong) GADRewardedAd *rewardedAd;

@end

@implementation ViewController
- (void)loadRewardedAd {
  GADRequest *request = [GADRequest request];
  [GADRewardedAd
      loadWithAdUnitID:@"ca-app-pub-3940256099942544/1712485313"
                request:request
      completionHandler:^(GADRewardedAd *ad, NSError *error) {
        if (error) {
          NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]);
          return;
        }
        self.rewardedAd = ad;
        NSLog(@"Rewarded ad loaded.");
      }];
}

[اختياري] التحقّق من صحة عمليات ردّ الاتصال في عملية إثبات الملكية من جهة الخادم

يجب أن تستخدم التطبيقات التي تتطلّب بيانات إضافية في عمليات استدعاء التحقّق على جهة الخادم ميزة البيانات المخصّصة للإعلانات التي تضم مكافآت. يتمّ تمرير أيّ قيمة سلسلة تمّ ضبطها على عنصر إعلان مكافأة إلى مَعلمة طلب البحث custom_data في طلب استدعاء SSV. في حال عدم تحديد قيمة data custom، لن تكون قيمة مَعلمة طلب البحث custom_data متوفرة في دالة SSV callback.

يوضّح نموذج الرمز البرمجي التالي كيفية ضبط بيانات مخصّصة على عنصر إعلان مقابل مكافأة قبل طلب إعلان.

Swift

do {
  rewardedAd = try await GADRewardedAd.load(
    withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
  let options = GADServerSideVerificationOptions()
  options.customRewardString = "SAMPLE_CUSTOM_DATA_STRING"
  rewardedAd.serverSideVerificationOptions = options
} catch {
  print("Rewarded ad failed to load with error: \(error.localizedDescription)")
}

Objective-C

[GADRewardedAd
     loadWithAdUnitID:@"ca-app-pub-3940256099942544/1712485313"
              request:[GADRequest request];
    completionHandler:^(GADRewardedAd *ad, NSError *error) {
      if (error) {
        // Handle Error
        return;
      }
      self.rewardedAd = ad;
      GADServerSideVerificationOptions *options =
          [[GADServerSideVerificationOptions alloc] init];
      options.customRewardString = @"SAMPLE_CUSTOM_DATA_STRING";
      ad.serverSideVerificationOptions = options;
    }];

التسجيل لتلقّي مكالمات من فريق الدعم

لتلقّي إشعارات عن أحداث العرض، عليك تنفيذ بروتوكول GADFullScreenContentDelegate وتخصيصه للخاصية fullScreenContentDelegate للإعلان المعروض. يعالج بروتوكول GADFullScreenContentDelegate عمليات الاستدعاء المتعلّقة بعرض الإعلان بنجاح أو عدم نجاحه، ووقت إغلاقه. يوضّح الرمز البرمجي التالي كيفية تنفيذ البروتوكول وتخصيصه للإعلان:

Swift

import GoogleMobileAds
import UIKit

class ViewController: UIViewController, GADFullScreenContentDelegate {

  private var rewardedAd: GADRewardedAd?

  func loadRewardedAd() async {
    do {
      rewardedAd = try await GADRewardedAd.load(
        withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
      rewardedAd?.fullScreenContentDelegate = self
    } catch {
      print("Rewarded ad failed to load with error: \(error.localizedDescription)")
    }
  }

  /// Tells the delegate that the ad failed to present full screen content.
  func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
    print("Ad did fail to present full screen content.")
  }

  /// Tells the delegate that the ad will present full screen content.
  func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
    print("Ad will present full screen content.")
  }

  /// Tells the delegate that the ad dismissed full screen content.
  func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
    print("Ad did dismiss full screen content.")
  }
}

SwiftUI

خصِّص السمة fullScreenContentDelegate للإعلان الذي تم عرضه:

rewardedAd?.fullScreenContentDelegate = self

تنفيذ البروتوكول:

func adDidRecordImpression(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func adDidRecordClick(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func ad(
  _ ad: GADFullScreenPresentingAd,
  didFailToPresentFullScreenContentWithError error: Error
) {
  print("\(#function) called")
}

func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func adWillDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
  // Clear the rewarded ad.
  rewardedAd = nil
}

Objective-C

@interface ViewController () <GADFullScreenContentDelegate>

@property(nonatomic, strong) GADRewardedAd *rewardedAd;

@end

@implementation ViewController
- (void)loadRewardedAd {
  GADRequest *request = [GADRequest request];
  [GADRewardedAd
      loadWithAdUnitID:@"ca-app-pub-3940256099942544/4806952744"
                request:request
      completionHandler:^(GADRewardedAd *ad, NSError *error) {
        if (error) {
          NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]);
          return;
        }
        self.rewardedAd = ad;
        NSLog(@"Rewarded ad loaded.");
        self.rewardedAd.fullScreenContentDelegate = self;
      }];
}

/// Tells the delegate that the ad failed to present full screen content.
- (void)ad:(nonnull id<GADFullScreenPresentingAd>)ad
    didFailToPresentFullScreenContentWithError:(nonnull NSError *)error {
    NSLog(@"Ad did fail to present full screen content.");
}

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

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

GADRewardedAd هو عنصر للاستخدام لمرة واحدة. وهذا يعني أنّه بعد عرض إعلان يقدّم مكافأة، لا يمكن عرضه مرة أخرى. ومن أفضل الممارسات تحميل إعلان مكافأة آخر باستخدام طريقة adDidDismissFullScreenContent: في GADFullScreenContentDelegate كي يبدأ تحميل الإعلان المكافأة التالي فور إغلاق الإعلان السابق.

عرض الإعلان والتعامل مع حدث المكافأة

قبل عرض إعلان يضم مكافأة للمستخدمين، يجب منح المستخدم خيارًا واضحًا لعرض محتوى الإعلان الذي يضم مكافأة مقابل مكافأة. يجب أن تكون الإعلانات التي تضم مكافآت اختيارية في جميع الأوقات.

عند عرض إعلانك، يجب تقديم عنصر GADUserDidEarnRewardHandler لمعالجة المكافأة للمستخدم.

يقدّم الرمز البرمجي التالي أفضل طريقة لعرض إعلان بمكافأة.

Swift

func show() {
  guard let rewardedAd = rewardedAd else {
    return print("Ad wasn't ready.")
  }

  // The UIViewController parameter is an optional.
  ad.present(fromRootViewController: nil) {
    let reward = ad.adReward
    print("Reward received with currency \(reward.amount), amount \(reward.amount.doubleValue)")
    // TODO: Reward the user.
  }
}

SwiftUI

راقِب أحداث واجهة المستخدم في العرض لتحديد وقت عرض الإعلان.

var body: some View {
  VStack(spacing: 20) {
      Button("Watch video for additional 10 coins") {
        viewModel.showAd()
        showWatchVideoButton = false
      }

عرض الإعلان الذي يضم مكافأة من نموذج العرض:

func showAd() {
  guard let rewardedAd = rewardedAd else {
    return print("Ad wasn't ready.")
  }

  rewardedAd.present(fromRootViewController: nil) {
    let reward = rewardedAd.adReward
    print("Reward amount: \(reward.amount)")
    self.addCoins(reward.amount.intValue)
  }
}

Objective-C

- (void)show {
  if (self.rewardedAd) {
    // The UIViewController parameter is nullable.
    [self.rewardedAd presentFromRootViewController:nil
                                  userDidEarnRewardHandler:^{
                                  GADAdReward *reward =
                                      self.rewardedAd.adReward;
                                  // TODO: Reward the user!
                                }];
  } else {
    NSLog(@"Ad wasn't ready");
  }
}

الأسئلة الشائعة

هل يمكنني الحصول على تفاصيل المكافأة الخاصة بـ GADRewardedAd؟
نعم، إذا كنت بحاجة إلى مبلغ المكافأة قبل بدء userDidEarnReward callback ، يحتوي GADRewardedAd على adReward خاصية يمكنك التحقّق منها للتأكّد من مبلغ المكافأة بعد تحميل الإعلان.
هل هناك مهلة لمكالمة الإعداد؟
بعد 10 ثوانٍ، تستدعي حزمة "SDK لإعلانات Google على الأجهزة الجوّالة" القيمة GADInitializationCompletionHandler المقدَّمة إلى الأسلوب startWithCompletionHandler:، حتى إذا لم تكن شبكة التوسّط قد اكتملت عملية الإعداد.
ماذا لو لم تكن بعض شبكات التوسّط جاهزة عند تلقّي طلب إعادة الاتصال لبدء عملية الإعداد؟

ننصحك بتحميل إعلان داخل GADInitializationCompletionHandler. حتى إذا لم تكن شبكة التوسّط جاهزة، تستمر حزمة "SDK لإعلانات Google على الأجهزة الجوّالة" في طلب إعلان من تلك الشبكة. وبالتالي، إذا اكتملت عملية بدء شبكة التوسّط بعد انتهاء مهلة الانتظار، سيظل بإمكانها عرض طلبات الإعلانات المستقبلية في تلك الجلسة.

يمكنك مواصلة الاستعلام عن حالة بدء جميع المحوِّلات على مدار جلسة تطبيقك من خلال استدعاء GADMobileAds.initializationStatus.

كيف يمكنني معرفة سبب عدم جاهزية شبكة توسّط معيّنة؟

توضِّح سمة description لعنصر GADAdapterStatus سبب عدم جاهزية المحوِّل لعرض طلبات الإعلانات.

هل يتم دائمًا استدعاء معالِج الإنجاز userDidEarnRewardHandler قبل طريقة التفويض adDidDismissFullScreenContent:؟

بالنسبة إلى إعلانات Google، تحدث جميع المكالمات التي تبلغ مدتها userDidEarnRewardHandler قبل adDidDismissFullScreenContent:. بالنسبة إلى الإعلانات التي يتم عرضها من خلال التوسّط، يحدّد تنفيذ حزمة تطوير البرامج (SDK) لشبكة المواقع الإعلانية التابعة لجهة خارجية ترتيب طلب الاستدعاء. بالنسبة إلى حِزم SDK لشبكات الإعلانات التي توفّر طريقة واحدة مفوَّضة تتضمّن معلومات المكافأة، يشغِّل محوِّل التوسّط userDidEarnRewardHandler قبل adDidDismissFullScreenContent:.

أمثلة على GitHub

يمكنك الاطّلاع على أمثلة كاملة على الإعلانات التي تضم مكافآت بلغتك المفضّلة:

الخطوات التالية

مزيد من المعلومات عن خصوصية المستخدمين