<br />

## Prerequisites

Complete the [custom events setup](https://developers.google.com/admob/ios/custom-events/setup.md.txt).

## Request an interstitial ad

When the custom event line item is reached in the waterfall mediation chain,
the `loadInterstitial:adConfiguration:completionHandler:` method is called on
the class name you provided when [creating a custom
event](https://developers.google.com/admob/ios/custom-events/custom-events/setup#create). In this case,
that method is in `SampleCustomEvent`, which then calls
the `loadInterstitial:adConfiguration:completionHandler:` method in
`SampleCustomEventInterstitial`.

To request an interstitial ad, create or modify a class that implements
`GADMediationAdapter` and `loadInterstitial:adConfiguration:completionHandler:`.
If a class that extends `GADMediationAdapter` already exists, implement
`loadInterstitial:adConfiguration:completionHandler:` there. Additionally,
create a new class to implement `GADMediationInterstitialAd`.

In our custom event example,
[`SampleCustomEvent`](https://github.com/googleads/googleads-mobile-ios-mediation/blob/main/example/CustomEvent/SampleCustomEvent.m) implements
the `GADMediationAdapter` interface and then delegates to
`SampleCustomEventInterstitial`.

### Swift

```swift
import GoogleMobileAds

class SampleCustomEvent: NSObject, MediationAdapter {

  fileprivate var interstitialAd: SampleCustomEventInterstitial?
  ...

  func loadInterstitial(
    for adConfiguration: MediationInterstitialAdConfiguration,
    completionHandler: @escaping GADMediationInterstitialLoadCompletionHandler
  ) {
    self.interstitialAd = SampleCustomEventInterstitial()
    self.interstitialAd?.loadInterstitial(
      for: adConfiguration, completionHandler: completionHandler)
  }
}
```

### Objective-C

```objective-c
#import "SampleCustomEvent.h"

@implementation SampleCustomEvent

SampleCustomEventInterstitial *sampleInterstitial;

- (void)loadInterstitialForAdConfiguration:
            (GADMediationInterstitialAdConfiguration *)adConfiguration
                         completionHandler:
                             (GADMediationInterstitialLoadCompletionHandler)
                                 completionHandler {
  sampleInterstitial = [[SampleCustomEventInterstitial alloc] init];
  [sampleInterstitial loadInterstitialForAdConfiguration:adConfiguration
                                       completionHandler:completionHandler];
}
```

`SampleCustomEventInterstitial` is responsible for the following tasks:

- Loading the interstitial ad and invoking a
  [`GADMediationInterstitialAdLoadCompletionHandler`](https://developers.google.com/admob/ios/api/reference/Protocols/GADMediationAdapter.md.txt)
  method once loading completes.

- Implementing the `GADMediationInterstitialAd` protocol.

- Receiving and reporting ad event callbacks to Google Mobile Ads SDK.

The optional parameter defined in the UI is
included in the ad configuration.
The parameter can be accessed through
`adConfiguration.credentials.settings[@"parameter"]`. This parameter is
typically an ad unit identifier that an ad network SDK requires when
instantiating an ad object.

### Swift

```swift
import GoogleMobileAds

class SampleCustomEventInterstitial: NSObject, MediationInterstitialAd {
  /// The Sample Ad Network interstitial ad.
  var interstitial: SampleInterstitial?

  /// The ad event delegate to forward ad rendering events to Google Mobile Ads SDK.
  var delegate: MediationInterstitialAdEventDelegate?

  var completionHandler: GADMediationInterstitialLoadCompletionHandler?

  func loadInterstitial(
    for adConfiguration: MediationInterstitialAdConfiguration,
    completionHandler: @escaping GADMediationInterstitialLoadCompletionHandler
  ) {
    interstitial = SampleInterstitial.init(
      adUnitID: adConfiguration.credentials.settings["parameter"] as? String)
    interstitial?.delegate = self
    let adRequest = SampleAdRequest()
    adRequest.testMode = adConfiguration.isTestRequest
    self.completionHandler = completionHandler
    interstitial?.fetchAd(adRequest)
  }

  func present(from viewController: UIViewController) {
    if let interstitial = interstitial, interstitial.isInterstitialLoaded {
      interstitial.show()
    }
  }
}
```

### Objective-C

```objective-c
#import "SampleCustomEventInterstitial.h"

@interface SampleCustomEventInterstitial () <SampleInterstitialAdDelegate,
                                             GADMediationInterstitialAd> {
  /// The sample interstitial ad.
  SampleInterstitial *_interstitialAd;

  /// The completion handler to call when the ad loading succeeds or fails.
  GADMediationInterstitialLoadCompletionHandler _loadCompletionHandler;

  /// The ad event delegate to forward ad rendering events to the Google Mobile
  /// Ads SDK.
  id <GADMediationInterstitialAdEventDelegate> _adEventDelegate;
}
@end

- (void)loadInterstitialForAdConfiguration:
            (GADMediationInterstitialAdConfiguration *)adConfiguration
                         completionHandler:
                             (GADMediationInterstitialLoadCompletionHandler)
                                 completionHandler {
  __block atomic_flag completionHandlerCalled = ATOMIC_FLAG_INIT;
  __block GADMediationInterstitialLoadCompletionHandler
      originalCompletionHandler = [completionHandler copy];

  _loadCompletionHandler = ^id<GADMediationInterstitialAdEventDelegate>(
      _Nullable id<GADMediationInterstitialAd> ad, NSError *_Nullable error) {
    // Only allow completion handler to be called once.
    if (atomic_flag_test_and_set(&completionHandlerCalled)) {
      return nil;
    }

    id<GADMediationInterstitialAdEventDelegate> 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;
  };

  NSString *adUnit = adConfiguration.credentials.settings[@"parameter"];
  _interstitialAd = [[SampleInterstitial alloc] initWithAdUnitID:adUnit];
  _interstitialAd.delegate = self;
  SampleAdRequest *adRequest = [[SampleAdRequest alloc] init];
  adRequest.testMode = adConfiguration.isTestRequest;
  [_interstitialAd fetchAd:adRequest];
}
```

Whether the ad is successfully fetched or encounters an error, you
would call `GADMediationInterstitialLoadCompletionHandler`. In the event of
success, pass through the class that implements `GADMediationInterstitialAd`
with a `nil` value for the error parameter; in the event of failure, pass
through the error you encountered.

Typically, these methods are implemented inside callbacks from the
third-party SDK your adapter implements. For this example, the Sample SDK
has a `SampleInterstitialAdDelegate` with relevant callbacks:

### Swift

```swift
func interstitialDidLoad(_ interstitial: SampleInterstitial) {
  if let handler = completionHandler {
    delegate = handler(self, nil)
  }
}

func interstitial(
  _ interstitial: SampleInterstitial,
  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

```objective-c
- (void)interstitialDidLoad:(SampleInterstitial *)interstitial {
  _adEventDelegate = _loadCompletionHandler(self, nil);
}

- (void)interstitial:(SampleInterstitial *)interstitial
    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);
}
```

`GADMediationInterstitialAd` requires implementing a `present` method to display
the ad:

### Swift

```swift
func present(from viewController: UIViewController) {
  if let interstitial = interstitial, interstitial.isInterstitialLoaded {
    interstitial.show()
  }
}
```

### Objective-C

```objective-c
- (void)presentFromViewController:(UIViewController *)viewController {
  if ([_interstitialAd isInterstitialLoaded]) {
    [_interstitialAd show];
  } else {
    NSError *error = SampleCustomEventErrorWithCodeAndDescription(
        SampleCustomEventErrorAdNotLoaded,
        [NSString stringWithFormat:@"The interstitial ad failed to present "
                                   @"because the ad was not loaded."]);
    [_adEventDelegate didFailToPresentWithError:error]
  }
}
```

## Forward mediation events to Google Mobile Ads SDK

Once you've called `GADMediationInterstitialLoadCompletionHandler` with a loaded
ad, the returned `GADMediationInterstitialAdEventDelegate` delegate object can
then be used by the adapter to forward presentation events from the third-party
SDK to Google Mobile Ads SDK. The `SampleCustomEventInterstitial` class
implements the `SampleInterstitialAdDelegate` protocol to forward callbacks from
the sample ad network to Google Mobile Ads SDK.

It's important that your custom event forwards as many of these callbacks as
possible, so that your app receives these equivalent events from Google Mobile Ads SDK.
Here's an example of using callbacks:

### Swift

```swift
func interstitialWillPresentScreen(_ interstitial: SampleInterstitial) {
  delegate?.willPresentFullScreenView()
  delegate?.reportImpression()
}

func interstitialWillDismissScreen(_ interstitial: SampleInterstitial) {
  delegate?.willDismissFullScreenView()
}

func interstitialDidDismissScreen(_ interstitial: SampleInterstitial) {
  delegate?.didDismissFullScreenView()
}

func interstitialWillLeaveApplication(_ interstitial: SampleInterstitial) {
  delegate?.reportClick()
}
```

### Objective-C

```objective-c
- (void)interstitialWillPresentScreen:(SampleInterstitial *)interstitial {
  [_adEventDelegate willPresentFullScreenView];
  [_adEventDelegate reportImpression];
}

- (void)interstitialWillDismissScreen:(SampleInterstitial *)interstitial {
  [_adEventDelegate willDismissFullScreenView];
}

- (void)interstitialDidDismissScreen:(SampleInterstitial *)interstitial {
  [_adEventDelegate didDismissFullScreenView];
}

- (void)interstitialWillLeaveApplication:(SampleInterstitial *)interstitial {
  [_adEventDelegate reportClick];
}
```

This completes the custom events implementation for interstitial ads. The full
example is available on
[GitHub](https://github.com/googleads/googleads-mobile-ios-mediation/tree/master/example/CustomEvent).
You can use it with an ad network that is already supported or modify it to
display custom event interstitial ads.