広告ネットワーク メディエーション アダプタの開発

このガイドは、メディエーション アダプタの構築を検討している広告ネットワークを対象としています。 パブリッシャー様は、パブリッシャー様向けのメディエーション手順をご覧ください。

メディエーション アダプタは、広告ネットワークと Google モバイル広告メディエーションの間の通信レイヤです。アダプタは、広告ネットワークから広告を配信しながら、関連する広告イベントを AdMob に転送します。アダプタは、GADMAdNetworkAdapter プロトコルを実装して、必要な機能を提供する役割を担います。

前提条件

  • Xcode 15.3 以降
  • 8.0 以上のデプロイ ターゲット
  • Google Mobile Ads iOS SDK のダウンロードの [Mediation Adapters] フォルダにある追加ヘッダー

メディエーション アダプタを作成するには、広告ネットワークに Google との提携関係を確立しておく必要があります。

サンプル広告ネットワーク

このガイドでは、サンプル広告ネットワーク用のアダプタの作成方法を説明します。サンプル広告ネットワーク SDK には、ほとんどの広告ネットワークで提供されているクラスの代表的なクラスが含まれています。

@interface SampleBanner : UILabel

@property(nonatomic, copy) NSString *adUnit;
@property(nonatomic, weak) id<SampleBannerAdDelegate> delegate;
- (void)fetchAd:(SampleAdRequest *)request;

@end

typedef NS_ENUM(NSInteger, SampleErrorCode) {
  SampleErrorCodeBadRequest = 0,
  SampleErrorCodeUnknown = 1,
  SampleErrorCodeNetworkError = 2,
  SampleErrorCodeNoInventory = 3,
};

@interface SampleAdRequest : NSObject

@property(nonatomic, assign) BOOL testMode;
@property(nonatomic, copy) NSArray *keywords;

@end

@interface SampleInterstitial : NSObject

@property(nonatomic, copy) NSString *adUnit;
@property(nonatomic, weak) id<SampleInterstitialAdDelegate> delegate;
@property(nonatomic, assign, getter=isInterstitialLoaded) BOOL interstitialLoaded;
- (void)fetchAd:(SampleAdRequest *)request;
- (void)show;

@end

@protocol SampleBannerAdDelegate
- (void)bannerDidLoad:(SampleBanner *)banner;
- (void)banner:(SampleBanner *)banner didFailToLoadAdWithError:(SampleErrorCode)error;
- (void)bannerWillLeaveApplication:(SampleBanner *)banner;

@end

@protocol SampleInterstitialAdDelegate<NSObject>
- (void)interstitialDidLoad:(SampleInterstitial *)interstitial;
- (void)interstitial:(SampleInterstitial *)interstitial
    didFailToLoadAdWithError:(SampleErrorCode)error;
- (void)interstitialWillPresentScreen:(SampleInterstitial *)interstitial;
- (void)interstitialWillDismissScreen:(SampleInterstitial *)interstitial;
- (void)interstitialDidDismissScreen:(SampleInterstitial *)interstitial;
- (void)interstitialWillLeaveApplication:(SampleInterstitial *)interstitial;

@end

これらのクラスの詳細については、SDK 実装のサンプルをご覧ください。

コネクタ

メディエーション アダプタは、GADMAdNetworkConnector プロトコルを実装するオブジェクトを使用して Google Mobile Ads SDK とやり取りします。以降、このオブジェクトを「コネクタ」と呼びます。このコネクタは、広告リクエストに関する必要な情報を公開し、広告イベントやユーザー操作についてメディエーションにコールバックする手段を提供します。コネクタは、初期化時にメディエーション アダプタに提供されます。コネクタをインスタンス変数に格納するようにアダプタを設定します。

- (id)initWithGADMAdNetworkConnector:(id<GADMAdNetworkConnector>)c {
  if ((self = [super init])) {
    _connector = c;
  }
  return self;
}

サーバー パラメータ

多くの場合、広告ネットワークにはパブリッシャーを識別するための識別子が必要です。たとえば、サンプル広告ネットワークには広告ユニットが必要です。これらの必須のサーバー パラメータは、credentials メソッドを介してアダプタに提供されます。このメソッドは、識別子と対応する値の NSDictionary を返します。次のコード行は、サンプル広告ネットワーク用に ad_unit という名前のサーバー パラメータをコネクタから取得します。

