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

このガイドは、AdMob でサポートされている広告ネットワーク以外のネットワークのネイティブ広告を、AdMob メディエーションを使って読み込み、表示したいと考えているパブリッシャー様を対象としています。 メディエーションを使ったバナー広告、インタースティシャル広告、ディスプレイ リワード広告の読み込みと表示については、カスタム イベントAdMobをご覧ください。

カスタム イベントは、別のネットワークから広告をリクエストする機能を持つメディエーション アダプタ クラスです。これらのクラスのいずれかの名前を広告ユニットのメディエーション設定に追加すると、SDK はそれをインスタンス化して使用し、広告を取得できます。ネイティブ カスタム イベント クラスは、次のタスクを処理できる必要があります。

  • メディエーションされるネットワークからネイティブ広告をリクエストする。
  • メディエーション対象ネットワークの SDK から Google Mobile Ads SDK にイベントを転送する。
  • GADMediatedUnifiedNativeAd を使用して、メディエーション対象のネイティブ広告オブジェクトを AdMob のネイティブ広告インターフェースにマッピングする。

それぞれのタスクについては、以下で説明します。GitHub リポジトリで、サンプル カスタム イベント プロジェクトのソース全体を確認することもできます。

前提条件

AdMob のカスタム イベントを実装するには、まずプロジェクトに Mobile Ads SDK を統合しておく必要があります。広告リクエストの実行とメディエーションの仕組みに関する資料もご確認ください。

サンプル SDK

このガイドで使用されているコードは、「サンプル SDK」も含むサンプルのカスタム イベント プロジェクトから引用したものです。このプロジェクトは別の広告ネットワークの SDK のメディエーションを行うカスタム イベントの構築方法について説明するためのもので、メディエーションを行う SDK が必要だったため、Google では模擬的なサンプル SDK を作成しました。

サンプル SDK のクラスは、広告ネットワークの本稼働 SDK クラスと似ており、リクエスト オブジェクト(SampleNativeAdRequest など)、広告ローダー(SampleNativeAdLoader など)、実際のネットワーク SDK のシミュレーションに使われるその他のクラス、定数、インターフェースがあります。ただし、ここで生成される広告は模擬的なもので、新たなネットワーク トラフィックが発生することはありません。

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

requestNativeAdWithParameter: メソッド

カスタム イベント クラスは GADCustomEventNativeAd プロトコルを実装する必要があります。このプロトコルには、カスタム イベントからネイティブ広告をリクエストするために Google Mobile Ads SDK で使われるメソッドが含まれます。

Swift

func request(withParameter serverParameter: String,
                                   request: GADCustomEventRequest,
                                   adTypes: [Any],
                                   options: [Any],
                        rootViewController: UIViewController)

Objective-C

- (void)requestNativeAdWithParameter:(NSString *)serverParameter
                             request:(GADCustomEventRequest *)request
                             adTypes:(NSArray *)adTypes
                             options:(NSArray *)options
                  rootViewController:(UIViewController *)rootViewController;

このメソッドが呼び出されると、カスタム イベントは、ネイティブ広告を非同期的にリクエストします。requestNativeAdWithParameter: の 4 つのパラメータは、リクエスト時にカスタム イベントで使用できる情報を伝達します。

  • serverParameter - 広告ユニットのメディエーション設定にカスタム イベントを追加するとき、パブリッシャーは、各リクエストとともに渡される文字列値を入力できます。このパラメータはその値(通常は、メディエーションされるネットワークによって発行された他の広告ユニット ID)を保持します。
  • request - GADCustomEventRequest オブジェクトのひとつで、単一リクエストの固有プロパティ(リクエストされたネイティブ フォーマットなど)を含みます。 GADCustomEventRequest には、リクエスト時にパブリッシャーによって提供されるターゲティング情報のプロパティも含まれます。
  • adTypes - リクエストされたネイティブ フォーマットを示す定数値を含む NSArray です。GADUnifiedNativeAd オブジェクトの場合は、kGADAdLoaderAdTypeUnifiedNative が含まれます。
  • options - GADAdLoaderOptions オブジェクトを含む NSArray です。GADAdLoaderOptions オブジェクトは、広告の読み込みに関するパブリッシャーの設定を指定します。

リクエスト情報を伝えるパラメータに加えて、rootViewController パラメータは、広告が表示される UIViewController への参照を提供します。

