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

الإعلانات التي تضم مكافأة هي إعلانات يتوفّر للمستخدمين خيار التفاعل معها مقابل مكافآت داخل التطبيق. يوضّح لك هذا الدليل كيفية دمج الإعلانات التي تضم مكافآت من 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. في حال عدم ضبط قيمة بيانات مخصّصة، لن تكون قيمة معلَمة طلب البحث custom_data متوفّرة في استدعاء SSV.

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

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.")
  }
}

واجهة المستخدم

تحديد السمة 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.
  }
}

واجهة المستخدم

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

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

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

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

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

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

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

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

أمثلة على GitHub

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

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

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