Prebid SDK iOS with the GAM Prebid-Rendered Integration Method

Overview

This how-to guide covers the ‘Prebid-Rendered’ approach for integrating the Prebid SDK into your app with the GMA SDK. It utilizes:

  • Prebid SDK and Prebid server to handle the bidding and auction process.
  • GAM and the Google Mobile Ads (GMA) SDK manage the ad inventory and select the winning ad to display.
  • Prebid SDK renders display ads when a Prebid bid wins.
  • GMA SDK renders ads when a Prebid bid wins.

If you do not have GMA SDK in the app yet, refer to the Google Integration Documentation.

Alternative Approaches

Another way to integrate GAM into your app is with the GAM Bidding-Only integration.

Tradeoffs between these integration approaches:

Aspect Bidding-Only Integration Prebid-Rendered Integration
App code has direct access to bids check  
Support for MRAID 3.0   check
Support for SKAdnetwork   check
Loads data from Prebid Cache check  
Supports instream video check  
Triggers billing and Notice URLs check  
Supports Third Party Rendering libraries   check

Notes:

  • On one hand, using Prebid Cache reduces the amount of data that must be sent to the mobile device – the body of the creative does not need to be transmitted for bids. On the other hand, though, when a bid wins in the ad server, the body of the creative must be retrieved from the cache.
  • It is possible to mix-and-match implementations within an app. e.g. you could implement instream video with the Bidding-Only approach and other adunits with Prebid-Rendered.

Prerequisites

The GAM Prebid-Rendered Integration method assumes that you have the following components:

  • Google Ad Manager Account - A GAM account allows you to manage and serve ads within your mobile app. Within this account you’ll need to configure your inventory and create orders for serving ads within your app. This involves defining ad units (spaces within your app where ads will be displayed) and setting up orders and line items to deliver ads to those units. See Prebid’s AdOps Guide for more information.
  • Google Mobile Ads (GMA) SDK - This refers to the software development kit provided by Google. You need to ensure that you have the latest version of the GMA SDK supported by Prebid SDK. This SDK integration is necessary to communicate with the ad server and display ads in your app.
  • Prebid SDK - You will need the latest version of the Prebid Mobile SDK for either Android or iOS.
  • Prebid Server - You will need a cluster of servers running Prebid Server. You can set up your own Prebid Server or work with a Prebid Server managed service. Prebid Server provides you with the following:
    • Configuration storage - rather than hardcoding all the details of your current business arrangements in the app, Prebid Server stores which bidders you’re currently working with, their inventory details, and other settings that can be changed without updating your app.
    • Server-side auction - the server will make the connections to multiple auction bidding partners so the app doesn’t have to.
    • Privacy regulation tools - the server can help your legal team meet different regulatory needs in different jurisdictions by configuring various protocols and anonyimization activities.

How it Works

Here’s how the ad bidding-auction-rendering process works in this integration scenario.

GAM Prebid-Rendered Integration Details

  1. Prebid SDK calls Prebid Server which supplies one or more bids.
  2. PBSDK adds targeting values to GMA SDK.
  3. GMA SDK calls GAM, which makes the ad decision.
  4. If a 3rd party HTML creative is chosen (banner, native, interstitial, non-instream video):
    1. GMA SDK writes HTML to a webview, loading google_mobile_app_ads.js.
    2. This script triggers a “PrebidAppEvent”.
    3. Which in turn triggers PBSDK to handle the rendering of the creative:
      1. PBSDK fires the Prebid Server win event.
      2. If a 3rd party rendering SDK is in use, PBSDK calls it for rendering.
      3. Otherwise, it writes the creative into an iframe into an internal WebView, replaceing the GAMSDK’s WebView.
        1. Injects mraid.js into the webview to listen for events from MRAID: change size, etc.
        2. Sends data to the creative (e.g. ‘viewable’) which may trigger impression tracking within the creative.
        3. It does not currently hit the billing or notice urls (burl or nurl).
  5. If a video VastUrl creative is chosen (rewarded video only):
    1. The GMA SDK uses the platform video player which loads the special VAST file from the Prebid CDN.
    2. Prebid SDK watches VAST events for “PrebidAppEvent”. When it sees this, it takes over the rendering:
      1. PBSDK fires the PBS win event.
      2. If the response indicates a 3rd party rendering SDK, PBSDK will call it.
      3. Otherwise:
        1. PDBSK renders with the platform-standard VAST player.
        2. It uses the VAST from the bid response, not from Prebid Cache.
        3. The player fires any Impression tags in the VAST.
        4. PBSDK handles MRAID events.
        5. The app is called to handle the reward.
  6. If an In-App Native format is chosen:
    1. The GMA SDK delegates the rendering of native to the App and PBSDK when a special signal is specified.
    2. The app code gets the native assets from PBSDK. The app is coded to render the ad.
      1. PBSDK fires the eventtrackers when appropriate.
      2. The PBS win event is fired.
  7. Open Measurement events are handled directly by the Prebid SDK.
    1. If a 3rd party rendering SDK is used to render, then it will handle Open Measurement.

