Native Mediation Custom Events

This guide is for publishers who want to use DFP Mediation to load and display native ads from a network that isn't one of DFP's Supported ad networks. See Custom Events for information about using DFP Mediation to load and display banner, interstitial, or rewarded display ads.

Custom events are mediation adapter classes capable of requesting ads from another network. When you add the name of one of these classes to the mediation settings for an ad unit, the SDK can instantiate and use it to retrieve ads. Native custom event classes need to be able to do the following things:

  • Request native ads from a mediated network.
  • Forward events from the mediated network's SDK to the Google Mobile Ads SDK.
  • Use a GADMediatedUnifiedNativeAd to map mediated native ad objects to DFP's native ad interface.

Each of these tasks is covered below. You can also find the full source for a sample custom event project in our GitHub repository.

Prerequisites

To implement DFP custom events, you must first integrate the Mobile Ads SDK into your project. You might also want to read about making an ad request and how mediation works.

The Sample SDK

The code used in this guide is taken from our sample custom event project, which also includes a "Sample SDK." In order for the project to illustrate how to build a custom event that mediates another ad network's SDK, it needed an SDK to mediate, so we created a mock called the Sample SDK.

The Sample SDK features classes similar to what you'd find in an ad network's production SDK. There are request objects like SampleNativeAdRequest, ad loaders like SampleNativeAdLoader, and other classes, constants and protocols used to simulate a real network's SDK. The ads that it produces are mocks, though, and no additional network traffic is generated.

Request native ads

The requestNativeAdWithParameter: method

Custom event classes must implement the GADCustomEventNativeAd protocol, which includes a method used by the Google Mobile Ads SDK to request native ads from the custom event:

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;

When this method is called, the custom event should asynchronously request a native ad. Four of the parameters for requestNativeAdWithParameter: carry information that the custom event can use in making its request:

  • serverParameter - When adding a custom event to an ad unit's mediation configuration, publishers can enter a string value to be passed along with each request. This parameter holds that value (typically another ad unit ID, which was issued by the mediated network).
  • request - A GADCustomEventRequest object, which contains properties specific to a single request, such as which native formats are requested. GADCustomEventRequest also includes properties for targeting information provided by publishers at request time.
  • adTypes - An NSArray containing constants that indicate which native formats are requested. For UnifiedNativeAd objects, this should contain kGADAdLoaderAdTypeUnifiedNative.
  • options - An NSArray containing GADAdLoaderOptions objects that indicate the publisher's preferences for loading ads.

In addition to the parameters carrying request information, the rootViewController parameter provides a reference to the UIViewController in which the ad is to be displayed.

Here's a code snippet from our example custom event project that shows an implemented requestNativeAdWithParameter: method:

SampleCustomEventNativeAd (excerpt)

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];
}

This is a sample custom event that mediates to an imaginary ad network via a mock "Sample SDK." The custom event uses the information provided in the requestNativeAdWithParameter: parameters to request an ad from the Sample SDK's SampleNativeAdLoader. It also assigns itself as the delegate for theSampleNativeAdLoader, so it can forward events from the Sample SDK back to the Google Mobile Ads SDK. That process is the topic of the next section.

GADAdLoaderOptions

When making a request for native ads, publishers provide an array of GADAdLoaderOptions objects to specify their preferences for that request, such as how image assets should be returned. These are in turn provided to custom events as one of the parameters in the requestNativeAdWithParameter: method. Custom events should iterate over the options array, and act in accordance with the preferences it contains.

For example, if the options array contains a GADNativeAdImageAdLoaderOptions object with its shouldDownloadImages value set to true, the custom event must return actual image assets rather than just the URLs. In this case, if the SDK being adapted only ever provides URLs for images, then the custom event must use those urls to download the image files and make their data available to the publisher.

Forward events to the Mobile Ads SDK

A few things can happen when a custom event tries to load a native ad from its mediated network. The SDK could successfully return a native ad, it could come back with an error, or it might simply report that no ads are available. It's important for the Google Mobile Ads SDK to be aware of these events, so the GADCustomEventNativeAd protocol includes a delegate (of type GADCustomEventNativeAdDelegate), which the custom event can use to forward them.

It's part of a custom event's job to act as a "man in the middle," listening for events from the mediated SDK, and then sending the corresponding GADCustomEventNativeAdDelegate protocol message to the delegate as appropriate. Your custom event needs to be aware of the following messages :

  • customEventNativeAd:didReceiveMediatedUnifiedNativeAd: - This message should be sent when a custom event successfully loads a native ad. It takes a single parameter of type GADMediatedUnifiedNativeAd, which the custom event should use to pass an "adapted" version of the native ad it just loaded (GADMediatedUnifiedNativeAd classes are covered in the next section).
  • customEventNativeAd:didFailToLoadWithError: - When the custom event tries and fails to load a native ad, it should use this method to report the failure. It takes a single NSError parameter, which should contain information specific to the failure.

Here's an example of how this works in our example custom event project:

SampleCustomEventNativeAd (excerpt)

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