self.interstitialAd.adUnit = [[self.connector credentials] objectForKey:@"ad_unit"];

メディエーション ネットワークの設定

広告ネットワークは、そのネットワークに必要なサーバー パラメータを AdMob に通知する必要があります。これにより、AdMob のフロントエンドでネットワークを設定できるようになります。

フロントエンドでネットワークのメディエーションを有効にする場合、AdMob ではアダプタのインスタンス化に必要な値を入力する必要があります。次のスクリーンショットは、Millennial Media には Application Placement Identifier(APID)が、InMobi にはアプリ ID が必須であることを示しています。

メディエーション広告ネットワークの設定について詳しくは、こちらの記事をご覧ください。

メディエーション広告リクエストを行う

メディエーション バナー リクエストの場合、アダプタがインスタンス化された直後に getBannerWithSize メソッドが呼び出されます。このメソッドは何も返しません。ネットワーク経由で非同期の広告取得を開始するようにアダプタに通知します。アダプタで SDK のコールバックをリッスンします。SDK が指定された広告サイズをサポートしていない場合や、バナー広告をサポートしていない場合は、コネクタで adapter:didFailAd: メソッドを呼び出します。

サンプル広告ネットワーク用に getBannerWithSize を実装すると、次のようになります。

- (void)getBannerWithSize:(GADAdSize)adSize {
  //The adapter should fail immediately if the adSize is not supported
  if (!GADAdSizeEqualToSize(adSize, GADAdSizeBanner) &&
      !GADAdSizeEqualToSize(adSize, GADAdSizeMediumRectangle) &&
      !GADAdSizeEqualToSize(adSize, GADAdSizeFullBanner) &&
      !GADAdSizeEqualToSize(adSize, GADAdSizeLeaderboard)) {
    NSString *errorDesc =
        [NSString stringWithFormat:@"Invalid ad type %@, not going to get ad.",
                                   NSStringFromGADAdSize(adSize)];
    NSDictionary *errorInfo = [NSDictionary
        dictionaryWithObjectsAndKeys:errorDesc, NSLocalizedDescriptionKey, nil];
    NSError *error = [NSError errorWithDomain:GADErrorDomain
                                         code:GADErrorMediationInvalidAdSize
                                     userInfo:errorInfo];
    [self.connector adapter:self didFailAd:error];
    return;
  }
  self.bannerAd = [[SampleBanner alloc]
      initWithFrame:CGRectMake(0, 0, adSize.size.width, adSize.size.height)];

  self.bannerAd.delegate = self;
  self.bannerAd.adUnit = [[self.connector credentials] objectForKey:@"ad_unit"];

  // Setup request parameters.
  SampleAdRequest *request = [[SampleAdRequest alloc] init];
  request.testMode = self.connector.testMode;
  request.keywords = self.connector.userKeywords;
  [self.bannerAd fetchAd:request];
  NSLog(@"Requesting banner from Sample Ad Network");
}

追加のターゲティング パラメータ

コネクタには、広告ターゲット設定用に参照できる一般的なターゲット設定情報が含まれています。

  • userKeywords
  • testMode
  • childDirectedTreatment

メディエーションの追加パラメータ

メディエーションの追加パラメータを使用すると、コネクタが提供する追加のリクエスト パラメータでは対応できない、追加のターゲティング パラメータや入力を広告ネットワークでサポートできます。この機能は、GADAdNetworkExtras プロトコルを実装するクラスを通じて提供できます。例として、SampleAdNetworkExtras クラスを次に示します。

@interface SampleAdNetworkExtras : NSObject <GADAdNetworkExtras>
/// Should ad volume audio be muted.
@property(nonatomic, assign) BOOL muteAudio;

@end

パブリッシャーは、広告リクエストを行うときに GADAdNetworkExtras サブクラスのインスタンスを渡す必要があります。GADAdNetworkExtras サブクラスのこのインスタンスには、コネクタを通じてアクセスできます。ネットワークの広告リクエストを作成するときにメディエーションの追加パラメータを使用する方法は次のとおりです。