Major Integration Steps

Assuming your app already has AdUnits integrated with the GMA SDK, the technical implementation of Prebid mobile into your app will involve these major steps:

  1. Initialize the Prebid SDK - create a connection to your Prebid Server.
  2. Set Global Parameters - let bidders know important data about the page, privacy consent, and other settings.
  3. Work with your Prebid Server team to create the adunit configIds that will be used in the app.
  4. Set up GAM orders, line items, and creatives. See AdOps guidance
  5. Link Prebid AdUnit code to your GMA AdUnits - for any adunits that your business team wants to connect to Prebid with the configIds generated in Step 3. See the adunit-specific instructions below.

Ad Operations Guidance

The AdOps team will need to create line items in GAM. The creatives used depend on which media formats your adunits utilize:

AdUnit Format Line Item Targeting Creative Type Prebid Cache? Ad Ops Details
HTML banner, interstitial banner or video, non-instream video hb_pb
hb_format=banner
3rd party HTML that loads google_mobile_app_ads.js no link
Instream Video hb_pb
hb_format=video
inventoryType in (instream, mobile app)
VastUrl pointing to Prebid Cache yes link
Rewarded Video hb_pb
hb_format=video
inventoryType in (instream, mobile app)
rewarded adunits
VastUrl pointing to prebid-mobile-rewarded-vast.xml no link
In-app native hb_pb
hb_format=native
GAM native no link

Notes:

  • Instream video requires the Bidding-Only application coding integration approach. However, the line item setup is the same.
  • You may need up to 4 sets of line items to support Prebid Mobile depending on adunit types. If you also run Prebid.js or AMP, please see line item considerations for more information.
  • Discuss the Prebid Cache column with the Prebid Server team. They can set up the “top-level stored request” for your account to cache or not cache requests as needed.

Rendering and Tracking

This information may be useful when comparing data across various reporting systems:

Scenario 3pHTML Creative VastUrl Creative GAM Native Creative
Rendering Method js in iframe fires an event GMA SDK player App code with data from PBSDK
Fires Prebid win event always never always
Fires Prebid imp event never VAST impression tag never
Fires OpenRTB burl never n/a never
Fires OpenRTB nurl never n/a never
Fires OpenMeasurement events PBSDK n/a PBSDK

Notes:

  • OpenRTB burl and nurl will be utilized in a future release.

Event Handlers

First, a little bit of setup is needed.

Integrate Event Handlers

Prebid SDK provides rendering integration into the GMA SDK setup with the app events mechanism. To integrate Prebid Event Handlers into your app, add the following line to your Podfile:

pod 'PrebidMobileGAMEventHandlers'

Event Handlers Initialization

Warning: GMA SDK is a closed library that sometimes works in unexpected ways. The GADMobileAds.sharedInstance().start() should be called in all bundles where it is used. Otherwise, GMA SDK won’t load the ads with an error of: adView:didFailToReceiveAdWithError: SDK tried to perform a networking task before being initialized.

To avoid this error add the following line to your app right after initialization of GMA SDK:

GAMUtils.shared.initializeGAM()

AdUnit-Specific instructions

