ネイティブ広告のカスタム イベント

前提条件

カスタム イベントのセットアップを完了します。

ネイティブ広告をリクエストする

ウォーターフォール メディエーション チェーンでカスタム イベント広告申込情報に到達すると、 loadNativeAd:adConfiguration:completionHandler: メソッドは カスタム ディメンションの作成時に指定したクラス名 イベントをご覧ください。この場合、メソッドは SampleCustomEvent にあり、SampleCustomEventNativeloadNativeAd:adConfiguration:completionHandler: メソッドを呼び出します。

ネイティブ広告をリクエストするには、GADMediationAdapterloadNativeAd:adConfiguration:completionHandler: を実装するクラスを作成または変更します。条件 GADMediationAdapter を拡張するクラスがすでに存在するため、実装します。 loadNativeAd:adConfiguration:completionHandler:。さらに GADMediationNativeAd を実装する新しいクラス。

このカスタムイベントの例では SampleCustomEvent の実装 GADMediationAdapter インターフェースを呼び出してから、 SampleCustomEventNative

Swift

import GoogleMobileAds

class SampleCustomEvent: NSObject, GADMediationAdapter {

  fileprivate var nativeAd: SampleCustomEventNativeAd?

  func loadNativeAd(
    for adConfiguration: GADMediationNativeAdConfiguration,
    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"]。このパラメータは、 通常は広告ユニット識別子です 広告オブジェクトをインスタンス化します

Swift

class SampleCustomEventNativeAd: NSObject, GADMediationNativeAd {
  /// 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: GADMediationNativeAdEventDelegate?

  /// Completion handler called after ad load
  var completionHandler: GADMediationNativeLoadCompletionHandler?

  func loadNativeAd(
    for adConfiguration: GADMediationNativeAdConfiguration,
    completionHandler: @escaping GADMediationNativeLoadCompletionHandler
  ) {
    let adLoader = SampleNativeAdLoader()
    let sampleRequest = SampleNativeAdRequest()

    // The 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: GADAdLoaderOptions in options {
      if let imageOptions = loaderOptions as? GADNativeAdImageAdLoaderOptions {
        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? GADNativeAdMediaAdLoaderOptions
      {
        switch mediaOptions.mediaAspectRatio {
        case GADMediaAspectRatio.landscape:
          sampleRequest.preferredImageOrientation =
            NativeAdImageOrientation.landscape
        case GADMediaAspectRatio.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];

  // The 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 値で渡す error パラメータに指定します。エラー メッセージを渡します。 発生します。

通常、これらのメソッドは 実装する必要があります。この例では、サンプル SDK が 関連するコールバックを含む SampleNativeAdDelegate がある

Swift

func adLoader(
  _ adLoader: SampleNativeAdLoader, didReceive nativeAd: SampleNativeAd
) {
  extraAssets = [
    SampleCustomEventConstantsSwift.awesomenessKey: nativeAd.degreeOfAwesomeness
      ?? ""
  ]

  if let image = nativeAd.image {
    images = [GADNativeAdImage(image: image)]
  } else {
    let imageUrl = URL(fileURLWithPath: nativeAd.imageURL)
    images = [GADNativeAdImage(url: imageUrl, scale: nativeAd.imageScale)]
  }
  if let mappedIcon = nativeAd.icon {
    icon = GADNativeAdImage(image: mappedIcon)
  } else {
    let iconURL = URL(fileURLWithPath: nativeAd.iconURL)
    icon = GADNativeAdImage(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 によって異なることもあります。

こうした問題に対処するため、カスタム イベントが GADMediationNativeAd を実装するクラスを使用する必要があります。 SampleCustomEventNativeAd のような「map」に変更メディエーション対象 SDK のネイティブ広告オブジェクト Google Mobile Ads SDK に想定されているインターフェースと一致させます。

ここでは、Terraform の実装の詳細を SampleCustomEventNativeAd

マッピングを保存する

GADMediationNativeAd には、次のような特定のプロパティを実装することが想定されています。 次の SDK のプロパティからマッピングされています。

Swift

var nativeAd: SampleNativeAd?

var headline: String? {
  return nativeAd?.headline
}

var images: [GADNativeAdImage]?

var body: String? {
  return nativeAd?.body
}

var icon: GADNativeAdImage?

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 SDKGADMediationNativeAd プロトコルには、次のメソッドが含まれます。 (Google Mobile Ads SDK がイベントを取得するために使用する extraAssets)という これらの「余分な」アセットが用意されています。

画像アセットをマッピングする

画像アセットのマッピングは、単純なデータのマッピングよりも複雑 NSStringdouble などのデータ型です。画像は自動的にダウンロードされるか、 URL 値として返されます。また、画像のピクセル密度もさまざまです。

Google Mobile Ads SDK では、こうした細かい設定を簡単に管理できるよう、 GADNativeAdImage クラス。画像アセットの情報は(実際の UIImage オブジェクトの場合でも、単なる NSURL 値の場合でも)、このクラスを使用して Google Mobile Ads SDK に返す必要があります。

アイコン画像を保持する GADNativeAdImage を作成する場合、マッパークラスでの処理は次のようになります。

Swift

if let image = nativeAd.image {
  images = [GADNativeAdImage(image: image)]
} else {
  let imageUrl = URL(fileURLWithPath: nativeAd.imageURL)
  images = [GADNativeAdImage(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 だけです。そこで、 カスタム イベントで使用できる 2 種類のアプローチは、 メディエーション向け 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 への通知は、カスタム イベント側の責任となります。

クリックとインプレッションのトラッキングをオーバーライドするカスタム イベントでは、 ネイティブ広告のビューをメディエーション対象の SDK に渡す didRenderInView: メッセージ 使用して実際のトラッキングをメディエーション対象の 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 デリゲート そのオブジェクトを使用して、プレゼンテーション イベントを Google Mobile Ads SDK にリンクできます。

カスタム イベントは、できるだけ多くのコールバックを これにより、アプリはこれらの同等のイベントを Google Mobile Ads SDK があります。コールバックの使用例を以下に示します。

これで、ネイティブ広告のカスタム イベントの実装が完了しました。サンプル全体 は GitHub