Add Rewarded Video Ads to an iOS App

Rewarded video ads are a full screen experience where users opt-in to view a video ad in exchange for something of value, such as virtual currency, in-app items, exclusive content, and more. The ad experience is 15-30 second non-skippable and contains an end card with a call to action. Upon completion of the full video, you will receive a callback to grant the suggested reward to the user.

Below are details on how to implement rewarded video ads from Audience Network on iOS.

Please note, Rewarded Video is only supported for iOS 9 and above.

Set up the SDK

The Audience Network Rewarded Video format is now included in the public SDK. Rewarded video will be available for all gaming apps soon. If you don’t see Rewarded Video in Monetization Manager and you're on the latest SDK, apply now.

Ensure you have completed the Audience Network Getting Started and iOS Getting Started guides before you proceed.

Implementation

Now, in your View Controller header file (or Swift file, if you are a Swift user), import FBAudienceNetwork, declare conformance to the FBRewardedVideoAdDelegate protocol, and add an instance variable for the rewarded video ad unit

import UIKit
import FBAudienceNetwork

class ViewController: UIViewController, FBRewardedVideoAdDelegate {
  private var rewardedVideoAd: FBRewardedVideoAd?
}
#import <UIKit/UIKit.h>
@import FBAudienceNetwork;

@interface ViewController : UIViewController <FBRewardedVideoAdDelegate>

@property (nonatomic, strong) FBRewardedVideoAd *rewardedVideoAd;

@end

Add a function in your View Controller that initializes the rewarded video object and caches the video creative ahead of the time you want to show it