This section covers integration details for different ad formats. In each scenario, you’ll be asked for a configId - this is a key worked out with your Prebid Server provider. It’s used at runtime to pull in the bidders and parameters specific to this adunit. Depending on your Prebid Server partner, it may be a UUID or constructed out of parts like an account number and adunit name.

Banners

Display Banners

Integration example:

// 1. Create an Event Handler
let eventHandler = GAMBannerEventHandler(adUnitID: GAM_AD_UNIT_ID,
                                         validGADAdSizes: [NSValueFromGADAdSize(adSize)])
       
// 2. Create a Banner View
let banner = BannerView(configID: CONFIG_ID,
                        eventHandler: eventHandler)

banner.delegate = self

addBannerToUI(banner: banner)
        
// 3. Load an Ad
banner.loadAd()
Step 1: Create Event Handler

To create the GAMBannerEventHandler you should provide:

  • a GAM Ad Unit Id
  • the list of available sizes for this ad unit.
Step 2: Create Ad View

BannerView - is a view that will display the particular ad. It should be added to the UI. To create a BannerView you should provide:

  • configID - an ID of Stored Impression on the Prebid server
  • eventHandler - the instance of the banner event handler

You should also add the instance of BannerView to the UI.

Step 3: Load the Ad

Call the method loadAd() which will:

  • make a bid request to Prebid Server.
  • render the winning bid on display.

For non-instream Banner Video you also need to specify the ad format:

banner.adFormat = .video

The rest of the code will be the same as for integration of Display Banner.

Migrating banners from a Bidding-Only integration

GAM setup:

  1. Leave the original order and ad units as is. They are not relevant for the rendering approach but they will serve ads for released applications.
  2. Create new GAM ad unit.
  3. Setup new GAM Order for rendering approach.

Integration:

  1. Replace the GAMBannerView with BannerView in the UI.
  2. Implement the protocol BannerViewDelegate in the ViewController.
  3. Remove usage of GAMBannerView, GAMRequest, and implementation of the GADBannerViewDelegate.
  4. Remove original BannerAdUnit.
  5. Follow the instructions to integrate Banner API.

Interstitials

Integration example:

// 1. Create Event Handler
let eventHandler = GAMInterstitialEventHandler(adUnitID: GAM_AD_UNIT_ID)
    
// 2. Create Interstitial Ad Unit
interstitial = InterstitialRenderingAdUnit  (configID: CONFIG_ID,
                                  minSizePercentage: CGSize(width: 30, height: 30),
                                  eventHandler: eventHandler)
    
interstitial.delegate = self
    
// 3. Load an Ad
interstitial.loadAd()

/// .......

// 4. Show Ad
if interstitial.isReady {
    interstitial.show(from: self)
}

The default ad format for interstitial is .banner. In order to make a multiformat bid request, set the respective values in the adFormats property.

// Make bid request for video ad                                     
adUnit?.adFormats = [.video]

// Make bid request for both video amd disply ads                                     
adUnit?.adFormats = [.video, .banner]

// Make bid request for banner ad (default behaviour)                                     
adUnit?.adFormats = [.banner]

Step 1: Create Event Handler

To create an event handler you should provide a GAM Ad Unit.

Step 2: Create Interstitial Ad Unit

Initialize the InterstitialRenderingAdUnit with properties:

  • configID - an ID of Stored Impression on the Prebid server
  • minSizePercentage - specifies the minimum width and height percent an ad may occupy of a device’s real estate.
  • eventHandler - the instance of the interstitial event handler

NOTE: the minSizePercentage - plays an important role in the bidding process for display ads. If provided space is not enough demand partners won’t respond with bids.

Step 3: Load the Ad

Call the method loadAd() which will make a bid request to Prebid Server.

Step 4: Show the Ad when it is ready

Wait for the Prebid Server to return an ad and show it to the user in any suitable time.

// MARK: InterstitialRenderingAdUnitDelegate
    
func interstitialDidReceiveAd(_ interstitial: InterstitialAdUnit) {
    // Now the ad is ready for display
}

Migrating interstitials from a Bidding-Only integration