The class implements the Sample SDK's SampleNativeAdLoaderDelegate protocol. In SampleCustomEventNativeAd.m (excerpt) the custom event class itself was assigned to the SampleNativeAdLoader as its delegate:

Swift

adLoader.delegate = self

Objective-C

adLoader.delegate = self;

This ensures that the Sample SDK sends messages back to the custom event when it has success or failure to report. The custom event then sends the appropriate message to its own delegate, forwarding the event to the Google Mobile Ads SDK. In short, the Google Mobile Ads SDK listens to the custom event, which is listening to the mediated SDK.

The adLoader:didFailToLoadAdWithErrorCode method above is a great example of how this works. When the Sample SDK fails to load an ad, it sends an adLoader:didFailToLoadAdWithErrorCode: message to the custom event. The custom event creates a new NSError object with the SampleErrorCode provided by the Sample SDK, and then sends it to its own delegate via the customEventNativeAd:didFailToLoadWithError: message. In this way, a Sample SDK event is turned into a Google Mobile Ads SDK event.

Map native ads

Different SDKs have their own unique formats for native ads. One SDK might return objects that contain a "title" field, for instance, while another might have "headline." Additionally, the methods used to track impressions and process clicks may vary from one SDK to another. To smooth out these wrinkles, when a custom event receives a native ad object from its mediated network's SDK, it should use a subclass of GADMediatedNativeAd to "map" the mediated SDK's native ad object so it matches the interface expected by the Google Mobile Ads SDK.

The DFP's system-defined unified native ad format has a corresponding GADMediatedUnifiedNativeAd class. Custom events should create a subclass of this to map the native ad objects provided by their mediated SDK.

Here's an example mapper class from our example custom event project:

Swift

class SampleMediatedNativeAdSwift: NSObject {

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

  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
  }

}

extension SampleMediatedNativeAdSwift : 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 extraAssets : [String : Any]? {
    return extras
  }

  var adChoicesView : UIView? {
    return adInfoView
  }

  func didRecordImpression() {
    sampleAd.recordImpression()
  }

// 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
// didRenderInView:viewController here. If your mediated network does
// need a reference to the view, this method can be used to provide one.
  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.
  }

  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

// SampleMediatedNativeAppAd.h (excerpt)

@interface SampleMediatedNativeAd : NSObject<GADMediatedUnifiedNativeAd>

- (nullable instancetype)initWithSampleNativeAd:(nonnull SampleNativeAd *)sampleNativeAd
                          nativeAdViewAdOptions:
                              (nullable GADNativeAdViewAdOptions *)nativeAdViewAdOptions;

@end

// SampleMediatedNativeAd.m (excerpt)

@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];
    }

    _nativeAdViewAdOptions = nativeAdViewAdOptions;
  }
  return self;
}

- (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;
}

// 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:nonC
// lickableAssetViews 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.

  if (!_adInfoView) {
    _adInfoView = [[SampleAdInfoView alloc] init];
  }

  [view addSubview:_adInfoView];
  [self updateAdInfoViewPositionInSuperView:view];
}

- (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.

  // Remove the previously added AdChoices view from the ad view.
  if (!_adInfoView) {
    [_adInfoView removeFromSuperview];
  }
}

- (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];
  }
}

Let's first take a look at the initializer and some of the work it's doing.

Hold a reference to the mediated native ad object

The initializer accepts an instance of SampleNativeAd as its only parameter. This is the native ad class used by the Sample SDK for its native ads. The mapper needs a reference to the mediated ad object so it can pass on click and impression events, so it stores one as sampleAd.

Create an NSDictionary to hold extra assets

Some mediated networks may provide additional assets beyond those in the DFP native ad formats. The GADMediatedUnifiedNativeAd protocol includes a method called extraAssets that the Google Mobile Ads SDK uses to retrieve any of these "extra" assets from your mapper. The initializer above creates an NSDictionary and fills it with the extra assets provided by the Sample SDK (in this case, a single NSString value called degreeOfAwesomeness). This NSDictionary is used as a return value by the extraAssets method later on:

Swift

extras = [SampleCustomEventExtraKeyAwesomeness : sampleAd.degreeOfAwesomeness]

Objective-C

_extras = @{SampleCustomEventExtraKeyAwesomeness : _sampleAd.degreeOfAwesomeness};

Map image assets