サンプルのカスタム イベント プロジェクトから抜粋した、requestNativeAdWithParameter: メソッドの実装部分のコード スニペットを次に示します。

SampleCustomEventNativeAd(抜粋)

Swift

func request(withParameter serverParameter: String, request: GADCustomEventRequest, adTypes: [Any], options: [Any], rootViewController: UIViewController) {

  let adLoader = SampleNativeAdLoader()
  let sampleRequest = SampleNativeAdRequest()

  if let options = options as? [GADAdLoaderOptions] {
    for loaderOptions: GADAdLoaderOptions in options {
      if let imageOptions = loaderOptions as? GADNativeAdImageAdLoaderOptions {

        sampleRequest.shouldRequestPortraitImages =
        imageOptions.preferredImageOrientation = .portrait;
        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 options = loaderOptions as? GADNativeAdViewAdOptions {
        nativeAdViewAdOptions = options
      }
    }
  }
  // This custom event uses the server parameter to carry an ad unit ID,
  // which is the most common use case.
  adLoader.adUnitID = serverParameter
  adLoader.delegate = self
  adLoader.fetchAd(sampleRequest)
}

Objective-C

- (void)requestNativeAdWithParameter:(NSString *)serverParameter
                             request:(GADCustomEventRequest *)request
                             adTypes:(NSArray *)adTypes
                             options:(NSArray *)options
                  rootViewController:(UIViewController *)rootViewController {
  SampleNativeAdLoader *adLoader = [[SampleNativeAdLoader alloc] init];
  SampleNativeAdRequest *sampleRequest = [[SampleNativeAdRequest alloc] init];

  for (GADNativeAdImageAdLoaderOptions *imageOptions in options) {
    if (![imageOptions isKindOfClass:[GADNativeAdImageAdLoaderOptions class]]) {
      continue;
    }

    sampleRequest.shouldRequestPortraitImages =
        imageOptions.preferredImageOrientation ==
        GADNativeAdImageAdLoaderOptionsOrientationPortrait;
    sampleRequest.shouldDownloadImages = !imageOptions.disableImageLoading;
    sampleRequest.shouldRequestMultipleImages = imageOptions.shouldRequestMultipleImages;
  }

  // This custom event uses the server parameter to carry an ad unit ID,
  // which is the most common use case.
  adLoader.adUnitID = serverParameter;
  adLoader.delegate = self;

  [adLoader fetchAd:sampleRequest];
}

これは模擬的な「サンプル SDK」を介して架空の広告ネットワークを対象にメディエーションを行うカスタム イベントのサンプルです。カスタム イベントは、requestNativeAdWithParameter: パラメータで提供された情報を使用して、サンプル SDK の SampleNativeAdLoader から広告をリクエストします。また、カスタム イベントはそれ自体を SampleNativeAdLoader のデリゲートとして割り当てるため、サンプル SDK からのイベントを Google Mobile Ads SDK に返送することもできます。このプロセスについては、次のセクションのトピックで説明します。

GADAdLoaderOptions

パブリッシャーは、ネイティブ広告のリクエスト作成時に GADAdLoaderOptions オブジェクトの配列を提供して、画像アセットを返す方法などの設定をそのリクエストに関して指定します。これらの設定は、次に requestNativeAdWithParameter: メソッドのパラメータの 1 つとしてカスタム イベントに提供されます。カスタム イベントは options 配列を反復処理し、その配列に含まれる設定に沿って動作します。

たとえば、options 配列に GADNativeAdImageAdLoaderOptions オブジェクトが含まれており、その shouldDownloadImages 値が true に設定されている場合、カスタム イベントで URL だけでなく実際の画像アセットが返されなければなりません。しかし、メディエーション向け SDK により画像の URL しか提供されない場合、カスタム イベントによりその URL が使用されて画像ファイルがダウンロードされ、パブリッシャーが画像を使用できるようにする必要があります。

Mobile Ads SDK にイベントを転送する

メディエーション対象ネットワークからカスタム イベントがネイティブ広告を読み込もうとするとき、いくつかのことが起こる可能性があります。たとえば SDK がネイティブ広告を正常に返したり、エラーを報告したり、使用できる広告がないことを単に報告したりする可能性があります。GADCustomEventNativeAd プロトコルにデリゲート(タイプ GADCustomEventNativeAdDelegate)を含めて、カスタム イベントが転送に使用できるようにするには、Google Mobile Ads SDK がこうしたイベントを認識できることが重要です。

カスタム イベントの役割のひとつは、「中間者」として機能することです。つまり、メディエーション向け SDK のイベントをリッスンし、必要に応じて対応する GADCustomEventNativeAdDelegate プロトコル メッセージをデリゲートに送信することが求められます。カスタム イベントは次のメッセージを認識する必要があります。

  • customEventNativeAd:didReceiveMediatedUnifiedNativeAd: - カスタム イベントがネイティブ広告を正常に読み込んだときに、このメッセージが送信されます。このメッセージはタイプ GADMediatedUnifiedNativeAd のパラメータを単一パラメータとして受け取り、カスタム イベントはこれを使用して、読み込んだネイティブ広告の「適用済み」バージョンを渡します(GADMediatedUnifiedNativeAd クラスについては、次のセクションで説明します)。
  • customEventNativeAd:didFailToLoadWithError: - カスタム イベントがネイティブ広告を読み込もうとして失敗した場合、このメソッドを使って障害を報告します。このメソッドは、障害固有の情報を含む単一パラメータ NSError を取ります。

サンプル カスタム イベント プロジェクトの動作について、次に例を示します。

SampleCustomEventNativeAd(抜粋)

Swift

extension SampleCustomEventNativeAdSwift: SampleNativeAdLoaderDelegate {

  func adLoader(_ adLoader: SampleNativeAdLoader, didReceive nativeAd: SampleNativeAd) {
    let mediatedAd = SampleMediatedNativeAdSwift(
    sampleNativeAd:nativeAd,nativeAdViewAdOptions: nativeAdViewAdOptions)
    delegate?.customEventNativeAd(self, didReceive: mediatedAd)
  }

  func adLoader(_ adLoader: SampleNativeAdLoader, didFailToLoadAdWith errorCode: SampleErrorCode) {
    let error = NSError(domain: customEventErrorDomain, code: errorCode.rawValue, userInfo: nil)
    delegate?.customEventNativeAd(self, didFailToLoadWithError: error)
  }

}

Objective-C

@interface SampleCustomEventNativeAd () <SampleNativeAdLoaderDelegate>
@end

@implementation SampleCustomEventNativeAd

@synthesize delegate;

...

#pragma mark SampleNativeAdLoaderDelegate implementation

- (void)adLoader:(SampleNativeAdLoader *)adLoader didReceiveNativeAd:(SampleNativeAd *)nativeAd {
  SampleMediatedNativeAd *mediatedAd =
      [[SampleMediatedNativeAd alloc] initWithSampleNativeAd:nativeAd
                                       nativeAdViewAdOptions:_nativeAdViewAdOptions];
  [self.delegate customEventNativeAd:self didReceiveMediatedUnifiedNativeAd:mediatedAd];
}

- (void)adLoader:(SampleNativeAdLoader *)adLoader
    didFailToLoadAdWithErrorCode:(SampleErrorCode)errorCode {
  NSError *error = [NSError errorWithDomain:customEventErrorDomain code:errorCode userInfo:nil];
  [self.delegate customEventNativeAd:self didFailToLoadWithError:error];
}

...

@end

このクラスは、サンプル SDK の SampleNativeAdLoaderDelegate プロトコルを実装しています。SampleCustomEventNativeAd.m(抜粋)では、カスタム イベント クラス自体がデリゲートとして SampleNativeAdLoader に割り当てられています。

Swift

adLoader.delegate = self

Objective-C

adLoader.delegate = self;

これによって、サンプル SDK は、報告する成功または失敗があるときは必ずカスタム イベントにメッセージを返送するようになります。次に、カスタム イベントは適切なメッセージを独自のデリゲートに送信して、イベントを Google Mobile Ads SDK に転送します。つまり、Google Mobile Ads SDK はカスタム イベントをリッスンし、カスタム イベントはメディエーションされる SDK をリッスンします。

上記の adLoader:didFailToLoadAdWithErrorCode メソッドは、この動作を示す好例です。サンプル SDK は広告の読み込みに失敗すると、adLoader:didFailToLoadAdWithErrorCode: メッセージをカスタム イベントに送信します。カスタム イベントは、サンプル SDK によって提供された SampleErrorCode を使用して新しい NSError オブジェクトを作成し、customEventNativeAd:didFailToLoadWithError: メッセージを経由して独自のデリゲートに送信します。このようにして、サンプル SDK のイベントは Google Mobile Ads SDK のイベントに変換されます。

ネイティブ広告のマッピング

各種の SDK は、ネイティブ広告向けの固有のフォーマットを独自に備えています。たとえば、「title」フィールドを含むオブジェクトを返すものもあれば、「headline」フィールドを含むものもあります。また、インプレッションの追跡やクリックの処理に使用されるメソッドが SDK によって異なることもあります。こうした違いを取り除くため、カスタム イベントはメディエーションされるネットワークの SDK からネイティブ広告オブジェクトを受け取ると、GADMediatedNativeAd のサブクラスを使用して、メディエーションされる SDK のネイティブ広告オブジェクトを、Google Mobile Ads SDK で求められるインターフェースに合わせて「マッピング」する必要があります。

AdMob のシステム定義の統合ネイティブ広告フォーマットには、対応する GADMediatedUnifiedNativeAd クラスがあります。カスタム イベントは、このサブクラスを作成して、それらのメディエーション対象の SDK によって提供されたネイティブ広告オブジェクトをマッピングする必要があります。

サンプル カスタム イベント プロジェクトのマッパー クラスの一例を次に示します。

Swift

class SampleMediatedUnifiedNativeAdSwift : NSObject {

    var sampleAd : SampleNativeAd
    var mappedImages = [GADNativeAdImage]()
    var mappedIcon: GADNativeAdImage?
    var extras = [String:Any]()
    var nativeAdViewAdOptions: GADNativeAdViewAdOptions?
    let adInfoView = SampleAdInfoView()
    var sampleMediaView : SampleMediaView?

    init(sampleNativeAd : SampleNativeAd, nativeAdViewAdOptions : GADNativeAdViewAdOptions?) {
      sampleAd = sampleNativeAd
      super.init()
      extras = [SampleCustomEventConstantsSwift.awesomenessKey: sampleAd.degreeOfAwesomeness ?? ""]
      if let image = sampleAd.image {
         mappedImages = [GADNativeAdImage(image : image)]
      }
      else {
         let imageUrl = URL(fileURLWithPath : sampleAd.imageURL)
         mappedImages = [GADNativeAdImage(url : imageUrl, scale : sampleAd.imageScale)]
      }
      if let icon = sampleAd.icon {
        mappedIcon = GADNativeAdImage(image : icon)
      }
      else {
       let iconURL = URL(fileURLWithPath : sampleNativeAd.iconURL)
       mappedIcon = GADNativeAdImage(url : iconURL, scale : sampleAd.iconScale)
      }
      self.nativeAdViewAdOptions = nativeAdViewAdOptions
      self.sampleMediaView = self.sampleAd.mediaView
    }
}

extension SampleMediatedUnifiedNativeAdSwift : GADMediatedUnifiedNativeAd {
    var advertiser : String? {
        return sampleAd.advertiser
    }

    var headline : String? {
      return sampleAd.headline
    }

    var images : [GADNativeAdImage]? {
      return mappedImages
    }

    var body : String? {
      return sampleAd.body
    }

    var icon : GADNativeAdImage? {
      return mappedIcon
    }

    var callToAction : String? {
      return sampleAd.callToAction
    }

    var starRating : NSDecimalNumber? {
      return sampleAd.starRating
    }

    var store : String? {
      return sampleAd.store
    }

    var price : String? {
      return sampleAd.price
    }

    var adChoicesView : UIView? {
      return adInfoView
    }

    var extraAssets : [String : Any]? {
      return extras
    }

    var mediaView : UIView?{
      return self.sampleMediaView!
    }

    var hasVideoContent : Bool {
      return self.sampleAd.mediaView != nil
    }

    func didRecordImpression() {
      sampleAd.recordImpression()
    }

    func didRender(in view: UIView, clickableAssetViews: [GADUnifiedNativeAssetIdentifier : UIView],
                       nonclickableAssetViews: [GADUnifiedNativeAssetIdentifier : 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.sampleAd.mediaView.playMedia()
    }

    func didRecordClickOnAsset(withName assetName: GADUnifiedNativeAssetIdentifier, view: UIView, viewController: UIViewController) {
       sampleAd.handleClick(on: view)
    }

    func didUntrackView(_ view: UIView?) {
        // This method is called when the mediatedNativeAd is no longer
        // rendered in the provided view. Here you would remove any
        // tracking from the view that has mediated native ad.
    }

}

Objective-C

    @interface SampleMediatedNativeAd ()
    @property(nonatomic, strong) SampleNativeAd *sampleAd;
    @property(nonatomic, copy) NSArray *mappedImages;
    @property(nonatomic, strong) GADNativeAdImage *mappedIcon;
    @property(nonatomic, copy) NSDictionary *extras;
    @property(nonatomic, strong) GADNativeAdViewAdOptions *nativeAdViewAdOptions;
    @property(nonatomic, strong) SampleAdInfoView *adInfoView;
    @property(nonatomic, strong) SampleMediaView *mediaView;

    @end

    @implementation SampleMediatedNativeAd

    - (instancetype)initWithSampleNativeAd:(SampleNativeAd *)sampleNativeAd
                     nativeAdViewAdOptions:(nullable GADNativeAdViewAdOptions *)nativeAdViewAdOptions {
      if (!sampleNativeAd) {
        return nil;
      }

      self = [super init];
      if (self) {
        _sampleAd = sampleNativeAd;
        _extras = @{SampleCustomEventExtraKeyAwesomeness : _sampleAd.degreeOfAwesomeness};

        if (_sampleAd.image) {
          _mappedImages = @[ [[GADNativeAdImage alloc] initWithImage:_sampleAd.image] ];
        } else {
          NSURL *imageURL = [[NSURL alloc] initFileURLWithPath:_sampleAd.imageURL];
          _mappedImages =
              @[ [[GADNativeAdImage alloc] initWithURL:imageURL scale:_sampleAd.imageScale] ];
        }

        if (_sampleAd.icon) {
          _mappedIcon = [[GADNativeAdImage alloc] initWithImage:_sampleAd.icon];
        } else {
          NSURL *iconURL = [[NSURL alloc] initFileURLWithPath:_sampleAd.iconURL];
          _mappedIcon = [[GADNativeAdImage alloc] initWithURL:iconURL scale:_sampleAd.iconScale];
        }
        _mediaView = _sampleAd.mediaView;
        _nativeAdViewAdOptions = nativeAdViewAdOptions;

        // The sample SDK provides an AdChoices view (SampleAdInfoView).
        // If your SDK provides image and clickthrough 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.
        _adInfoView = [[SampleAdInfoView alloc] init];
      }
      return self;
    }

    - (BOOL)hasVideoContent {
      return self.sampleAd.mediaView != nil;
    }

    - (UIView *)mediaView {
      return _mediaView;
    }

    - (NSString *)advertiser {
      return self.sampleAd.advertiser;
    }

    - (NSString *)headline {
      return self.sampleAd.headline;
    }

    - (NSArray *)images {
      return self.mappedImages;
    }

    - (NSString *)body {
      return self.sampleAd.body;
    }

    - (GADNativeAdImage *)icon {
      return self.mappedIcon;
    }

    - (NSString *)callToAction {
      return self.sampleAd.callToAction;
    }

    - (NSDecimalNumber *)starRating {
      return self.sampleAd.starRating;
    }

    - (NSString *)store {
      return self.sampleAd.store;
    }

    - (NSString *)price {
      return self.sampleAd.price;
    }

    - (NSDictionary *)extraAssets {
      return self.extras;
    }

    - (UIView *)adChoicesView {
      return self.adInfoView;
    }

    // Because the Sample SDK has click and impression tracking via
    // methods on its native ad object which the developer is required
    // to call, there's no need to pass it a reference to the UIView
    // being used to display the native ad. So there's no need to
    // implement mediatedNativeAd:didRenderInView:viewController:clickableAssetViews:nonClickableAssetViews
    // here. If your mediated network does need a reference to the view,
    // this method can be used to provide one. You can also access the
    // clickable and non-clickable views by asset key if the mediation
    // network needs this information.
    - (void)didRenderInView:(UIView *)view
           clickableAssetViews:
               (NSDictionary<GADUnifiedNativeAssetIdentifier, UIView *> *)clickableAssetViews
        nonclickableAssetViews:
            (NSDictionary<GADUnifiedNativeAssetIdentifier, 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
      [_sampleAd playVideo];
    }

    - (void)didUntrackView:(UIView *)view {
      // This method is called when the mediatedNativeAd is no longer
      // rendered in the provided view. Here you would remove any
      // tracking from the view that has mediated native ad.
    }

    - (void)didRecordImpression {
      if (self.sampleAd) {
        [self.sampleAd recordImpression];
      }
    }

    - (void)didRecordClickOnAssetWithName:(GADUnifiedNativeAssetIdentifier)assetName
                                     view:(UIView *)view
                           viewController:(UIViewController *)viewController {
      if (self.sampleAd) {
        [self.sampleAd handleClickOnView:view];
      }
    }

    @end

まず、イニシャライザとその動作の一部について説明します。

メディエーション対象ネイティブ広告オブジェクトへの参照を保持する

イニシャライザは、SampleNativeAd のインスタンスを最初のパラメータとして受け取ります。これは、ネイティブ広告用のサンプル SDK で使用されるネイティブ広告クラスです。マッパーがクリック イベントとインプレッション イベントを渡して、sampleAd として保存できるようにするには、メディエーションされる広告オブジェクトへの参照が必要です。イニシャライザは、GADNativeAdViewAdOptions のインスタンスも受け取ります。

NSDictionary を作成して追加アセットを保持する

メディエーション対象となるネットワークによっては、AdMob のネイティブ広告フォーマット以外の追加アセットが用意されていることがあります。GADMediatedUnifiedNativeAd プロトコルには extraAssets というメソッドが含まれます。Google Mobile Ads SDK はこのメソッドを使用して、こうした「追加」アセットがある場合はマッパーから取得します。

上記のイニシャライザは NSDictionary を作成して、それをサンプル SDK によって提供される追加アセット(この場合は degreeOfAwesomeness という単一の NSString 値)で埋めます。この NSDictionary は、後で extraAssets メソッドによって戻り値として使用されます。

Swift

extras = [SampleCustomEventExtraKeyAwesomeness : sampleAd.degreeOfAwesomeness]

Objective-C

_extras = @{SampleCustomEventExtraKeyAwesomeness : _sampleAd.degreeOfAwesomeness};

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

画像アセットのマッピングは、NSStringdouble などの比較的単純なデータ型よりも少し複雑です。画像が自動的にダウンロードされたり、単に URL 値として返されたりすることがあります。ピクセル密度もさまざまに異なる可能性があります。カスタム イベント デベロッパーがこのような詳細を管理できるように、Google Mobile Ads SDK には GADNativeAdImage クラスが用意されています。画像アセット情報(実際の UIImage オブジェクトまたは NSURL 値のどちらの場合でも)は、このクラスを使用して Google Mobile Ads SDK に返される必要があります。

アイコン画像を保持するため、マッパークラスが GADNativeAdImage の作成をどのように処理するか、次に例を示します。

Swift

if let icon = sampleAd.icon {
    mappedIcon = GADNativeAdImage(image : icon)
}
else {
    let iconURL = URL(fileURLWithPath : sampleNativeAd.iconURL)
    mappedIcon = GADNativeAdImage(url : iconURL, scale : sampleAd.iconScale)
}

Objective-C

if (_sampleAd.icon) {
   _mappedIcon = [[GADNativeAdImage alloc] initWithImage:_sampleAd.icon];
} else {
   NSURL *iconURL = [[NSURL alloc] initFileURLWithPath:_sampleAd.iconURL];
   _mappedIcon = [[GADNativeAdImage alloc] initWithURL:iconURL scale:_sampleAd.iconScale];
}

リクエストの作成に関するセクションで説明したように、パブリッシャーは GADNativeAdImageAdLoaderOptions オブジェクトを使用して、ネイティブ広告の画像が自動的にダウンロードされないように指定できます。ここでは、マッパーは画像がすでにダウンロードされているかどうかを確認し、適切な情報(UIImage または NSURL 値とスケール値の一致するペア)を使用して GADNativeAdImage を作成しています。

イニシャライザの説明はここまでとして、次はクラス内のその他の処理について説明します。

マッピングされたアセットを返す

このマッパークラスは、ネイティブ広告で想定されるアセットに対応する GADMediatedUnifiedNativeAd からメソッドを継承します。Google Mobile Ads SDK はこれらのメソッドを呼び出してアセットを取得するため、マッパークラスは適切な値を返す必要があります。ほとんどのアセットについては、この処理は非常に簡単です。

Swift

var headline : String? {
  return sampleAd.headline
}

Objective-C

- (NSString *)headline {
  return self.sampleAd.headline;
}

ただし、一部のアセットについては、データタイプが一致しない場合や、他のタイプへの変換が必要になる場合があります。このような詳細を処理するのがマッパーの役割であり、アセットのメソッドはこの処理を行う場所として最適です。

AdChoices

アダプタは、AdChoices アイコンを提供する役割を担います。adChoicesView メソッドは、GADMediatedUnifiedNativeAd プロトコルのオプションのメソッドです。実装されると、SDK は提供された Ad Choices ビューを取得してネイティブ広告に表示します。

AdChoices アイコンを提供する方法について、実装サンプルを以下に示します。

Swift

class SampleMediatedUnifiedNativeAd: NSObject, GADMediatedUnifiedNativeAd {
  /// Ad networks should provide their own AdChoices view.
  private var adChoicesView: SampleAdChoicesView?

  var adChoicesView : UIView? {
      return adChoicesView
  }

Objective-C

@interface SampleMediatedNativeAd ()<GADMediatedUnifiedNativeAd> {

  /// Ad networks should provide their own AdChoices view.
  SampleAdChoicesView *_adChoicesView;

}

@implementation SampleMediatedNativeAd

- (UIView *)adChoicesView {
  return _adInfoView;
}

インプレッション イベントとクリック イベント

インプレッションやクリックが発生したときは必ずメディエーションされたネットワークの SDK に通知することが重要です。このため、マッパークラスは、独自に追跡しているインプレッションとクリックを処理するために必要な情報をメディエーションされたネットワーク SDK に提供する役割か、インプレッションまたはクリックが発生したときにメディエーションされたネットワーク SDK に明示的に通知する役割のいずれかを担います。

メディエーション対象ネイティブ広告オブジェクトに、クリックとインプレッションを記録するメソッドが用意されている場合、カスタム イベントのマッパークラスはそのメソッドを使用できます。これは最も一般的な手法です。GADMediatedUnifiedNativeAd には didRecordImpression:didRecordClickOnAssetWithName:view:viewController: という 2 つのメソッドが含まれています。マッパーはこれをオーバーライドして、対応するメソッドをメディエーション対象のネイティブ広告オブジェクトで呼び出す必要があります。

SampleMediatedNativeAd がこれをどのように処理するかを次に示します。

Swift

func didRecordImpression() {
  sampleAd.recordImpression()
}

func didRecordClickOnAsset(withName assetName: GADUnifiedNativeAssetIdentifier,
                                    view: UIView,
                                    viewController: UIViewController) {
  sampleAd.handleClick(on: view)
}

Objective-C

- (void)didRecordImpression {
  if (self.sampleAd) {
    [self.sampleAd recordImpression];
  }
}

- (void)didRecordClickOnAssetWithName:(GADUnifiedNativeAssetIdentifier)assetName
                                 view:(UIView *)view
                       viewController:(UIViewController *)viewController {
  if (self.sampleAd) {
    [self.sampleAd handleClickOnView:view];
  }
}

サンプル SDK のネイティブ広告オブジェクトへの参照を保持している SampleMediatedNativeAd は、そのオブジェクト上の適切なメソッドを呼び出すだけで、クリックまたはインプレッションを報告できます。

メディエーション向け SDK を使ってクリックとインプレッションを追跡する

クリックやインプレッションを独自に追跡する必要がある広告ネットワーク用に、GADCustomEventNativeAd プロトコルには handlesUserClickshandlesUserImpressions という 2 つのオプション メッセージが用意されています。このいずれかから YES を返すことは、カスタム イベントがそのタイプのイベントを独自に追跡していることを意味します。NO が返されるか、応答がない場合は、Google Mobile Ads SDK がカスタム イベントの代わりにクリックとインプレッションのトラッキングを処理し、GADMediatedUnifiedNativeAddidRecordImpression:didRecordClickOnAssetWithName: を使用してそれらのイベントを報告する必要があることを意味します。

クリックまたはインプレッションを独自にトラッキングするカスタム イベントは、GADMediatedUnifiedNativeAd プロトコルの didRenderInView: メッセージを使用して、ネイティブ広告のビューをメディエーション向け SDK のネイティブ広告オブジェクトに渡すことができます。メディエーション向け SDK はそのビューを使用して実際のトラッキングを行います。このガイドのサンプルコードでこれまでに紹介したサンプル SDK では、この手法をクリックとインプレッションの処理に使用していませんが、仮に使用した場合、適切な didRenderInView: メソッドは次のようになります。

Swift

func didRender(in view: UIView,
                  clickableAssetViews: [GADUnifiedNativeAssetIdentifier : UIView],
                  nonclickableAssetViews: [GADUnifiedNativeAssetIdentifier : UIView],
                  viewController: UIViewController) {
  sampleAd?.setNativeAdView(view)
}

Objective-C

- (void)didRenderInView:(UIView *)view
       clickableAssetViews:
           (NSDictionary<GADUnifiedNativeAssetIdentifier, UIView *> *)clickableAssetViews
    nonclickableAssetViews:
        (NSDictionary<GADUnifiedNativeAssetIdentifier, UIView *> *)nonclickableAssetViews
            viewController:(UIViewController *)viewController {
  [self.sampleAd setNativeAdView:view];
}

GADMediatedUnifiedNativeAd には didUntrackView: も含まれます。これは逆の用途に使用します。カスタム イベントはこのメソッドを実装して、ビューへの参照をすべて解放し、可能であればネイティブ広告オブジェクトとの関連付けを解除する必要があります。

GADMediatedNativeAdNotificationSource

SDK には、メディエーション対象のネイティブ広告が画面の表示やクリックの記録などのイベントを報告する際に使用できる GADMediatedNativeAdNotificationSource クラスが用意されています。このクラスには、メディエーションされるネイティブ広告の存続中に発生するさまざまなイベントに対応する 6 個のクラスメソッドが含まれます。各メソッドは、対応する広告オブジェクトへの参照を取ります。

  • mediatedNativeAdDidRecordImpression: - このメソッドは、Google Mobile Ads SDK にインプレッションの報告を返すために、独自にインプレッションを追跡するカスタム イベントから、メディエーションされるネイティブ広告によって呼び出される必要があります。報告の目的で必要になります。
  • mediatedNativeAdDidRecordClick: - 同様に、このメソッドは、クリックが発生したことを報告するために、独自にクリックを追跡するカスタム イベントから、メディエーションされるネイティブ広告によって呼び出される必要があります。
  • mediatedNativeAdWillPresentScreen: - メディエーションされるネイティブ広告でアプリ内のモーダル画面が開く直前に呼び出される必要があります。
  • mediatedNativeAdWillDismissScreen: - メディエーション対象ネイティブ広告によって開かれたアプリ内のモーダル画面が閉じられる直前に呼び出される必要があります。
  • mediatedNativeAdDidDismissScreen: - メディエーション対象ネイティブ広告によって開かれたアプリ内のモーダル画面が閉じられた直後に呼び出される必要があります。
  • mediatedNativeAdWillLeaveApplication: - メディエーション対象ネイティブ広告によってアプリからフォーカスが移動される(Safari でリンク先 URL を開く場合など)直前に呼び出される必要があります。

カスタム イベントを使用する

カスタム イベントを使用するには、広告ユニットのメディエーション設定にカスタム イベントを追加する必要があります。これは AdMob 管理画面で行います(広告ユニットのメディエーション設定を編集する詳しい手順については、カスタム イベントの作成に関するヘルプセンター記事をご覧ください)。

カスタム イベントを広告ユニットのメディエーション設定に追加する際は、次の 3 つの情報を求められます。

  • Class Name - カスタム イベントのクラス名です。
  • Label - AdMob の管理画面で広告ユニットのメディエーション ソースを表示する際に、カスタム イベントを表すのに使用するラベルです。 これは AdMob.com だけに表示されるお客様専用のラベルです。
  • Parameter - この広告ユニットがリクエストされたときにカスタム イベントに渡される文字列値です。通常は、メディエーションされるネットワークからの広告ユニット ID に設定されます。

カスタム イベントのエントリ例のスクリーンショットを次に示します。

これで、AdMob 向けの独自の iOS カスタム イベントの記述に必要なものすべてが準備できました。