المتطلبات الأساسية
أكمِل عملية إعداد الأحاف المخصّصة.
طلب إعلان مدمج مع المحتوى
عند الوصول إلى بند الحدث المخصّص في سلسلة توسّط العرض الإعلاني بدون انقطاع، يتم استدعاء الطريقة loadNativeAd:adConfiguration:completionHandler: باسم الفئة الذي قدّمته عند إنشاء حدث مخصّص. في هذه الحالة،
توجد هذه الطريقة في SampleCustomEvent، التي تستدعي بعد ذلك
الطريقة loadNativeAd:adConfiguration:completionHandler: في
SampleCustomEventNative.
لطلب إعلان مدمج مع المحتوى، أنشئ فئة أو عدِّلها لتنفيذ GADMediationAdapter وloadNativeAd:adConfiguration:completionHandler:. إذا كانت هناك فئة توسّع GADMediationAdapter، نفِّذ loadNativeAd:adConfiguration:completionHandler: فيها. بالإضافة إلى ذلك، أنشئ فئة جديدة لتنفيذ GADMediationNativeAd.
في مثال الحدث المخصّص،
SampleCustomEvent تنفِّذ
واجهة GADMediationAdapter ثم تفوّضها إلى
SampleCustomEventNative.
Swift
import GoogleMobileAds class SampleCustomEvent: NSObject, MediationAdapter { fileprivate var nativeAd: SampleCustomEventNativeAd? func loadNativeAd( for adConfiguration: MediationNativeAdConfiguration, completionHandler: @escaping GADMediationNativeAdLoadCompletionHandler ) { self.nativeAd = SampleCustomEventNativeAd() self.nativeAd?.loadNativeAd( for: adConfiguration, completionHandler: completionHandler) } }
Objective-C
#import "SampleCustomEvent.h" @implementation SampleCustomEvent SampleCustomEventNativeAd *sampleNativeAd; - (void)loadNativeAdForAdConfiguration: (GADMediationNativeAdConfiguration *)adConfiguration completionHandler: (GADMediationNativeAdLoadCompletionHandler) completionHandler { sampleNative = [[SampleCustomEventNativeAd alloc] init]; [sampleNative loadNativeAdForAdConfiguration:adConfiguration completionHandler:completionHandler]; }
SampleCustomEventNative` مسؤولة عن المهام التالية:
تحميل الإعلان المدمج مع المحتوى
تنفيذ بروتوكول
GADMediationNativeAdتلقّي عمليات معاودة الاتصال بأحداث الإعلانات وإرسالها إلى Google Mobile Ads SDK
يتم تضمين المَعلمة الاختيارية المحدّدة في واجهة مستخدم AdMob في إعداد الإعلان.
يمكن الوصول إلى المَعلمة من خلال
adConfiguration.credentials.settings[@"parameter"]. عادةً ما تكون هذه المَعلمة هي معرّف وحدة إعلانية تتطلبه حزمة تطوير البرامج (SDK) لشبكة إعلانية عند إنشاء كائن إعلان.
Swift
class SampleCustomEventNativeAd: NSObject, MediationNativeAd { /// The Sample Ad Network native ad. var nativeAd: SampleNativeAd? /// The ad event delegate to forward ad rendering events to the Google Mobile /// Ads SDK. var delegate: MediationNativeAdEventDelegate? /// Completion handler called after ad load var completionHandler: GADMediationNativeLoadCompletionHandler? func loadNativeAd( for adConfiguration: MediationNativeAdConfiguration, completionHandler: @escaping GADMediationNativeLoadCompletionHandler ) { let adLoader = SampleNativeAdLoader() let sampleRequest = SampleNativeAdRequest() // Google Mobile Ads SDK requires the image assets to be downloaded // automatically unless the publisher specifies otherwise by using the // GADNativeAdImageAdLoaderOptions object's disableImageLoading property. If // your network doesn't have an option like this and instead only ever // returns URLs for images (rather than the images themselves), your adapter // should download image assets on behalf of the publisher. This should be // done after receiving the native ad object from your network's SDK, and // before calling the connector's adapter:didReceiveMediatedNativeAd: method. sampleRequest.shouldDownloadImages = true sampleRequest.preferredImageOrientation = NativeAdImageOrientation.any sampleRequest.shouldRequestMultipleImages = false let options = adConfiguration.options for loaderOptions: AdLoaderOptions in options { if let imageOptions = loaderOptions as? NativeAdImageAdLoaderOptions { sampleRequest.shouldRequestMultipleImages = imageOptions.shouldRequestMultipleImages // If the GADNativeAdImageAdLoaderOptions' disableImageLoading property is // YES, the adapter should send just the URLs for the images. sampleRequest.shouldDownloadImages = !imageOptions.disableImageLoading } else if let mediaOptions = loaderOptions as? NativeAdMediaAdLoaderOptions { switch mediaOptions.mediaAspectRatio { case MediaAspectRatio.landscape: sampleRequest.preferredImageOrientation = NativeAdImageOrientation.landscape case MediaAspectRatio.portrait: sampleRequest.preferredImageOrientation = NativeAdImageOrientation.portrait default: sampleRequest.preferredImageOrientation = NativeAdImageOrientation.any } } } // This custom event uses the server parameter to carry an ad unit ID, which // is the most common use case. adLoader.delegate = self adLoader.adUnitID = adConfiguration.credentials.settings["parameter"] as? String self.completionHandler = completionHandler adLoader.fetchAd(sampleRequest) } }
Objective-C
#import "SampleCustomEventNativeAd.h" @interface SampleCustomEventNativeAd () <SampleNativeAdDelegate, GADMediationNativeAd> { /// The sample native ad. SampleNativeAd *_nativeAd; /// The completion handler to call when the ad loading succeeds or fails. GADMediationNativeLoadCompletionHandler _loadCompletionHandler; /// The ad event delegate to forward ad rendering events to the Google Mobile /// Ads SDK. id<GADMediationNativeAdEventDelegate> _adEventDelegate; } @end - (void)loadNativeAdForAdConfiguration: (GADMediationNativeAdConfiguration *)adConfiguration completionHandler:(GADMediationNativeLoadCompletionHandler) completionHandler { __block atomic_flag completionHandlerCalled = ATOMIC_FLAG_INIT; __block GADMediationNativeLoadCompletionHandler originalCompletionHandler = [completionHandler copy]; _loadCompletionHandler = ^id<GADMediationNativeAdEventDelegate>( _Nullable id<GADMediationNativeAd> ad, NSError *_Nullable error) { // Only allow completion handler to be called once. if (atomic_flag_test_and_set(&completionHandlerCalled)) { return nil; } id<GADMediationNativeAdEventDelegate> delegate = nil; if (originalCompletionHandler) { // Call original handler and hold on to its return value. delegate = originalCompletionHandler(ad, error); } // Release reference to handler. Objects retained by the handler will also // be released. originalCompletionHandler = nil; return delegate; }; SampleNativeAdLoader *adLoader = [[SampleNativeAdLoader alloc] init]; SampleNativeAdRequest *sampleRequest = [[SampleNativeAdRequest alloc] init]; // Google Mobile Ads SDK requires the image assets to be downloaded // automatically unless the publisher specifies otherwise by using the // GADNativeAdImageAdLoaderOptions object's disableImageLoading property. If // your network doesn't have an option like this and instead only ever returns // URLs for images (rather than the images themselves), your adapter should // download image assets on behalf of the publisher. This should be done after // receiving the native ad object from your network's SDK, and before calling // the connector's adapter:didReceiveMediatedNativeAd: method. sampleRequest.shouldDownloadImages = YES; sampleRequest.preferredImageOrientation = NativeAdImageOrientationAny; sampleRequest.shouldRequestMultipleImages = NO; sampleRequest.testMode = adConfiguration.isTestRequest; for (GADAdLoaderOptions *loaderOptions in adConfiguration.options) { if ([loaderOptions isKindOfClass:[GADNativeAdImageAdLoaderOptions class]]) { GADNativeAdImageAdLoaderOptions *imageOptions = (GADNativeAdImageAdLoaderOptions *)loaderOptions; sampleRequest.shouldRequestMultipleImages = imageOptions.shouldRequestMultipleImages; // If the GADNativeAdImageAdLoaderOptions' disableImageLoading property is // YES, the adapter should send just the URLs for the images. sampleRequest.shouldDownloadImages = !imageOptions.disableImageLoading; } else if ([loaderOptions isKindOfClass:[GADNativeAdMediaAdLoaderOptions class]]) { GADNativeAdMediaAdLoaderOptions *mediaOptions = (GADNativeAdMediaAdLoaderOptions *)loaderOptions; switch (mediaOptions.mediaAspectRatio) { case GADMediaAspectRatioLandscape: sampleRequest.preferredImageOrientation = NativeAdImageOrientationLandscape; break; case GADMediaAspectRatioPortrait: sampleRequest.preferredImageOrientation = NativeAdImageOrientationPortrait; break; default: sampleRequest.preferredImageOrientation = NativeAdImageOrientationAny; break; } } else if ([loaderOptions isKindOfClass:[GADNativeAdViewAdOptions class]]) { _nativeAdViewAdOptions = (GADNativeAdViewAdOptions *)loaderOptions; } } // This custom event uses the server parameter to carry an ad unit ID, which // is the most common use case. NSString *adUnit = adConfiguration.credentials.settings[@"parameter"]; adLoader.adUnitID = adUnit; adLoader.delegate = self; [adLoader fetchAd:sampleRequest]; }
سواء تم جلب الإعلان بنجاح أو حدث خطأ، عليك استدعاء GADMediationNativeAdLoadCompletionHandler. في حال النجاح، مرِّر الفئة التي تنفِّذ GADMediationNativeAd بقيمة nil لمَعلمة الخطأ، وفي حال الفشل، مرِّر الخطأ الذي واجهته.
عادةً ما يتم تنفيذ هذه الطرق داخل عمليات معاودة الاتصال من حزمة تطوير البرامج (SDK) التابعة لجهة خارجية التي تنفِّذها المحوّل. في هذا المثال، تحتوي حزمة تطوير البرامج (SDK) النموذجية على SampleNativeAdDelegate مع عمليات معاودة الاتصال ذات الصلة:
Swift
func adLoader( _ adLoader: SampleNativeAdLoader, didReceive nativeAd: SampleNativeAd ) { extraAssets = [ SampleCustomEventConstantsSwift.awesomenessKey: nativeAd.degreeOfAwesomeness ?? "" ] if let image = nativeAd.image { images = [NativeAdImage(image: image)] } else { let imageUrl = URL(fileURLWithPath: nativeAd.imageURL) images = [NativeAdImage(url: imageUrl, scale: nativeAd.imageScale)] } if let mappedIcon = nativeAd.icon { icon = NativeAdImage(image: mappedIcon) } else { let iconURL = URL(fileURLWithPath: nativeAd.iconURL) icon = NativeAdImage(url: iconURL, scale: nativeAd.iconScale) } adChoicesView = SampleAdInfoView() self.nativeAd = nativeAd if let handler = completionHandler { delegate = handler(self, nil) } } func adLoader( _ adLoader: SampleNativeAdLoader, didFailToLoadAdWith errorCode: SampleErrorCode ) { let error = SampleCustomEventUtilsSwift.SampleCustomEventErrorWithCodeAndDescription( code: SampleCustomEventErrorCodeSwift .SampleCustomEventErrorAdLoadFailureCallback, description: "Sample SDK returned an ad load failure callback with error code: \(errorCode)" ) if let handler = completionHandler { delegate = handler(nil, error) } }
Objective-C
- (void)adLoader:(SampleNativeAdLoader *)adLoader didReceiveNativeAd:(SampleNativeAd *)nativeAd { if (nativeAd.image) { _images = @[ [[GADNativeAdImage alloc] initWithImage:nativeAd.image] ]; } else { NSURL *imageURL = [[NSURL alloc] initFileURLWithPath:nativeAd.imageURL]; _images = @[ [[GADNativeAdImage alloc] initWithURL:imageURL scale:nativeAd.imageScale] ]; } if (nativeAd.icon) { _icon = [[GADNativeAdImage alloc] initWithImage:nativeAd.icon]; } else { NSURL *iconURL = [[NSURL alloc] initFileURLWithPath:nativeAd.iconURL]; _icon = [[GADNativeAdImage alloc] initWithURL:iconURL scale:nativeAd.iconScale]; } // The sample SDK provides an AdChoices view (SampleAdInfoView). If your SDK // provides image and click through URLs for its AdChoices icon instead of an // actual UIView, the adapter is responsible for downloading the icon image // and creating the AdChoices icon view. _adChoicesView = [[SampleAdInfoView alloc] init]; _nativeAd = nativeAd; _adEventDelegate = _loadCompletionHandler(self, nil); } - (void)adLoader:(SampleNativeAdLoader *)adLoader didFailToLoadAdWithErrorCode:(SampleErrorCode)errorCode { NSError *error = SampleCustomEventErrorWithCodeAndDescription( SampleCustomEventErrorAdLoadFailureCallback, [NSString stringWithFormat:@"Sample SDK returned an ad load failure " @"callback with error code: %@", errorCode]); _adEventDelegate = _loadCompletionHandler(nil, error); }
ربط الإعلانات المدمجة مع المحتوى
تتضمّن حِزَم تطوير البرامج (SDK) المختلفة أشكالاً فريدة للإعلانات المدمجة مع المحتوى. على سبيل المثال، قد تعرض إحدى حِزَم تطوير البرامج (SDK) كائنات تحتوي على حقل "العنوان"، بينما قد تحتوي حزمة أخرى على "العنوان الرئيسي". بالإضافة إلى ذلك، يمكن أن تختلف الطرق المستخدَمة لتتبُّع مرّات الظهور ومعالجة النقرات من حزمة تطوير برامج (SDK) إلى أخرى.
لمعالجة هذه المشاكل، عندما يتلقّى حدث مخصّص كائن إعلان مدمج مع المحتوى من حزمة تطوير البرامج (SDK) التي يتوسّطها، يجب أن يستخدم فئة تنفِّذ GADMediationNativeAd، مثل SampleCustomEventNativeAd، لـ "ربط" كائن الإعلان المدمج مع المحتوى الخاص بحزمة تطوير البرامج (SDK) التي يتوسّطها لكي يتطابق مع الواجهة التي تتوقّعها Google Mobile Ads SDK.
لنلقِ الآن نظرة أقرب على تفاصيل تنفيذ SampleCustomEventNativeAd.
تخزين عمليات الربط
من المتوقّع أن تنفِّذ GADMediationNativeAd خصائص معيّنة يتم ربطها من خصائص حِزَم تطوير البرامج (SDK) الأخرى:
Swift
var nativeAd: SampleNativeAd? var headline: String? { return nativeAd?.headline } var images: [NativeAdImage]? var body: String? { return nativeAd?.body } var icon: NativeAdImage? var callToAction: String? { return nativeAd?.callToAction } var starRating: NSDecimalNumber? { return nativeAd?.starRating } var store: String? { return nativeAd?.store } var price: String? { return nativeAd?.price } var advertiser: String? { return nativeAd?.advertiser } var extraAssets: [String: Any]? { return [ SampleCustomEventConstantsSwift.awesomenessKey: nativeAd?.degreeOfAwesomeness ?? "" ] } var adChoicesView: UIView? var mediaView: UIView? { return nativeAd?.mediaView }
Objective-C
/// Used to store the ad's images. In order to implement the /// GADMediationNativeAd protocol, we use this class to return the images /// property. NSArray<GADNativeAdImage *> *_images; /// Used to store the ad's icon. In order to implement the GADMediationNativeAd /// protocol, we use this class to return the icon property. GADNativeAdImage *_icon; /// Used to store the ad's ad choices view. In order to implement the /// GADMediationNativeAd protocol, we use this class to return the adChoicesView /// property. UIView *_adChoicesView; - (nullable NSString *)headline { return _nativeAd.headline; } - (nullable NSArray<GADNativeAdImage *> *)images { return _images; } - (nullable NSString *)body { return _nativeAd.body; } - (nullable GADNativeAdImage *)icon { return _icon; } - (nullable NSString *)callToAction { return _nativeAd.callToAction; } - (nullable NSDecimalNumber *)starRating { return _nativeAd.starRating; } - (nullable NSString *)store { return _nativeAd.store; } - (nullable NSString *)price { return _nativeAd.price; } - (nullable NSString *)advertiser { return _nativeAd.advertiser; } - (nullable NSDictionary<NSString *, id> *)extraAssets { return @{SampleCustomEventExtraKeyAwesomeness : _nativeAd.degreeOfAwesomeness}; } - (nullable UIView *)adChoicesView { return _adChoicesView; } - (nullable UIView *)mediaView { return _nativeAd.mediaView; } - (BOOL)hasVideoContent { return self.mediaView != nil; }
يمكن أن توفّر بعض الشبكات التي يتم التوسّط فيها مواد عرض إضافية بخلاف تلك التي تحدّدها
Google Mobile Ads SDK. يتضمّن بروتوكول GADMediationNativeAd طريقة
تُسمّى extraAssets تستخدمها Google Mobile Ads SDK لاسترداد أيّ من
مواد العرض "الإضافية" هذه من أداة الربط.
ربط مواد عرض الصور
يكون ربط مواد عرض الصور أكثر تعقيدًا من ربط أنواع البيانات الأبسط، مثل NSString أو double. قد يتم تنزيل الصور تلقائيًا أو عرضها كقيم عناوين URL. يمكن أن تختلف أيضًا كثافة وحدات البكسل.
لمساعدتك في إدارة هذه التفاصيل، توفّر Google Mobile Ads SDK الفئة
GADNativeAdImage. يجب عرض معلومات مادة عرض الصورة (سواء كانت كائنات UIImage
فعلية أو قيم NSURL فقط) إلى Google Mobile Ads SDK
باستخدام هذه الفئة.
إليك كيف تعالج فئة أداة الربط إنشاء GADNativeAdImage لاحتواء صورة الرمز:
Swift
if let image = nativeAd.image { images = [NativeAdImage(image: image)] } else { let imageUrl = URL(fileURLWithPath: nativeAd.imageURL) images = [NativeAdImage(url: imageUrl, scale: nativeAd.imageScale)] }
Objective-C
if (nativeAd.image) { _images = @[ [[GADNativeAdImage alloc] initWithImage:nativeAd.image] ]; } else { NSURL *imageURL = [[NSURL alloc] initFileURLWithPath:nativeAd.imageURL]; _images = @[ [[GADNativeAdImage alloc] initWithURL:imageURL scale:nativeAd.imageScale] ]; }
أحداث مرّات الظهور والنقرات
تحتاج كلّ من Google Mobile Ads SDK وحزمة تطوير البرامج (SDK) التي يتم التوسّط فيها إلى معرفة متى تحدث مرّة ظهور أو نقرة، ولكن يجب أن تتتبّع إحدى حِزَم تطوير البرامج (SDK) هذه الأحداث فقط. هناك طريقتان مختلفتان يمكن أن تستخدمهما الأحداث المخصّصة، وذلك حسب ما إذا كانت حزمة تطوير البرامج (SDK) التي يتم التوسّط فيها تتيح تتبُّع مرّات الظهور والنقرات من تلقاء نفسها.
تتبُّع النقرات ومرّات الظهور باستخدام Google Mobile Ads SDK
إذا كانت حزمة تطوير البرامج (SDK) التي يتم التوسّط فيها لا تتتبّع مرّات الظهور والنقرات من تلقاء نفسها ولكنها توفّر طرقًا لتسجيل النقرات ومرّات الظهور، يمكن أن تتتبّع Google Mobile Ads SDK هذه الأحداث وإشعار المحوّل. يتضمّن بروتوكول GADMediationNativeAd طريقتَين: didRecordImpression: وdidRecordClickOnAssetWithName:view:viewController: يمكن أن تنفِّذهما الأحداث المخصّصة لاستدعاء الطريقة المقابلة في كائن الإعلان المدمج مع المحتوى الذي يتم التوسّط فيه:
Swift
func didRecordImpression() { nativeAd?.recordImpression() } func didRecordClickOnAsset( withName assetName: GADUnifiedNativeAssetIdentifier, view: UIView, wController: UIViewController ) { nativeAd?.handleClick(on: view) }
Objective-C
- (void)didRecordImpression { if (self.nativeAd) { [self.nativeAd recordImpression]; } } - (void)didRecordClickOnAssetWithName:(GADUnifiedNativeAssetIdentifier)assetName view:(UIView *)view viewController:(UIViewController *)viewController { if (self.nativeAd) { [self.nativeAd handleClickOnView:view]; } }
بما أنّ الفئة التي تنفِّذ بروتوكول GADMediationNativeAd تحتوي على مرجع لكائن الإعلان المدمج مع المحتوى الخاص بحزمة تطوير البرامج (SDK) النموذجية، يمكنها استدعاء الطريقة المناسبة في هذا الكائن للإبلاغ عن نقرة أو مرّة ظهور. يُرجى العِلم أنّ الطريقة didRecordClickOnAssetWithName:view:viewController: تأخذ مَعلمة واحدة: كائن View المقابل لمادة عرض الإعلان المدمج مع المحتوى التي تلقّت النقرة.
تتبُّع النقرات ومرّات الظهور باستخدام حزمة تطوير البرامج (SDK) التي يتم التوسّط فيها
قد تفضّل بعض حِزَم تطوير البرامج (SDK) التي يتم التوسّط فيها تتبُّع النقرات ومرّات الظهور من تلقاء نفسها. في هذه الحالة، عليك تنفيذ الطريقتَين handlesUserClicks وhandlesUserImpressions كما هو موضّح في مقتطف الرمز أدناه. من خلال عرض
YES، تشير إلى أنّ الحدث المخصّص يتحمّل مسؤولية تتبُّع
هذه الأحداث وسيُشعر Google Mobile Ads SDK عند حدوثها.
يمكن أن تستخدم الأحداث المخصّصة التي تلغي تتبُّع النقرات ومرّات الظهور الرسالة didRenderInView: لتمرير طريقة عرض الإعلان المدمج مع المحتوى إلى كائن الإعلان المدمج مع المحتوى الخاص بحزمة تطوير البرامج (SDK) التي يتم التوسّط فيها للسماح لحزمة تطوير البرامج (SDK) التي يتم التوسّط فيها بإجراء عملية التتبُّع الفعلية. لا تستخدم حزمة تطوير البرامج (SDK) النموذجية من مشروع مثال الحدث المخصّص (الذي تم أخذ مقتطفات الرمز من هذا الدليل) هذا الأسلوب، ولكن إذا كانت تستخدمه، سيستدعي رمز الحدث المخصّص الطريقة setNativeAdView:view: كما هو موضّح في مقتطف الرمز أدناه:
Swift
func handlesUserClicks() -> Bool { return true } func handlesUserImpressions() -> Bool { return true } func didRender( in view: UIView, clickableAssetViews: [GADNativeAssetIdentifier: UIView], nonclickableAssetViews: [GADNativeAssetIdentifier: UIView], viewController: UIViewController ) { // This method is called when the native ad view is rendered. Here you would pass the UIView // back to the mediated network's SDK. self.nativeAd?.setNativeAdView(view) }
Objective-C
- (BOOL)handlesUserClicks { return YES; } - (BOOL)handlesUserImpressions { return YES; } - (void)didRenderInView:(UIView *)view clickableAssetViews:(NSDictionary<GADNativeAssetIdentifier, UIView *> *) clickableAssetViews nonclickableAssetViews:(NSDictionary<GADNativeAssetIdentifier, UIView *> *) nonclickableAssetViews viewController:(UIViewController *)viewController { // This method is called when the native ad view is rendered. Here you would // pass the UIView back to the mediated network's SDK. Playing video using // SampleNativeAd's playVideo method [_nativeAd setNativeAdView:view]; }
إعادة توجيه أحداث التوسّط إلى Google Mobile Ads SDK
بعد استدعاء
GADMediationNativeLoadCompletionHandler
باستخدام إعلان تم تحميله، يمكن أن يستخدم المحوّل بعد ذلك كائن التفويض GADMediationNativeAdEventDelegate
الذي تم عرضه لإعادة توجيه أحداث العرض من
حزمة تطوير البرامج (SDK) التابعة لجهة خارجية إلى Google Mobile Ads SDK.
من المهم أن يعيد الحدث المخصّص توجيه أكبر عدد ممكن من عمليات معاودة الاتصال هذه، لكي يتلقّى تطبيقك هذه الأحداث المكافئة من Google Mobile Ads SDK. إليك مثال على استخدام عمليات معاودة الاتصال:
بهذا نكون قد أكملنا عملية تنفيذ الأحداث المخصّصة للإعلانات المدمجة مع المحتوى. يتوفّر المثال الكامل على GitHub.