OpenWrap - InApp Developer Guide: iOS InApp Header Bidding for MoPub

Document created by catherine.racette on Aug 8, 2017Last modified by catherine.racette on Aug 24, 2017
Version 1Show Document
  • View in full screen mode

(Version 1.2.1)

Introduction

In-App Header Bidding allows publishers to allocate ad inventory using a technology and methodology that bypasses inefficiencies that have kept apps from finding the best prices.

 

Header bidding is the process of sending out an initial ad call to one or more buyers to solicit an exact price for inclusion in the ad server’s inventory allocation process. At a high level this is a 3-step process:

  1. The ad call needs to be initiated prior to the page loading.
  2. Buyers get first look at the inventory and submit a pre-bid price.
  3. This pre-bid price then becomes the bid floor for the ad server call, which checks if any other buyers in the same priority tier can beat it. As a result, inventory gets allocated to the highest yielding buyer while respecting other publisher controls that may have been set up in the ad server. 

Header bidding primarily benefits publishers who use third party SDKs (e.g., MoPub) to manage their ads. However, MoPub doesn’t allow publishers to effectively pull in programmatic buyers that compete against Marketplace and direct deals, so publishers are limited as to which buyers they can utilize.

 

When a page in the publisher's app is loaded, the code reaches out to PubMatic for bids before the ad server’s direct sales are called.

 

The diagram below shows how PubMatic OpenWrap - InApp header bidder integrates with publisher’s app.

  • The In-App header bidding arrangement accomplishes several things:
  • All the demand sources are bidding at the same time, which replaces waterfall’s preferential ordering of buyers.
  • Advertisers have a chance at obtaining the best ad inventory.
  • Stats have shown publisher gains as high as 50 percent in CPMs when moved to header bidding setup.

Supported Ad Formats 

  • Simple Banner
  • Rich Media, Interstitial

Prerequisites

Before continuing with the in-app code integration, use the guidelines in the MoPub SDK documentation to get started with MoPub integration for iOS.

 

In-App Code Integration

Use the instructions below to complete the in-app code integration.

  1. Integrating the PubMatic Sample Code in the Publisher’s Application
  2. Creating a Header Bidding Request
  3. Prefetching Bids Using PMPrefetchManager
  4. Handling Prefetched Bids from PMPrefetchManager
  5. Receiving Winning Bids using MoPub’s Custom Event Handler
  6. Getting Rendered Ad from Prefetched Creative
  7. Using HeaderBiddingBannerHelper (Optional)
  8. Setting Refresh Interval (Optional)
  9. App debugging

Integrating the PubMatic Sample Code in the Publisher’s Application

Copy the contents of the Headerbidding folder to the Publisher’s iOS application. Refer to PubMatic's Sample application for faster and easier integration.

Creating a Header Bidding Request

  1. Import PMPrefetchManager file as shown below.
#import "PMPrefetchManager.h" 
  1. Create Impression objects that contain information about specific ad slots like impressionId (Unique identifier), slot name, sizes and slot index. 
    PMBannerImpression *impression = [[PMBannerImpression alloc] initWithImpressionId:<ImpressionId>
    slotName:<slotName> slotIndex:<SlotIndex> sizes:<AdSizes>];

    ImpressionId :
    Used to identify unique ad slot/banner of MoPub screen.This should match with imp_id configured at step 2 in Ad Server Set-Up in the MoPub section below

    SlotName: A string identifier. It should be the same slot name mapped to PubMatic ad tag. Please refer to mapping in an Excel sheet in the PubMatic Setup section below (Internal only).

    SlotIndex:
    Required when the same adunit is used multiple times on the screen. If there are two adunits on the screen, testAdunit (Above the fold) and testAdunit (Below the fold), then slotindex can be used to differentiate between slots with same name.

    AdSizes :
    Different add sizes can be provided for requesting Ad with different sizes
  2. Create a prefetch request object by specifying publisher id and impressions, from step 1, to request prefetched bids. It is required to make an ad request to PubMatic against impression objects.

    Sample code for creating ad request & setting some basic parameters:
    PMBannerPrefetchRequest * prefetchAdRequest = [[PMBannerPrefetchRequest alloc] initForPrefetchWithPublisherId:<PublisherId> impressionArray:<impressions>]; 
        [prefetchAdRequest setAwt:PMAWTSeparateTracker];
        [prefetchAdRequest setKeywords:@"entertainment,sports"];
        [prefetchAdRequest setEthnicity:PMEthnicityAsianAmerican];
        [prefetchAdRequest setDnt:NO];
        [prefetchAdRequest setPaid:NO];
        [prefetchAdRequest setDma:@"734"];
        [prefetchAdRequest setCoppa:YES];
        [prefetchAdRequest setIABCategory:@"IAB1-1,IAB1-7"];

    For additional parameter details, please refer to Table 3 in the PubMatic Prefetch API Parameter Details section below.

     
  3. You can also specify additional targeting information on PMBannerPrefetchRequest object such as store URL, app domain, gender, ethnicity and much more.

 

