This document describes the Prebid Mobile (PBM) Native In App Rendering capability. Though PBM has the ability to render native ad components through its Banner Ad object, PBM’s Native In App Rendering solution enables publishers to render the native assets in native code.
At a high level the in app rendering process works like this:
1.14.0-beta1 version converting the native ad template to the ad objects is changed to match the IAB specs. See this issue for the details. If you update SDK from the previous version - verify the native ads integration before the release.
These instructions will enable you to create a creative template in either Google Ad Manager or MoPub that can then be applied to native ads in your app.
Delivery and then NativeCreate native ad.Android & iOS app code.ADD VARIABLE and add the following variable names and placeholders.| Variable Name | Place Holder | 
|---|---|
| isPrebid | [%isPrebid%] | 
| hb_cache_id_local | [%hb_cache_id_local%] | 
Make sure to indicate that the variables are required.
Delivery > Creatives, and create a creative with Native Format, choosing the template you created. In the user-defined variables you just created, set the following values:| Variable Name | Value | 
|---|---|
| isPrebid | 1 | 
| hb_cache_id_local | %%PATTERN:hb_cache_id_local%% | 
hb_pb key-values. Associate the creative you added in steps 4 thru 8 (making sure to choose your native format as expected creatives on the line item) to the ad unit you created in the second step.hb_pb key-value.Native.Easy Form choose Manual JSON.
{
"mainimage": "https://dummyimage.com/600x400/000/fff",
"isPrebid": true,
"hb_cache_id_local": "%%KEYWORD:hb_cache_id_local%%"
}
Save.The NativeAdDelegate protocol provides three methods to handle the display and check the validity of the returned native ad.
nativeAdLoaded
Use this method to pass a NativeAd to inflate.
Parameters
| Name | Scope | Type | Description | 
|---|---|---|---|
| NativeAd | Required | ad | A NativeAd | 
nativeAdNotFound
Use this method when a NativeAd is not found in the server returned response. The ad should be displayed as a regular AdUnit type.
nativeAdNotValid
Use this method when a Prebid native ad was returned, but a NativeAd object was not able to be created from the cached assets. Display different content.
An object representing the NativeAd to be displayed.
Setting this option to true, in your instance of Prebid Mobile, enables you to add an id for each asset in the assets array. The default setting is false
Swift
Prebid.shared.shouldAssignNativeAssetID = true
Objective C
[Prebid shared].shouldAssignNativeAssetID = YES;
registerViews
Takes a View that will handle the display of the native asset image and a listener object.
Parameters
| Name | Scope | Type | Description | 
|---|---|---|---|
| view | Required | View | The view to display the native asset image in. | 
unregister
Unregisters the View stored for displaying the native asset’s image.
Use these getters to return various components of the native ad.
| Name | Returns | Description | 
|---|---|---|
| getTitle | String | Returns the title of the native ad. | 
| getDescription | String | Returns the description of the native ad. | 
| getIconUrl | String | Returns the path for the icon of the native ad. | 
| getImageUrl | String | Returns the path for the image of the native ad. | 
| getCallToAction | String | Returns the type of action of the native ad | 
| getClickUrl | String | Returns the click url of the native ad | 
This object provides methods for searching for a PrebidNativeAd in the response and displaying the image from the image url in the response.
findNative
This method searches for the variable isPrebid in the native response. If the variable is located and its value is true the PrebidNativeAd instance is created and passed back to PrebidNativeAdListener.
Parameters
| Name | Scope | Type | Description | ||
|---|---|---|---|---|---|
| adObject | Required | AnyObject | The ad object to search for. | 
How to consume native in iOS:
func createPrebidNativeView(){
    let adNib = UINib(nibName: "PrebidNativeAdView", bundle: Bundle(for: type(of: self)))
    let array = adNib.instantiate(withOwner: self, options: nil)
    if let prebidNativeAdView = array.first as? PrebidNativeAdView{
        self.prebidNativeAdView = prebidNativeAdView
        prebidNativeAdView.frame = CGRect(x: 0, y: 0, width: self.adContainerView.frame.size.width, height: 150 + self.screenWidth * 400 / 600)
        self.view.addSubview(prebidNativeAdView)
    }
}
func loadNativeAssets(){
    let image = NativeAssetImage(minimumWidth: 200, minimumHeight: 200, required: true)
    image.type = ImageAsset.Main
    let icon = NativeAssetImage(minimumWidth: 20, minimumHeight: 20, required: true)
    icon.type = ImageAsset.Icon
    let title = NativeAssetTitle(length: 90, required: true)
    let body = NativeAssetData(type: DataAsset.description, required: true)
    let cta = NativeAssetData(type: DataAsset.ctatext, required: true)
    let sponsored = NativeAssetData(type: DataAsset.sponsored, required: true)
    nativeUnit = NativeRequest(configId: "25e17008-5081-4676-94d5-923ced4359d3", assets: [icon,title,image,body,cta,sponsored])
    nativeUnit.context = ContextType.Social
    nativeUnit.placementType = PlacementType.FeedContent
    nativeUnit.contextSubType = ContextSubType.Social
    let event1 = EventType.Impression
    eventTrackers = NativeEventTracker(event: event1, methods: [EventTracking.Image,EventTracking.js])
    nativeUnit.eventtrackers = [eventTrackers]
}
var adLoader: GADAdLoader?
var nativeUnit: NativeRequest!
var nativeAd:NativeAd?
var nativeUnit: NativeRequest!
var eventTrackers: NativeEventTracker!      
func loadPrebidNativeForDFP(){
    createPrebidNativeView()
    loadNativeAssets()    
    let dfpRequest:DFPRequest = DFPRequest()
    nativeUnit.fetchDemand(adObject: dfpRequest) { [weak self] (resultCode: ResultCode) in
              adLoader = GADAdLoader(adUnitID: "/19968336/Abhas_test_native_native_adunit",
                           rootViewController: self,
                           adTypes: [ GADAdLoaderAdType.dfpBanner, GADAdLoaderAdType.nativeCustomTemplate],
                           options: [ ])
              adLoader?.delegate  = self
              adLoader?.load(dfpRequest)
    }
}
//MARK: : DFP Native Delegate
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: GADRequestError) {
    print("Prebid GADAdLoader failed \(error)")
}
func nativeCustomTemplateIDs(for adLoader: GADAdLoader) -> [String] {
    return ["11963183"]
}
func adLoader(_ adLoader: GADAdLoader,
              didReceive nativeCustomTemplateAd: GADNativeCustomTemplateAd){
    print("Prebid GADAdLoader received customTemplageAd")
    Utils.shared.delegate = self
    Utils.shared.findNative(adObject: nativeCustomTemplateAd)
}
func adLoader(_ adLoader: GADAdLoader, didReceive bannerView: DFPBannerView) {
    prebidNativeAdView?.addSubview(bannerView)
}
func validBannerSizes(for adLoader: GADAdLoader) -> [NSValue] {
    return [NSValueFromGADAdSize(kGADAdSizeBanner)]
}
var mpNative:MPNativeAdRequest?
var mpAd: MPNativeAd?
var nativeUnit: NativeRequest!
var nativeAd:NativeAd?
var nativeUnit: NativeRequest!
var eventTrackers: NativeEventTracker!
func loadPrebidNativeForMoPub(){
    removePreviousAds()
    createPrebidNativeView()
    loadNativeAssets()
    let settings: MPStaticNativeAdRendererSettings = MPStaticNativeAdRendererSettings.init()
    let config:MPNativeAdRendererConfiguration = MPStaticNativeAdRenderer.rendererConfiguration(with: settings)
    self.mpNative = MPNativeAdRequest.init(adUnitIdentifier: "2674981035164b2db5ef4b4546bf3d49", rendererConfigurations: [config])
    let targeting:MPNativeAdRequestTargeting = MPNativeAdRequestTargeting.init()
    self.mpNative?.targeting = targeting
    nativeUnit.fetchDemand(adObject: mpNative!) { [weak self] (resultCode: ResultCode) in
        print("Prebid demand fetch for AdManager \(resultCode.name())")
        if let mpNative = mpNative{
            mpNative.start(completionHandler: { (request, response, error)->Void in
                if error == nil {
                    self.mpAd = response!
                    Utils.shared.delegate = self
                    Utils.shared.findNative(adObject: response!)
                }
            })
       }
    }
}
//MARK: : NativeAdDelegate Delegate
func nativeAdLoaded(ad:NativeAd) {
    print("nativeAdLoaded")
    nativeAd = ad
    nativeAd?.delegate = self
    if  let prebidNativeAdView = prebidNativeAdView {
        nativeAd?.registerView(view: prebidNativeAdView, clickableViews: [prebidNativeAdView.callToActionButton])
    }
    prebidNativeAdView?.titleLabel.text = nativeAd?.title
    prebidNativeAdView?.bodyLabel.text = nativeAd?.text
    if let iconString = nativeAd?.iconUrl, let iconUrl = URL(string: iconString) {
        DispatchQueue.global().async {
            let data = try? Data(contentsOf: iconUrl)
            DispatchQueue.main.async {
                if data != nil {
                    self.prebidNativeAdView?.iconImageView.image = UIImage(data:data!)
                }
            }
        }
    }
    if let imageString = nativeAd?.imageUrl,let imageUrl = URL(string: imageString) {
        DispatchQueue.global().async {
            let data = try? Data(contentsOf: imageUrl)
            DispatchQueue.main.async {
                if data != nil {
                 self.prebidNativeAdView?.mainImageView.image = UIImage(data:data!)
                }
            }
        }
    }
    prebidNativeAdView?.callToActionButton.setTitle(nativeAd?.callToAction, for: .normal)
    prebidNativeAdView?.sponsoredLabel.text = nativeAd?.sponsoredBy
}
func nativeAdNotFound() {
    print("nativeAdNotFound")
}
func nativeAdNotValid() {
    print("nativeAdNotValid")
}