GAM setup:

  1. Leave the original order and ad units as is. They are not relevant for the rendering approach but they will serve ads for released applications.
  2. Create a new GAM ad unit.
  3. Setup the new GAM Order for rendering approach.

Integration:

  1. Replace the GAMInterstitialAd with InterstitialRenderingAdUnit in the View Controller.
  2. Implement the protocol InterstitialAdUnitDelegate in the View Controller.
  3. Remove usage of GAMInterstitialAd, GAMRequest.
  4. Remove original InterstitialAdUnit.
  5. Follow the instructions to integrate Interstitial API.

Rewarded Video

Integration example:

 // 1. Create an Event Handler
let eventHandler = GAMRewardedEventHandler(adUnitID: GAM_AD_UNIT_ID)
    
// 2. Create an Ad Unit
rewardedAd = RewardedAdUnit(configID: CONFIG_ID,
                               eventHandler: eventHandler)
    
rewardedAd.delegate = self
    
// 3. Load an Ad
rewardedAd.loadAd()

/// .......

// 4. Display Ad
if rewardedAd.isReady {
    rewardedAd.show(from: self)
}

The proccess for displaying the Rewarded Ad is the same as for the Interstitial Ad.

To be notified when a user earns a reward - implement the method of RewardedAdUnitDelegate:

- (void)rewardedAdUserDidEarnReward:(RewardedAdUnit *)rewardedAd;

The reward object is stored in the RewardedAdUnit:

if let reward = rewardedAd.reward as? GADAdReward {
    // ...
}

Step 1: Create Event Handler

To create an event handler you should provide a GAM Ad Unit ID.

Step 2: Create Rewarded Ad Unit

Create the RewardedAdUnit object with parameters:

  • configID - an ID of Stored Impression on the Prebid server
  • eventHandler - the instance of rewarded event handler

Step 3: Load the Ad

Call the loadAd() method which will make a bid request to Prebid server.

Step 4: Show the Ad when it is ready

Wait for the ad to load and display it to the user in any suitable time.

// MARK: RewardedAdUnitDelegate
    
func rewardedAdDidReceiveAd(_ rewardedAd: RewardedAdUnit) {
    // Now the ad is ready for display
}

Migrating Rewarded Video from a Bidding-Only integration

GAM setup:

  1. Leave the original order and ad units as is. They are not relevant for the rendering approach but they will serve ads for released applications.
  2. Create a new GAM ad unit.
  3. Setup the new GAM Order for rendering approach.

Integration:

  1. Replace the GADRewardedAd with RewardedAdUnit in the View Controller.
  2. Implement the protocol RewardedAdUnitDelegate in the View Controller.
  3. Remove usage of GAMRequest.
  4. Remove original RewardedVideoAdUnit.
  5. Follow the instructions to integrate Rewarded API.

Additional Ad Unit Configuration

Each ad unit in the original integration method is a subclass of the AdUnit class, which provides the following properties and methods for the additional configuration.

Autorefresh

setAutoRefreshMillis

If set on a given banner adunit, the fetchDemand function will be called every periodMillis until stopAutoRefresh is called. Each call to fetchDemand will invoke the onComplete function. This refresh only pertains to Prebid Mobile and not to any ad server refresh processes. It is suggested that the adServes refresh be turned off.

stopAutoRefresh

Halts the auto-refresh behavior for a given Prebid Mobile ad unit. If no auto-refresh behavior has been set, stopAutoRefresh will be ignored.

resumeAutoRefresh

Resumes a stopped autorefresh for the ad unit with the previously-defined autorefresh value.

GPID

(requires SDK v2.1.6)

The Global Placement ID (GPID) is a key that uniquely identifies a specific instance of an adunit. Some bidders require this value. An important scenario is “infinite scroll” – if your app creates instances of an adunit dynamically as the user scrolls through content, the the GPID must be different for each by appending some kind of sequence or ID. e.g. “/newsfeed#7”

Using the following method, you can set the impression-level GPID value to the bid request:

adUnit.setGPID("/36117602/hnp-sfgate.com/Homepage/AP300")

Further Reading