override func viewDidLoad() {
  super.viewDidLoad()
  
  // Instantiate an rewarded video object.
  // NOTE: the placement ID will eventually identify this as your app. You can ignore it while you are testing
  // and replace it later when you have signed up.
  // While you are using this temporary code you will only get test ads and if you release
  // your code like this to the App Store your users will not receive ads (you will get a 'No Fill' error).
  let rewardedVideoAd = FBRewardedVideoAd(placementID: "YOUR_PLACEMENT_ID")
  rewardedVideoAd.delegate = self
  
  // For auto play video ads, it's recommended to load the ad at least 30 seconds before it is shown
  rewardedVideoAd.load()
  
  self.rewardedVideoAd = rewardedVideoAd
}
- (void) viewDidLoad 
{
  [super viewDidLoad];
  // Instantiate a rewarded video ad object. 
  // NOTE: the placement ID will eventually identify this as your app. You can ignore it while 
  // you are testing and replace it later when you have signed up.
  // While you are using this temporary code you will only get test ads and if you release
  // your code like this to the App Store your users will not receive ads (you will get a 'No Fill' error).
  self.rewardedVideoAd = [[FBRewardedVideoAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
  self.rewardedVideoAd.delegate = self;

  // For auto play video ads, it's recommended to load the ad at least 30 seconds before it is shown
  [self.rewardedVideoAd loadAd];
}

The ID that displays at YOUR_PLACEMENT_ID is a temporary ID for test purposes only.

If you use this temporary ID in your live code, your users will not receive ads (they will get a No Fill error). You must return here after testing and replace this temporary ID with a live Placement ID.

To find out how the generate a live Placement ID, refer to Audience Network Setup

Now that you have added the code to load the ad, you can add functions which will handle various events.

For example:

  • rewardedVideoAdDidLoad ensures your app is aware when the ad is cached and ready to be displayed
  • rewardedVideoAdVideoComplete lets you know when to deliver your reward to the user after a completed video view
func rewardedVideoAdDidLoad(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("Video ad is loaded and ready to be displayed")
}

func rewardedVideoAd(_ rewardedVideoAd: FBRewardedVideoAd, didFailWithError error: Error) {
  print("Rewarded video ad failed to load")
}

func rewardedVideoAdDidClick(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("Video ad clicked")
}

func rewardedVideoAdDidClose(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("Rewarded Video ad closed - this can be triggered by closing the application, or closing the video end card")
}

func rewardedVideoAdVideoComplete(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("Rewarded Video ad video completed - this is called after a full video view, before the ad end card is shown. You can use this event to initialize your reward")
}
- (void)rewardedVideoAdDidLoad:(FBRewardedVideoAd *)rewardedVideoAd
{
  NSLog(@"Video ad is loaded and ready to be displayed");
}
    
- (void)rewardedVideoAd:(FBRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *)error
{
  NSLog(@"Rewarded video ad failed to load");
}

- (void)rewardedVideoAdDidClick:(FBRewardedVideoAd *)rewardedVideoAd
{
  NSLog(@"Video ad clicked");
}
    
- (void)rewardedVideoAdDidClose:(FBRewardedVideoAd *)rewardedVideoAd
{
  NSLog(@"Rewarded Video ad closed - this can be triggered by closing the application, or closing the video end card");
}

- (void)rewardedVideoAdVideoComplete:(FBRewardedVideoAd *)rewardedVideoAd;
{
  NSLog(@"Rewarded Video ad video completed - this is called after a full video view, before the ad end card is shown. You can use this event to initialize your reward");
}

Finally, when you are ready to show the rewarded video ad you can call the following code within your own reward function.

private func showRewardedVideoAd() {
  guard let rewardedVideoAd = rewardedVideoAd, rewardedVideoAd.isAdValid else {
    return
  }
  rewardedVideoAd.show(fromRootViewController: self)
}
- (void)showRewardedVideoAd
{
  if (self.rewardedVideoAd && self.rewardedVideoAd.isAdValid) {
    [self.rewardedVideoAd showAdFromRootViewController:self];
  }
}

The method to show a rewarded video ad includes an animated boolean flag which allows you to animate the presentation. By default it is set to YES / true, but you can override it.

When running on the simulator, test ads will be shown by default. To enable test ads on a device, add the following line of code before loading an ad: AdSettings.addTestDevice(HASHED ID). Use the hashed ID that is printed to the log cat when you first make a request to load an ad on a device.

Optionally, you can add the following additional functions to handle the cases where the rewarded video ad will close or when the rewarded video impression is being captured:

func rewardedVideoAdWillClose(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("The user clicked on the close button, the ad is just about to close")
}

func rewardedVideoAdWillLogImpression(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("Rewarded Video impression is being captured")
}
- (void)rewardedVideoAdWillClose:(FBRewardedVideoAd *)rewardedVideoAd
{
  NSLog(@"The user clicked on the close button, the ad is just about to close");
}

- (void)rewardedVideoAdWillLogImpression:(FBRewardedVideoAd *)rewardedVideoAd
{
  NSLog(@"Rewarded Video impression is being captured");
}

Server Side Reward Validation

Overview

If you manage your user rewards server-side, then Facebook offers a solution for carrying this out securely by using a validation technique. Our server will communicate with a specified https endpoint to validate each ad impression and validate whether a reward should be granted.

  1. Audience Network SDK requests a rewarded video ad with the following parameters:
    • Audience Network Placement ID
    • Unique User ID - an attribute you use to identify a unique user. For example, a numeric identifier
    • Reward Value - the value of the reward you would like to grant the user. For example, 100Coins specified end point, together with the App Secret.
  2. Upon receipt, the server validates the request and responds as follows:
    • 200 response: request is valid and the reward should be delivered
    • Non 200 response: request is not valid, and the reward should not be delivered.
  3. Once the video is complete, the end card is presented and one of the following events will fire.
    • onRewardServerSuccess - triggered only if a 200 response was received during step 3.
    • onRewardServerFailed - triggered if a non 200 response was received during step 3.

An example of the URL which will hit your publisher end point, from Facebook's server.

https://www.your_end_point.com/?token=APP_SECRET&puid=USER_ID&pc=REWARD_ID&ptid=UNIQUE_TRANSACTION_ID

Please provide your publisher end point to your Facebook representative in order to enable this feature.

SDK Implementation

It is possible to set the Reward Data (USER_ID and CURRENCY) before, or after the loadAd method. Both are demonstrated in the code snippet below.

let rewardedVideoAd = FBRewardedVideoAd(placementID: "YOUR_PLACEMENT_ID")
rewardedVideoAd.delegate = self

// Set the rewarded ad data before or after `load` method is called
rewardedVideoAd.setRewardDataWithUserID("USER_ID", withCurrency: "CURRENCY")

// For auto play video ads, it's recommended to load the ad at least 30 seconds before it is shown
rewardedVideoAd.load()

self.rewardedVideoAd = rewardedVideoAd
self.rewardedVideoAd = [[FBRewardedVideoAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
self.rewardedVideoAd.delegate = self;

// Set the rewarded ad data before or after `loadAd` method is called
[self.rewardedVideoAd setRewardDataWithUserID:@"USER_ID" withCurrency:@"CURRENCY"];

[self.rewardedVideoAd loadAd];

In addition to the functions noted above in the FBRewardedVideoAdDelegate, the following events should be used to hande the granting of rewards in your app. The following can be used alongise the events monetioned above.

func rewardedVideoAdServerRewardDidFail(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("Rewarded video ad not validated, or no response from server")
}

func rewardedVideoAdServerRewardDidSucceed(_ rewardedVideoAd: FBRewardedVideoAd) {
  print("Rewarded video ad validated by server")
}
- (void)rewardedVideoAdServerRewardDidSucceed:(FBRewardedVideoAd *)rewardedVideoAd
{
  NSLog(@"Rewarded video ad validated by server");
}

- (void)rewardedVideoAdServerRewardDidFail:(FBRewardedVideoAd *)rewardedVideoAd
{
  NSLog(@"Rewarded video ad not validated, or no response from server");
}

Please note - the server validation callbacks will only occur after the end card has been dismissed by a user. You should not deallocate the rewarded video object until after one of these callbacks.

Next Steps