Rewarded ads

Select platform: Android iOS Unity Flutter

Rewarded ads are ads that users have the option of interacting with in exchange for in-app rewards . This guide shows you how to integrate rewarded ads from AdMob into an iOS app. Read some customer success stories: case study 1 , case study 2 .

Prerequisites

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 the Mobile Ads SDK's test ads work, see 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) 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 
 ; 
  
 }]; 
  
 

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

Apps that require extra data in server-side verification 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 SAMPLE_CUSTOM_DATA_STRING with your custom data.

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

SwiftUI

  rewardedAd 
 ?. 
 fullScreenContentDelegate 
  
 = 
  
 self  
 
 . 
 swift 
 

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 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, the 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, the 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 completion handler always get called before the adDidDismissFullScreenContent: delegate method?

For Google ads, all userDidEarnRewardHandler calls occur before adDidDismissFullScreenContent: . For ads served through 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:

Next steps

Learn more about user privacy .

Create a Mobile Website
View Site in Mobile | Classic
Share by: