Требования
Настройте специальные события.
Как запросить нативное объявление
Когда в цепочке каскадной медиации будет достигнута позиция специального события, будет вызван метод 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, который реализует ваш адаптер. В этом примере в Sample 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 есть собственные уникальные форматы нативных объявлений. Один может возвращать объекты, содержащие поле "title", а другой – "headline". Кроме того, методы отслеживания показов и обработки кликов могут различаться в разных 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, содержит ссылку на объект нативного объявления из Sample 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.