Mapping image assets is a little more complicated than mapping simpler data types like NSString or double. Images might be downloaded automatically or simply returned as URL values. Their pixel density can also vary. To help custom event developers manage these details, the Google Mobile Ads SDK provides the GADNativeAdImage class. Image asset information (whether it's actual UIImage objects or just NSURL values) should be returned to the Google Mobile Ads SDK using this class. Here's how the mapper class handles creating a GADNativeAdImage to hold the icon image for its app install ad:

Swift

if let icon = sampleAd.icon {
  mappedIcon = GADNativeAdImage(image: icon)
} else {
  let iconURL = URL(fileURLWithPath: sampleNativeAppInstallAd.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];
}

If you recall from the section on making requests, publishers can use a GADNativeAdImageAdLoaderOptions object to specify that native ad images shouldn't be automatically downloaded. Here, the mapper checks to see if the image was downloaded already, and creates a GADNativeAdImage with the appropriate information—either a UIImage or a matching pair of NSURL and scale values.

With the initializer covered, let's move on to the work being done elsewhere in the class.

Return mapped assets

This mapper class inherits methods from GADMediatedUnifiedNativeAd that correspond to the expected assets for a native ad. The Google Mobile Ads SDK calls these methods to retrieve the assets, so your mapper class should return the appropriate value. For most assets, this is pretty simple:

Swift

var headline : String? {
  return sampleAd.headline
}

Objective-C

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

For some assets, however, data types may not match or some other type of conversion may be required. It's the mapper's job to handle these details, and the asset methods are a good place to do it.

AdChoices

Your adapter is responsible for providing an AdChoices icon. The adChoicesView method is an optional method of the GADMediatedNativeAppInstallAd and GADMediatedNativeContentAd protocols. When implemented, the SDK will take the provided Ad Choices View and display it in the native ad. A sample implementation of how to provide the AdChoices icon is shown below:

Swift

class SampleMediatedNativeAd: 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;
}

Impression and click events

It's important that the mediated network's SDK is notified any time an impression or click occurs, so Mapper classes are responsible for either providing the mediated network SDK with the information it needs to handle impression and click tracking on it's own, or to explicitly notify the mediated network SDK when an impression or click occurs.

If the mediated native ad objects provide methods to record clicks and impressions, a custom event's mapper classes can use them. This is the most common approach. GADMediatedUnifiedNativeAd includes two methods, didRecordImpression: and didRecordClickOnAssetWithName:view:viewController:, which mappers should override and use to call the corresponding method on the mediated native ad object.

Here's how the SampleMediatedNativeAd handles this:

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];
  }
}

Because the SampleMediatedNativeAd holds a reference to the Sample SDK's native ad object, it can simply call the appropriate method on that object to report a click or impression.

Let the mediated SDK track clicks and impressions

For ad networks that need to track clicks and impressions on their own, GADCustomEventNativeAd protocol offers two optional messages: handlesUserClicks and handlesUserImpressions. Returning a YES from one of these indicates the custom event tracks that type of occurrence for itself. Returning a NO or not responding indicates that the Google Mobile Ads SDK should handle tracking clicks and impressions on behalf of the custom event and use didRecordImpression: and didRecordClickOnAssetWithName: on the GADMediatedUnifiedNativeAd to report them.

Custom events tracking clicks or impressions themselves can use the didRenderInView: message in the GADMediatedUnifiedNativeAd protocol to pass the native ad's view to the mediated SDK's native ad object, so the mediated SDK can use it to do the actual tracking. The sample SDK shown so far in this guide's code examples doesn't use this approach for handling clicks and impressions, but if it did, the appropriate didRenderInView: method would look like this:

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 also includes didUntrackView:, which is used for the opposite purpose. Custom events should implement it to release any references to the view and if possible disassociate it from the native ad object.

GADMediatedNativeAdNotificationSource

In order for mediated native ads to report events like the presentation of a screen or recording of a click, the SDK provides the GADMediatedNativeAdNotificationSource class. It has six class methods corresponding to various events in the life of a mediated native ad, each taking a reference to the corresponding ad object:

  • mediatedNativeAdDidRecordImpression: - This method should be called by mediated native ads from custom events that track impressions for themselves to report an impression back to the Google Mobile Ads SDK. This is required for reporting purposes.
  • mediatedNativeAdDidRecordClick: - Similarly, custom events that track their own clicks should have their mediated native ads call this method to report that a click has occurred.
  • mediatedNativeAdWillPresentScreen: - Must be called just before a mediated native ad opens an in-app modal screen.
  • mediatedNativeAdWillDismissScreen: - Must be called just before the in-app modal screen opened by the mediated native ad is dismissed.
  • mediatedNativeAdDidDismissScreen: - Must be called after an in-app modal screen opened by the mediated native ad is dismissed.
  • mediatedNativeAdWillLeaveApplication: - Must be called just before the mediated native ad causes focus to leave the application, such as when opening a destination URL in Safari.

Use a custom event

To use a custom event, you need to add it to the mediation configuration for an ad unit. This is done in the Mobile SDK mediation provides instructions.

When you add the custom event to an ad unit's mediation configuration, you'll be asked for three pieces of information:

  • Class Name - This is the class name of your custom event.
  • Label - This is the label you'd like DFP's interface to use to represent the custom event when it displays the ad unit's mediation sources.
  • Parameter - This is a string value that is passed to the custom event whenever requests for this ad unit are made. Typically this value is set to an ad unit ID from the mediated network.

Here's a screenshot of an example custom event entry:

That's it! You now have everything you need to write your own iOS custom events for DFP.

Send feedback about...

Google Mobile Ads SDK for DoubleClick for Publishers iOS Apps
Need help? Visit our support page.