SampleAdRequest *request = [[SampleAdRequest alloc] init];
SampleAdNetworkExtras *myAdNetworkExtras = [self.connector networkExtras];
request.muteAudio = myAdNetworkExtras.muteAudio;
[self.bannerAd fetchAd:request];

コネクタを介して GADAdNetworkExtras サブクラスにアクセスできるようにするには、networkExtrasClass を実装して GADAdNetworkExtras サブクラスを返します。

+ (Class<GADAdNetworkExtras>)networkExtrasClass {
  return [SampleAdNetworkExtras class];
}

アダプタがメディエーション エクストラを使用しない場合、networkExtrasClass メソッドは Nil を返します。

メディエーションに通知する

アダプタでネットワークの広告リスナーを実装し、コネクタを介して関連する広告イベント コールバックを転送します。次の表に、各デリゲート メソッドを呼び出すタイミングを示します。

メソッド 電話をかけるタイミング
adapter:didReceiveAdView: バナー リクエストが成功しました。
adapter:didFailAd: バナー リクエストに失敗しました。
adapterDidGetAdClick: バナーがクリックされた。
adapterWillPresentFullScreenModal: バナーにはアプリ内オーバーレイが表示されます。
adapterWillDismissFullScreenModal: アプリ内オーバーレイが閉じます。
adapterDidDismissFullScreenModal: アプリ内オーバーレイが閉じられました。
adapterWillLeaveApplication: ユーザーが別のアプリを起動する広告をクリックしたため、アプリがバックグラウンドに配置されるか、終了する。

次の例では、サンプル広告ネットワークの SampleBannerAdDelegate インターフェースを実装して、エラー メッセージとステータス メッセージを転送します。

- (void)bannerDidLoad:(SampleBanner *)banner {
  [self.connector adapter:self didReceiveAdView:banner];
}

- (void)banner:(SampleBanner *)banner didFailWithError:(SampleErrorCode)error {
  [self.connector adapter:self
                didFailAd:[NSError errorWithDomain:@"Ad request failed"
                                              code:error
                                          userInfo:nil]];
}

- (void)bannerWillLeaveApplication:(SampleBanner *)banner {
  [self.connector adapterDidGetAdClick:self];
  [self.connector adapterWillLeaveApplication:self];
}

アプリ内オーバーレイと外部アプリケーションの起動

バナーがクリックされると、広告のフルスクリーン オーバーレイや外部アプリ(Safari やアプリストアなど)が開く場合があります。これら 2 つのケースでは、呼び出すコネクタ コールバックが異なります。

バナーをクリックするとフルスクリーン オーバーレイが開く場合は、オーバーレイの表示時に adapterWillPresentFullScreenModal: を呼び出します。オーバーレイが閉じているときは、adapterWillDismissFullScreenModal:adapterDidDismissFullScreenModal: の両方を呼び出します。

バナークリック(またはフルスクリーン オーバーレイ クリック)によりユーザーがアプリを離れる場合は、adapterWillLeaveApplication: コールバックを呼び出します。

これで、バナー用のメディエーション アダプタが機能するようになりました。SampleAdapter の完全な実装については、GitHub をご覧ください。

インタースティシャル アダプタを実装する

インタースティシャル広告のアダプタの実装は、バナー広告と同様です。getInterstitial メソッドは、アダプターがインスタンス化された直後に呼び出されます。このメソッドは何も返しません。アダプタは、ネットワーク経由で非同期の広告フェッチを開始することが想定されています。アダプタが、コールバックをリッスンするために SDK へのデリゲートとして機能するようにします。SDK がインタースティシャル広告をサポートしていない場合は、次のようにコネクタの adapter:didFailAd: メソッドを呼び出します。

- (void)getInterstitial {
  self.interstitialAd = [[SampleInterstitial alloc] init];
  self.interstitialAd.delegate = self;
  self.interstitialAd.adUnit =
      [[self.connector credentials] objectForKey:@"ad_unit"];

  SampleAdRequest *request = [[SampleAdRequest alloc] init];
  // Setup request parameters.
  request.testMode = self.connector.testMode;
  request.keywords = self.connector.userKeywords;

  [self.interstitialAd fetchAd:request];
  NSLog(@"Requesting interstitial from Sample Ad Network");
}