Prefetching Bids Using PMPrefetchManager

  1. Create PMPrefetchManager object. Please note that PMPrefetchManager instance must be created using sharedInstance method to share prefetched creative in adapter.
PMPrefetchManager *prefetchManager = [PMPrefetchManager sharedInstance]; 
    prefetchManager.delegate = self;

Set a network timeout (In seconds) using maxNetworkTimeout property of PMPrefetchManager. Default, network timeout is 3 seconds

 

  1. Adopt the PMPrefetchDelegate and implement the delegate methods -

    - (void)prefetchManager:didReceiveBids: 
    - (void)prefetchManager:didFailWithError:

     

  2. Call prefetchCreativesForRequest: on PMPrefetchManager object created in step 1.

Handling Prefetched Bids from PMPrefetchManager

  1. Upon success, the PMPrefetchManager will respond with delegate callback - (void)prefetchManager:didReceiveBids: with a map of PMBid objects.

    The keys for this map will be the impression ids. The PMBid object contains impression id, status and price information. 
    Example:
    - (void)prefetchManager:(PMPrefetchManager *)prefetchManager didReceiveBids:(NSDictionary *)bids 
    {
    //get bid for impressionId.
                PMBid *bid = bids[impressionId];
    }

    Call MoPub ad with pre fetched bid information. Please note prefetchManager: didReceiveBids: & prefetchManager:didFailWithError are called on a secondary thread to do UI work from these callbacks dispatch it on main queue.

  2. Set bid details from PMBid object as keywords for MoPub ad.

     NSMutableString * keywords = [NSMutableString new]; 
    [keywords appendFormat:@"%@:%d,",@"bidstatus",bid.status.intValue];
           [keywords appendFormat:@"%@:%0.1f,",@"m_bid",bid.price];
           [keywords appendFormat:@"%@:%@,",@"bidid",bid.impId];

         if (bid.dealId) {
                    [keywords appendFormat:@ "%@:%@",@"wdeal",bid.dealId];
                }
    banner.keywords = [NSString stringWithString:keywords];
    (banner is an MPAdView object)

    Note: dealId is used for PMP deals. and bid price is rounded till single decimal digit

  3. Call loadAd: on MPAdView

    dispatch_async(dispatch_get_main_queue(), ^{ 

    [banner loadAd];
    });

    banner: Instance of MPAdView

     

Receiving Winning Bids using MoPub's Custom Event Handler

The publisher must implement a custom event handler subclassing MoPub’s MPBannerCustomEvent.

 

For every winning bid, this event handler will receive event

- (void)requestAdWithSize:(CGSize)size customEventInfo:(NSString *)info 

 

...where, info dictionary contains the impressionId for which the header bid has won.

Getting Rendered Ad from Prefetched Creative

Call renderedViewForImpressionId:adSize: method on PMPrefetchManager passing the impressionId and size received in the previous step. In case of success, this method will return a rendered creative in a webView & fire impression trackers.

 

NSString *key = [info objectForKey:@”imp_id”]; 
UIWebView *webview = [self.prefetchManager renderedViewForImpressionId:key adSize:size];


Call bannerCustomEvent:didLoadAd: on the custom event class delegate if a valid ad is returned (i.e. webview is not nil)

 

if (webview) { 
        [self.delegate bannerCustomEvent:self didLoadAd:webview];
    }else{
        
        MPLogInfo(@"Failed to render prefetched Ad creative");
        [self.delegate bannerCustomEvent:self didFailToLoadAdWithError:nil];
    }


Using HeaderBiddingBannerHelper (Optional)

The MoPubHeaderBiddingBannerHelper class will be a part of Publisher's app. This class can be used as a convenient way to integrate PubMatic's header bidding solution with MoPub.

 

Customize this class to integrate any other header bidding partner in addition to PubMatic.

  1. Create a AdSlotInfo object for each ad slot by providing slot name , list of ad sizes and MPAdView.
    AdSlotInfo * adSlot = [[AdSlotInfo alloc] initWithBannerView:self.mopubAdView slotName:<SlotName> sizes:<AdSizes>]; 

 

  1. Create a list of AdSlotInfo objects
  2. Create an object of MoPubHeaderBiddingBannerHelper with the ad slot list created in step 2 and call execute.
    MoPubHeaderBiddingBannerHelper *helper = [[MoPubHeaderBiddingBannerHelper alloc] initWithAdSlotInfo:<adSlotInfoArray> publisherId:<pubId> controller:<conroller>]; 
    [self.helper execute];

