<br />

## Prerequisites

Complete the [custom events setup](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/custom-events/setup.md.txt).

## Request a rewarded ad

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

To request a rewarded ad, create or modify a class that implements
`GADMediationAdapter` and `loadRewarded:adConfiguration:completionHandler:`. If
a class that extends `GADMediationAdapter` already exists, implement
`loadRewarded:adConfiguration:completionHandler:` there. Additionally,
create a new class to implement `GADMediationRewardedAd`.

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
`SampleCustomEventRewarded`.

### Swift

```swift
import GoogleMobileAds

class SampleCustomEvent: NSObject, MediationAdapter {

  fileprivate var rewardedAd: SampleCustomEventRewarded?
  ...

  func loadRewarded(
    for adConfiguration: MediationRewardedAdConfiguration,
    completionHandler: @escaping GADMediationRewardedLoadCompletionHandler
  ) {
    self.rewardedAd = SampleCustomEventRewarded()
    self.rewardedAd?.loadRewarded(
      for: adConfiguration, completionHandler: completionHandler)
  }
}
```

### Objective-C

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

@implementation SampleCustomEvent
...

SampleCustomEventRewarded *sampleRewarded;

- (void)loadRewardedForAdConfiguration:
            (GADMediationRewardedAdConfiguration *)adConfiguration
                     completionHandler:
                         (GADMediationRewardedLoadCompletionHandler)
                             completionHandler {
  sampleRewarded = [[SampleCustomEventRewarded alloc] init];
  [sampleRewarded loadRewardedForAdConfiguration:adConfiguration
                               completionHandler:completionHandler];
}
```

`SampleCustomEventRewarded` is responsible for the following tasks:

- Loading the rewarded ad.

- Implementing the `GADMediationRewardedAd` protocol.

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

The optional parameter defined in the Ad Manager 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
class SampleCustomEventRewarded: NSObject, MediationRewardedAd {
  /// The Sample Ad Network rewarded ad.
  var nativeAd: SampleRewarded?

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

  /// Completion handler called after ad load.
  var completionHandler: GADMediationRewardedLoadCompletionHandler?

  func loadRewarded(
    for adConfiguration: MediationRewardedAdConfiguration,
    completionHandler: @escaping GADMediationRewardedLoadCompletionHandler
  ) {
    rewarded = SampleRewarded.init(
      adUnitID: adConfiguration.credentials.settings["parameter"] as? String)
    rewarded?.delegate = self
    let adRequest = SampleAdRequest()
    adRequest.testMode = adConfiguration.isTestRequest
    self.completionHandler = completionHandler
    rewarded?.fetchAd(adRequest)
  }
}
```

### Objective-C

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

@interface SampleCustomEventRewarded () <SampleRewardedAdDelegate,
                                         GADMediationRewardedAd> {
  /// The sample rewarded ad.
  SampleRewarded *_rewardedAd;

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

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

- (void)loadRewardedAdForAdConfiguration:(GADMediationRewardedAdConfiguration *)adConfiguration
                       completionHandler:
                           (GADMediationRewardedLoadCompletionHandler)completionHandler {
  __block atomic_flag completionHandlerCalled = ATOMIC_FLAG_INIT;
  __block GADMediationRewardedLoadCompletionHandler originalCompletionHandler =
      [completionHandler copy];

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

    id<GADMediationRewardedAdEventDelegate> 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"];
  _rewardedAd = [[SampleRewardedAd alloc] initWithAdUnitID:adUnit];
  _rewardedAd.delegate = self;
  SampleAdRequest *adRequest = [[SampleAdRequest alloc] init];
  adRequest.testMode = adConfiguration.isTestRequest;
  [_rewardedAd fetchAd:adRequest];
}
```

Whether the ad is successfully fetched or encounters an error, you
would call `GADMediationRewardedLoadCompletionHandler`. In the event of
success, pass through the class that implements `GADMediationRewardedAd`
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 `SampleRewardedAdDelegate` with relevant callbacks:

### Swift

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

func rewarded(
  rewarded: SampleRewarded, didFailToLoadAdWith errorCode: SampleErrorCode
) {
  let error =
    SampleCustomEventUtils.SampleCustomEventErrorWithCodeAndDescription(
      code: SampleCustomEventErrorCode
        .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)rewardedDidLoad:(SampleRewarded *)rewarded {
  _adEventDelegate = _loadCompletionHandler(self, nil);
}

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

`GADMediationrewardedAd` requires implementing a `present(viewController:)`
method to display the ad:

### Swift

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

### Objective-C

```objective-c
- (void)presentFromViewController:(UIViewController *)viewController {
  if ([_rewardedAd isRewardedLoaded]) {
    [_rewardedAd show];
  } else {
    NSError *error = SampleCustomEventErrorWithCodeAndDescription(
        SampleCustomEventErrorAdNotLoaded,
        [NSString stringWithFormat:
                      @"The rewarded 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 `GADMediationRewardedLoadCompletionHandler` with a loaded
ad, the returned `GADMediationRewardedAdEventDelegate` delegate object can
then be used by the adapter to forward presentation events from the third-party
SDK to Google Mobile Ads SDK. The `SampleCustomEventRewarded` class
implements the `SampleRewardedAdDelegate` 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 rewardedAdDidPresent(_ rewarded: SampleRewardedAd) {
  delegate?.willPresentFullScreenVideo()
  delegate?.didStartVideo()
}

func rewardedAdUserDidEarnReward(_ rewarded: SampleRewardedAd) {
  AdReward aReward = AdReward("", rewarded)
  delegate.didRewardUser()
}
```

### Objective-C

```objective-c
- (void)rewardedAdDidPresent:(SampleRewardedAd *)rewardedAd {
  [_adEventDelegate willPresentFullScreenView];
  [_adEventDelegate didStartVideo];
}

- (void)rewardedAd:(nonnull SampleRewardedAd *)rewardedAd
    userDidEarnReward:(NSUInteger)reward {
  GADAdReward *aReward = [[GADAdReward alloc]
      initWithRewardType:@""
            rewardAmount:[NSDecimalNumber numberWithUnsignedInt:reward]];
  [_adEventDelegate didRewardUserWithReward];
}
```

This completes the custom events implementation for rewarded 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 rewarded ads.