پیشنیازها
تنظیمات رویدادهای سفارشی را تکمیل کنید.
درخواست تبلیغ بومی
وقتی به ردیف رویداد سفارشی در زنجیره میانجی آبشاری (waterfall mediation chain) میرسید، متد loadNativeAd:adConfiguration:completionHandler: بر اساس نام کلاسی که هنگام ایجاد یک رویداد سفارشی ارائه کردهاید، فراخوانی میشود. در این حالت، آن متد در SampleCustomEvent قرار دارد که سپس متد loadNativeAd:adConfiguration:completionHandler: را در SampleCustomEventNative فراخوانی میکند.
برای درخواست یک تبلیغ native، کلاسی ایجاد یا اصلاح کنید که GADMediationAdapter پیادهسازی کند و loadNativeAd:adConfiguration:completionHandler: فراخوانی کند. اگر کلاسی که GADMediationAdapter را ارثبری میکند از قبل وجود دارد، loadNativeAd:adConfiguration:completionHandler: را در آنجا پیادهسازی کنید. علاوه بر این، یک کلاس جدید برای پیادهسازی GADMediationNativeAd ایجاد کنید.
در مثال رویداد سفارشی ما، SampleCustomEvent رابط GADMediationAdapter را پیادهسازی میکند و سپس آن را به SampleCustomEventNative واگذار میکند.
سویفت
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) } }
هدف-سی
#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.دریافت و گزارش فراخوانیهای رویداد تبلیغات به SDK تبلیغات موبایلی گوگل.
پارامتر اختیاری که در رابط کاربری مدیریت تبلیغات تعریف شده است، در پیکربندی تبلیغات گنجانده شده است. این پارامتر از طریق adConfiguration.credentials.settings[@"parameter"] قابل دسترسی است. این پارامتر معمولاً یک شناسه واحد تبلیغاتی است که یک SDK شبکه تبلیغاتی هنگام نمونهسازی یک شیء تبلیغاتی به آن نیاز دارد.
سویفت
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) } }
هدف-سی
#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 برای پارامتر خطا، و در صورت شکست، خطایی را که با آن مواجه شدهاید، منتقل کنید.
معمولاً این متدها درون فراخوانیهای (callbacks) از SDK شخص ثالثی که آداپتور شما پیادهسازی میکند، پیادهسازی میشوند. برای این مثال، Sample SDK دارای یک SampleNativeAdDelegate با فراخوانیهای مربوطه است:
سویفت
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) } }
هدف-سی
- (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 واسطه استفاده کند تا با رابط مورد انتظار SDK تبلیغات موبایل گوگل مطابقت داشته باشد.
اکنون نگاه دقیقتری به جزئیات پیادهسازی SampleCustomEventNativeAd میاندازیم.
نقشههای خود را ذخیره کنید
انتظار میرود GADMediationNativeAd ویژگیهای خاصی را که از سایر ویژگیهای SDK به آنها نگاشت شدهاند، پیادهسازی کند:
سویفت
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 }
هدف-سی
/// 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; }
برخی از شبکههای واسطه میتوانند داراییهای اضافی فراتر از آنچه توسط SDK تبلیغات موبایل گوگل تعریف شده است، ارائه دهند. پروتکل GADMediationNativeAd شامل روشی به نام extraAssets است که SDK تبلیغات موبایل گوگل از آن برای بازیابی هر یک از این داراییهای "اضافی" از نقشهکش شما استفاده میکند.
داراییهای تصویر نقشه
نگاشت داراییهای تصویر پیچیدهتر از نگاشت انواع داده سادهتر مانند NSString یا double است. تصاویر ممکن است به صورت خودکار دانلود شوند یا به عنوان مقادیر URL بازگردانده شوند. تراکم پیکسل آنها نیز میتواند متفاوت باشد.
برای کمک به شما در مدیریت این جزئیات، SDK تبلیغات موبایل گوگل کلاس GADNativeAdImage را ارائه میدهد. اطلاعات مربوط به تصاویر (چه اشیاء UIImage واقعی باشند و چه فقط مقادیر NSURL ) باید با استفاده از این کلاس به SDK تبلیغات موبایل گوگل بازگردانده شوند.
در اینجا نحوه مدیریت کلاس نگاشتکننده برای ایجاد یک GADNativeAdImage جهت نگهداری تصویر آیکون آمده است:
سویفت
if let image = nativeAd.image { images = [NativeAdImage(image: image)] } else { let imageUrl = URL(fileURLWithPath: nativeAd.imageURL) images = [NativeAdImage(url: imageUrl, scale: nativeAd.imageScale)] }
هدف-سی
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] ]; }
رویدادهای نمایش و کلیک
هم SDK تبلیغات موبایل گوگل و هم SDK واسطه باید بدانند که چه زمانی یک نمایش یا کلیک رخ میدهد، اما فقط یک SDK باید این رویدادها را ردیابی کند. بسته به اینکه SDK واسطه از ردیابی نمایشها و کلیکها به تنهایی پشتیبانی میکند یا خیر، دو رویکرد متفاوت وجود دارد که رویدادهای سفارشی میتوانند از آنها استفاده کنند.
پیگیری کلیکها و نمایشها با SDK تبلیغات موبایلی گوگل
اگر SDK واسطه، ردیابی نمایش و کلیک خود را انجام ندهد، اما روشهایی برای ثبت کلیکها و نمایشها ارائه دهد، SDK تبلیغات موبایل گوگل میتواند این رویدادها را ردیابی کرده و به آداپتور اطلاع دهد. پروتکل GADMediationNativeAd شامل دو متد است: didRecordImpression: و didRecordClickOnAssetWithName:view:viewController: که رویدادهای سفارشی میتوانند برای فراخوانی متد مربوطه در شیء تبلیغ بومی واسطه، پیادهسازی کنند:
سویفت
func didRecordImpression() { nativeAd?.recordImpression() } func didRecordClickOnAsset( withName assetName: GADUnifiedNativeAssetIdentifier, view: UIView, wController: UIViewController ) { nativeAd?.handleClick(on: view) }
هدف-سی
- (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 را پیادهسازی میکند، ارجاعی به شیء تبلیغ بومی Sample SDK دارد، میتواند متد مناسب را روی آن شیء فراخوانی کند تا یک کلیک یا نمایش را گزارش دهد. توجه داشته باشید که متد didRecordClickOnAssetWithName:view:viewController: یک پارامتر واحد میگیرد: شیء View مربوط به دارایی تبلیغ بومی که کلیک را دریافت کرده است.
کلیکها و نمایشها را با SDK واسطه ردیابی کنید
برخی از SDK های واسطه ممکن است ترجیح دهند کلیکها و نمایشها را خودشان ردیابی کنند. در این صورت، شما باید متدهای handlesUserClicks و handlesUserImpressions را همانطور که در قطعه کد زیر نشان داده شده است، پیادهسازی کنید. با برگرداندن YES ، شما نشان میدهید که رویداد سفارشی مسئولیت ردیابی این رویدادها را بر عهده میگیرد و هنگام وقوع این رویدادها، SDK تبلیغات موبایلی گوگل را مطلع خواهد کرد.
رویدادهای سفارشی که ردیابی کلیک و نمایش را لغو میکنند، میتوانند از پیام didRenderInView: برای ارسال نمای تبلیغ بومی به شیء تبلیغ بومی SDK واسطه استفاده کنند تا SDK واسطه بتواند ردیابی واقعی را انجام دهد. نمونه SDK از پروژه نمونه رویداد سفارشی ما (که قطعه کدهای این راهنما از آن گرفته شده است) از این رویکرد استفاده نمیکند، اما اگر استفاده میکرد، کد رویداد سفارشی، متد setNativeAdView:view: را همانطور که در قطعه کد زیر نشان داده شده است، فراخوانی میکرد:
سویفت
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) }
هدف-سی
- (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]; }
رویدادهای میانجیگری را به SDK تبلیغات موبایلی گوگل منتقل کنید
زمانی که GADMediationNativeLoadCompletionHandler با یک تبلیغ بارگذاری شده فراخوانی کردید، شیء نماینده GADMediationNativeAdEventDelegate که بازگردانده شده است، میتواند توسط آداپتور برای ارسال رویدادهای ارائه از SDK شخص ثالث به SDK تبلیغات موبایل گوگل استفاده شود.
مهم است که رویداد سفارشی شما تا حد امکان این فراخوانیهای برگشتی را ارسال کند، به طوری که برنامه شما این رویدادهای معادل را از SDK تبلیغات موبایلی گوگل دریافت کند. در اینجا مثالی از استفاده از فراخوانیهای برگشتی آورده شده است:
این پیادهسازی رویدادهای سفارشی برای تبلیغات بومی را تکمیل میکند. مثال کامل در GitHub موجود است.