Setting Refresh Interval (Optional)

This solution provides an optional feature to auto refresh the banner ad after a specified interval.

 

The default value for refresh interval is 0 seconds, i.e., by default auto refresh feature is disabled. The publisher can set an appropriate refresh interval using the refreshInterval property of PMPrefetchManager. Expected value should be in range of 12 to 120.

Table 1. Ad refresh behavior on setting refresh interval value:

Value (X) in secondsSDK Behavior
X<=0Ad will not refresh
X > 0 & X <= 12Ad will get refreshed after every 12 seconds.
X > 12 & X <=120Ad will get refreshed after every X seconds
X > 120Ad will get refreshed after every 120 seconds

 

Note: To use this feature, please disable the ad server’s refresh functionality. Please refer to the MoPub portal documentation for additional information.

App Debugging

Header bidding code logs the request & response from the PubMatic server in debug mode. This debug log can help to see if PubMatic is providing proper bids or not. Below is sample logs from Header bidding sample application.

PubMatic Prefetch API Parameter Details

Please refer the following properties for sending the targeting parameter values.

Table 2. PMBannerPrefetchRequest properties

 

S. noMethodDescription
1storeURLURL of the app store from where a user can download this application. This URL must match the storeurl that is whitelisted in the UI.
2appDomainIndicates the domain of the mobile application.
3paid

Indicates whether the mobile application is a paid version or not. Possible values are:

  • false - Free version
  • true - Paid version
4awt

Indicates whether the tracking URL has been wrapped or not in the creative tag.

Possible options are:

  • PMAWTSeparateTracker - Indicates that the tracking URL is sent separately in the response JSON as tracking_url. In this case, the tracking_url field is absent in the JSON response.
  • PMAWTiframeEmbeddedTracker - Indicates that the tracking_url value is wrapped in an Iframe and appended to the creative_tag.
  • PMAWTJSEmbeddedTracker - Indicates that the tracking_url value is wrapped in a JS tag and appended to the creative_tag.
5pmZoneIdThis parameter is used to pass a zone ID for reporting.
6ethnicityNumeric code of ethnicity.
7userIncomeUser's income or income range in dollars (whole numbers). For example, inc=50000 or 50000-75000. 
8birthYearVisitor's birth year as a four-digit integer. For example, 1975.
9genderGender of the visitor. Possible values are:
  • PMGenderMale - Male
  • PMGenderFemale - Female
  • PMGenderOther - Others
  • PMGenderUnknown - Unknown
10cityCity of the user. For example, city=New York
11zipHome zip code if the visitor is present in the U.S.; otherwise it indicates the postal code. 
12coppa

Indicates whether the visitor is COPPA-specific or not. For COPPA (Children's Online Privacy Protection Act) compliance, if the visitor's age is below 13, then such visitors should not be served targeted ads.

 

Possible options are:

  • false - Indicates that the visitor is not COPPA-specific and can be served targeted ads.
  • true - Indicates that the visitor is COPPA-specific and should be served only COPPA-compliant ads.

 

The United States Federal Trade Commission has written a comprehensive FAQ on complying with COPPA at http://business.ftc.gov/documents/Complying-with-COPPA-Frequently-Asked-Questions.

13appCategoryApplication primary category as displayed on storeurl page for the respective platform.  
14keywordsList of keywords indicating the consumer's interests or intent. 
15latitudeLatitude of the device location.
16longitudeLongitude of the device location.
17dntIf set, it restricts user and device targeting. 
This can also be set by enabling the “Limit Ad Tracking” option in the iOS device.
18isIDFAEnabled

If set, it uses advertisement id otherwise it uses vendor id for targeting.

 

This has effect only if 'dnt' is set to NO.

19udidHashTypeAllows to apply following hashing on udid param value before sending to server 
  •  PMUdidhashTypeUnknown=0,
  • PMUdidhashTypeRaw=1,
  • PMUdidhashTypeSHA1=2,
  • PMUdidhashTypeMD5=3

Default is PMUdidhashTypeRaw

20IABCategory

List of IAB content categories for the overall site/application. Refer the "Table 6.1 Content Categories" in the Open RTB 2.1 / 2.2 specifications document. If the site/application falls under multiple IAB categories, you can send categories separated by comma.

Note: For more details about these parameters, please refer to HTTP Parameters Details (SSP Ad Server) 

    

PubMatic: See PubMatic Setup - Internal to PubMatic for details on Admin UI set up.

Attachments

    Outcomes