MediationBannerAdapter の場合と同様に、コネクタからパブリッシャー ID と広告ターゲット設定の情報を取得できます。

メディエーションに通知する

アダプタでネットワーク用の広告デリゲートを実装し、コネクタを介して関連する広告イベント コールバックを転送します。次の表に、各デリゲート メソッドを呼び出すタイミングを示します。

メソッド 電話をかけるタイミング
adapterDidReceiveInterstitial: インタースティシャル リクエストが成功しました。
adapter:didFailInterstitial: インタースティシャル リクエストに失敗しました。
adapterDidGetAdClick: インタースティシャルがクリックされた。
adapterWillPresentInterstitial: インタースティシャルが表示されます。
adapterWillDismissInterstitial: インタースティシャルが閉じようとしています。
adapterDidDismissInterstitial: インタースティシャルが閉じられました。
adapterWillLeaveApplication: 別のアプリを起動する広告をユーザーがクリックしたため、アプリがバックグラウンドになるか終了します。

次の例では、サンプル広告ネットワークの SampleInterstitialAdDelegate インターフェースを実装して、エラー メッセージとステータス メッセージを転送します。

- (void)interstitialDidLoad:(SampleInterstitial *)interstitial {
  [self.connector adapterDidReceiveInterstitial:self];
}

- (void)interstitial:(SampleInterstitial *)interstitial
    didFailWithError:(SampleErrorCode)error {
  [self.connector adapter:self
      didFailInterstitial:[NSError errorWithDomain:@"Ad request failed"
                                              code:error
                                          userInfo:nil]];
}

- (void)interstitialWillPresentScreen:(SampleInterstitial *)interstitial {
  [self.connector adapterWillPresentInterstitial:self];
}

- (void)interstitialWillDismissScreen:(SampleInterstitial *)interstitial {
  [self.connector adapterWillDismissInterstitial:self];
}

- (void)interstitialDidDismissScreen:(SampleInterstitial *)interstitial {
  [self.connector adapterDidDismissInterstitial:self];
}

インタースティシャルを表示する

アダプタは、adapterDidReceiveInterstitial を呼び出した後、presentInterstitialFromRootViewController が呼び出されるまでインタースティシャルの表示を待機します。インタースティシャルを表示するタイミングはアプリ デベロッパーが決定します。インタースティシャルを受信してから数分遅れる場合もあります。

サンプル広告ネットワーク用の presentInterstitialFromRootViewController: の実装を次に示します。

- (void)presentInterstitialFromRootViewController:
    (UIViewController *)rootViewController {
  if ([self.interstitialAd isLoaded]) {
    [self.interstitialAd show];
  }
}

これで、メディエーション アダプタでインタースティシャル広告を処理する準備が整いました。SampleAdapter の完全な実装については、GitHub をご覧ください。

よくある質問

アダプタは、SDK ライブラリの一部として含める必要がありますか?それとも個別のライブラリとして含める必要がありますか?
アダプタは SDK ライブラリの一部として含めることをおすすめします。これにより、デベロッパーはネットワークを組み込むためにライブラリを 1 つだけ参照するだけで済みます。
バナー広告のみをアダプタでサポートしている場合は、どうすればよいですか?

バナーのみをアダプタでサポートする場合は、インタースティシャル リクエストのエラーイベントをメディエーションに転送するよう設定します。

- (void)getInterstitial {
  NSDictionary *errorInfo = @{ NSLocalizedDescriptionKey : @"Some error" };
  NSError *error = [NSError errorWithDomain:GADErrorDomain
                                       code:GADErrorInvalidRequest
                                   userInfo:errorInfo];
  [self.connector adapter:self didFailInterstitial:error];
  return;
}
インタースティシャル広告のみをアダプタでサポートするにはどうすればよいですか?

インタースティシャルのみをアダプタでサポートしている場合は、バナー リクエストのエラーイベントをメディエーションに転送するよう設定します。

- (void)getBannerWithSize:(GADAdSize)adSize {
  NSDictionary *errorInfo = @{ NSLocalizedDescriptionKey : @"Some error" };
  NSError *error =
      [NSError errorWithDomain:GADErrorDomain
                          code:GADErrorInvalidRequest
                      userInfo:errorInfo];
  [self.connector adapter:self didFailAd:error];
  return;
}