Select platform: [Android](https://developers.google.com/admob/android/next-gen/rewarded "View this page for the Android platform documentation.") [iOS](https://developers.google.com/admob/ios/rewarded "View this page for the iOS platform documentation.") [Unity](https://developers.google.com/admob/unity/rewarded "View this page for the Unity platform documentation.") [Flutter](https://developers.google.com/admob/flutter/rewarded "View this page for the Flutter platform documentation.") [Android (Legacy)](https://developers.google.com/admob/android/rewarded "View this page for the Android (Legacy) platform documentation.")

<br />

Rewarded ads are ads that users have the option of interacting with [in exchange
for in-app rewards](https://support.google.com/admob/answer/7313578). This guide
shows you how to integrate rewarded ads from AdMob
into an iOS app.

Read some customer success stories:
[case study 1](https://admob.google.com/home/resources/kongregate-uses-admob-to-boost-revenue-average-30-dollar-cpm/),
[case study 2](https://admob.google.com/home/resources/four-thirty-three-uses-admob-to-boost-mobile-game-revenue-15-percent/).


## Prerequisites

Before you continue, [set up Google Mobile Ads SDK](https://developers.google.com/admob/ios/quick-start).

## Always test with test ads

When building and testing your apps, make sure you use test ads rather than
live, production ads. Failure to do so can lead to suspension of your account.

The easiest way to load test ads is to use our dedicated test ad unit ID for iOS
rewarded ads:

`ca-app-pub-3940256099942544/1712485313`

It's been specially configured to return test ads for every request, and you're
free to use it in your own apps while coding, testing, and debugging. Just make
sure you replace it with your own ad unit ID before publishing your app.

For more information about how Google Mobile Ads SDK test ads work, see [Test
Ads](https://developers.google.com/admob/ios/test-ads).

## Implementation

The primary steps to integrate rewarded ads are as follows:

- Load an ad
- \[Optional\] Validate SSV callbacks
- Register for callbacks
- Display the ad and handle the reward event

### Load an ad

Loading an ad is accomplished using the [`load(adUnitID:request)`](https://developers.google.com/admob/ios/api/reference/Classes/GADRewardedAd#+loadwithadunitid:request:completionhandler:)
method on the `GADRewardedAd` class.

### Swift

    func loadRewardedAd() async {
      do {
        rewardedAd = try await RewardedAd.load(
          // Replace this ad unit ID with your own ad unit ID.
          with: "ca-app-pub-3940256099942544/1712485313", request: Request())
        rewardedAd?.fullScreenContentDelegate = self
      } catch {
        print("Rewarded ad failed to load with error: \(error.localizedDescription)")
      }
    }

### SwiftUI

    import GoogleMobileAds

    class RewardedViewModel: NSObject, ObservableObject, FullScreenContentDelegate {
      @Published var coins = 0
      private var rewardedAd: RewardedAd?

      func loadAd() async {
        do {
          rewardedAd = try await RewardedAd.load(
            with: "ca-app-pub-3940256099942544/1712485313", request: Request())
          rewardedAd?.fullScreenContentDelegate = self
        } catch {
          print("Failed to load rewarded ad with error: \(error.localizedDescription)")
        }
      }

### Objective-C

    // Replace this ad unit ID with your own ad unit ID.
    [GADRewardedAd loadWithAdUnitID:@"ca-app-pub-3940256099942544/1712485313"
                  request:[GADRequest request]
        completionHandler:^(GADRewardedAd *ad, NSError *error) {
          if (error) {
            NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]);
            return;
          }
          self.rewardedAd = ad;
          self.rewardedAd.fullScreenContentDelegate = self;
        }];


> [!TIP]
> **Tip:** You can use ad load calls to build up a cache of preloaded ads before you intend to show them, so that ads can be shown with zero latency when needed. Because ads expire after an hour, you should clear this cache and reload with new ads every hour.

<br />

### \[Optional\] Validate server-side verification (SSV) callbacks

Apps that require extra data in [server-side
verification](https://developers.google.com/admob/ios/ssv) callbacks should use the
custom data feature of rewarded ads. Any string value set on a rewarded ad
object is passed to the `custom_data` query parameter of the SSV callback. If no
custom data value is set, the `custom_data` query parameter value won't be
present in the SSV callback.

The following code sample demonstrates how to set custom data on a rewarded ad
object before requesting an ad:

### Swift

    private func validateServerSideVerification() async {
      do {
        rewardedAd = try await RewardedAd.load(
          // Replace this ad unit ID with your own ad unit ID.
    with: "ca-app-pub-3940256099942544/1712485313", request: Request())
    let options = ServerSideVerificationOptions()
    options.customRewardText = "SAMPLE_CUSTOM_DATA_STRING"
        rewardedAd?.serverSideVerificationOptions = options
      } catch {
        print("Rewarded ad failed to load with error: \(error.localizedDescription)")
      }
    }

### Objective-C

    // Replace this ad unit ID with your own ad unit ID.
    [GADRewardedAd loadWithAdUnitID:@"ca-app-pub-3940256099942544/1712485313"
                            request:[GADRequest request]
                  completionHandler:^(GADRewardedAd *ad, NSError *error) {
                    if (error) {
                      NSLog(@"Rewarded ad failed to load with error: %@", error.localizedDescription);
                      return;
                    }
                    self.rewardedAd = ad;
    GADServerSideVerificationOptions \*options =
    \[\[GADServerSideVerificationOptions alloc\] init\];
    options.customRewardString = @"SAMPLE_CUSTOM_DATA_STRING";
    ad.serverSideVerificationOptions = options;
                  }];

Replace <var translate="no">SAMPLE_CUSTOM_DATA_STRING</var> with your custom data.

> [!IMPORTANT]
> **Key Point:** The custom reward string is [percent
> escaped](https://en.wikipedia.org/wiki/Percent-encoding) and might require decoding when parsed from the SSV callback.

### Register for callbacks

To receive notifications for presentation events, you must assign the
`GADFullScreenContentDelegate` to the `fullScreenContentDelegate` property of the
returned ad:

### Swift

    rewardedAd?.fullScreenContentDelegate = self

### SwiftUI

    rewardedAd?.fullScreenContentDelegate = self

### Objective-C

    self.rewardedAd.fullScreenContentDelegate = self;

The `GADFullScreenContentDelegate` protocol handles callbacks for when the ad
presents successfully or unsuccessfully, and when it is dismissed. The following
code shows how to implement the protocol:

### Swift

    func adDidRecordImpression(_ ad: FullScreenPresentingAd) {
      print("\(#function) called.")
    }

    func adDidRecordClick(_ ad: FullScreenPresentingAd) {
      print("\(#function) called.")
    }

    func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) {
      print("\(#function) called.")
    }

    func adWillDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
      print("\(#function) called.")
    }

    func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
      print("\(#function) called.")
      // Clear the rewarded ad.
      rewardedAd = nil
    }

    func ad(
      _ ad: FullScreenPresentingAd,
      didFailToPresentFullScreenContentWithError error: Error
    ) {
      print("\(#function) called with error: \(error.localizedDescription).")
    }

### SwiftUI

    func adDidRecordImpression(_ ad: FullScreenPresentingAd) {
      print("\(#function) called")
    }

    func adDidRecordClick(_ ad: FullScreenPresentingAd) {
      print("\(#function) called")
    }

    func ad(
      _ ad: FullScreenPresentingAd,
      didFailToPresentFullScreenContentWithError error: Error
    ) {
      print("\(#function) called")
    }

    func adWillPresentFullScreenContent(_ ad: FullScreenPresentingAd) {
      print("\(#function) called")
    }

    func adWillDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
      print("\(#function) called")
    }

    func adDidDismissFullScreenContent(_ ad: FullScreenPresentingAd) {
      print("\(#function) called")
      // Clear the rewarded ad.
      rewardedAd = nil
    }

### Objective-C

    - (void)adDidRecordImpression:(id<GADFullScreenPresentingAd>)ad {
      NSLog(@"%s called", __PRETTY_FUNCTION__);
    }

    - (void)adDidRecordClick:(id<GADFullScreenPresentingAd>)ad {
      NSLog(@"%s called", __PRETTY_FUNCTION__);
    }

    - (void)adWillPresentFullScreenContent:(id<GADFullScreenPresentingAd>)ad {
      NSLog(@"%s called", __PRETTY_FUNCTION__);
    }

    - (void)adWillDismissFullScreenContent:(id<GADFullScreenPresentingAd>)ad {
      NSLog(@"%s called", __PRETTY_FUNCTION__);
    }

    - (void)adDidDismissFullScreenContent:(id<GADFullScreenPresentingAd>)ad {
      NSLog(@"%s called", __PRETTY_FUNCTION__);
      // Clear the rewarded ad.
      self.rewardedAd = nil;
    }

    - (void)ad:(id)ad didFailToPresentFullScreenContentWithError:(NSError *)error {
      NSLog(@"%s called with error: %@", __PRETTY_FUNCTION__, error.localizedDescription);
    }

### Display the ad and handle the reward event

Before displaying a rewarded ad to users, you must present the user with an
explicit choice to view rewarded ad content in exchange for a reward. Rewarded
ads must always be an opt-in experience.

When presenting your ad, you must provide a `GADUserDidEarnRewardHandler` object
to handle the reward for the user.

The following code presents the best method for displaying a rewarded ad:

### Swift

    rewardedAd.present(from: self) {
      let reward = rewardedAd.adReward
      print("Reward received with currency \(reward.amount), amount \(reward.amount.doubleValue)")

      // TODO: Reward the user.
    }

### SwiftUI

Listen to UI events in the view to determine when to show the ad.

    var body: some View {
      VStack(spacing: 20) {
          Button("Watch video for additional 10 coins") {
            viewModel.showAd()
            showWatchVideoButton = false
          }

Present the rewarded ad from the view model:

    func showAd() {
      guard let rewardedAd = rewardedAd else {
        return print("Ad wasn't ready.")
      }

      rewardedAd.present(from: nil) {
        let reward = rewardedAd.adReward
        print("Reward amount: \(reward.amount)")
        self.addCoins(reward.amount.intValue)
      }
    }

### Objective-C

    [self.rewardedAd presentFromRootViewController:self
                          userDidEarnRewardHandler:^{
                            GADAdReward *reward = self.rewardedAd.adReward;
                            NSString *rewardMessage = [NSString
                                stringWithFormat:@"Reward received with currency %@ , amount %lf",
                                                 reward.type, [reward.amount doubleValue]];
                            NSLog(@"%@", rewardMessage);

                            // TODO: Reward the user.
                          }];

## FAQ

Can I get the reward details for the `GADRewardedAd`?
:   Yes, if you need the reward amount before the `userDidEarnReward` callback
    is fired, `GADRewardedAd` has an
    [`adReward`](https://developers.google.com/admob/ios/api/reference/Classes/GADRewardedAd#adreward)
    property that you can check to verify the reward amount after the ad has loaded.

Is there a timeout for the initialization call?
:   After 10 seconds, Google Mobile Ads SDK invokes the
    `GADInitializationCompletionHandler` provided to the
    `startWithCompletionHandler:` method, even if a mediation network still hasn't
    completed initialization.

What if some mediation networks aren't ready when I get the initialization callback?

:   We recommend loading an ad inside the
    `GADInitializationCompletionHandler`. Even if a mediation network is not ready,
    Google Mobile Ads SDK still asks that network for an ad. So if a
    mediation network finishes initializing after the timeout, it can still service
    future ad requests in that session.

    You can continue to poll the initialization status of all adapters throughout
    your app session by calling `GADMobileAds.initializationStatus`.

How do I find out why a particular mediation network isn't ready?

:   The `description` property of a `GADAdapterStatus` object describes why an
    adapter is not ready to service ad requests.

Does the [`userDidEarnRewardHandler`](https://developers.google.com/admob/ios/api/reference/Classes/GADRewardedAd#-presentfromrootviewcontroller:userdidearnrewardhandler:) completion handler always get called before the [`adDidDismissFullScreenContent:`](https://developers.google.com/admob/ios/api/reference/Protocols/GADFullScreenContentDelegate#-addiddismissfullscreencontent:) delegate method?

:   For Google ads, all `userDidEarnRewardHandler` calls occur
    before `adDidDismissFullScreenContent:`. For ads served through
    [mediation](https://developers.google.com/admob/ios/mediation), the third-party ad network
    SDK's implementation determines the callback order. For ad network SDKs that
    provide a single delegate method with reward information, the mediation adapter
    invokes `userDidEarnRewardHandler` before `adDidDismissFullScreenContent:`.

## Examples on GitHub

View the full rewarded ads examples in your preferred language:

- [Swift](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Swift/admob/RewardedVideoExample)
- [SwiftUI](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Swift/advanced/SwiftUIDemo/SwiftUIDemo/Rewarded)
- [Objective-C](https://github.com/googleads/googleads-mobile-ios-examples/tree/main/Objective-C/admob/RewardedVideoExample)

## Next steps

Learn more about [user privacy](https://developers.google.com/admob/ios/privacy).