iOS GAM Bidding-Only Integration - Native In-App

Back to Bidding-Only Integration

Visit the AdOps guide for instructions on setting up the In-App creatives on GAM.

At a high level, the in-app workflow follows this sequence:

  1. The publisher prepares the ad layout and provides the native ad configuration to the SDK’s ad unit.
  2. Prebid SDK fetches native demand. However, instead of caching the native assets on the server, the assets are cached locally in the SDK.
  3. Ad request are made to Google Ad Manager.
  4. Upon receiving results from Google Ad Manager, the SDK determines if any of the received items are from Prebid Server.
  5. If there are Prebid ads, the cached assets are then rendered.

Integration Example:

private var nativeRequestAssets: [NativeAsset] {
    let image = NativeAssetImage(minimumWidth: 200, minimumHeight: 50, 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)

    return [title, icon, image, sponsored, body, cta]
}

Then integrate the native style ad using GADAdLoader

// 1. Setup NativeRequest
nativeUnit = NativeRequest(configId: storedPrebidImpression, assets: nativeRequestAssets)
nativeUnit.context = ContextType.Social
nativeUnit.placementType = PlacementType.FeedContent
nativeUnit.contextSubType = ContextSubType.Social
nativeUnit.eventtrackers = eventTrackers

// 2. Make a bid request
nativeUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in
    guard let self = self else { return }

    //3. Configure and make a GAM ad request
    self.adLoader = GADAdLoader(adUnitID: gamRenderingNativeAdUnitId,rootViewController: self,
                                adTypes: [GADAdLoaderAdType.customNative], options: [])
    self.adLoader.delegate = self
    self.adLoader.load(self.gamRequest)
}

.....

// Step 4
// MARK: GADCustomNativeAdLoaderDelegate

func customNativeAdFormatIDs(for adLoader: GADAdLoader) -> [String] {
    ["11934135"]
}

func adLoader(_ adLoader: GADAdLoader, didReceive customNativeAd: GADCustomNativeAd) {
    Utils.shared.delegate = self
    Utils.shared.findNative(adObject: customNativeAd)
}

// Step 5
// MARK: - NativeAdDelegate

func nativeAdLoaded(ad: NativeAd) {
    nativeAd = ad
    titleLabel.text = ad.title
    bodyLabel.text = ad.text

    if let iconString = ad.iconUrl {
        ImageHelper.downloadImageAsync(iconString) { result in
            if case let .success(icon) = result {
                DispatchQueue.main.async {
                    self.iconView.image = icon
                }
            }
        }
    }

    if let imageString = ad.imageUrl {
        ImageHelper.downloadImageAsync(imageString) { result in
            if case let .success(image) = result {
                DispatchQueue.main.async {
                    self.mainImageView.image = image
                }
            }
        }
    }

    callToActionButton.setTitle(ad.callToAction, for: .normal)
    sponsoredLabel.text = ad.sponsoredBy

    nativeAd.registerView(view: view, clickableViews: [callToActionButton])
}

func nativeAdNotFound() {
    PrebidDemoLogger.shared.error("Native ad not found")
}

func nativeAdNotValid() {
    PrebidDemoLogger.shared.error("Native ad not valid")
}

Step 1: Create a NativeRequest

Initialize the NativeRequest with properties:

  • configId - an ID of the Stored Impression on the Prebid Server
  • assets - the array of NativeAsset objects which describes your native ad.

Asset Types

NativeAssetImage

Type Scope Description
Main Optional The image that will be displayed in the native ad. Include a value for minimumWidth and minimumHeight. Ensure that the NativeAssetImage.type is set to ImageAsset.Main
Icon Optional The icon that will be displayed with the native ad. Include a value for minimumWidth and minimumHeight. Ensure that the NativeAssetImage.type is set to ImageAsset.Icon.

NativeAssetData

Type Scope Description
Description Optional The content to appear with the ad. Ensure that the type is set to DataAsset.description.
ctatext Optional The text for the call to action button of the native ad. Ensure that the type is set to DataAsset.ctatext.
Sponsored Optional The sponsor (brand) of the native ad. Ensure that the type is set to DataAsset.sponsored.

NativeAssetTitle

Type Scope Description
Title Optional The title of the native ad.

Other Native parameters

Using the NativeParameters object (with the PrebidRequest object) or the NativeRequest object, you can customize the bid request for native ads.

assets

The array of requested asset objects. Prebid SDK supports all kinds of assets according to the IAB spec except video.

eventtrackers

The array of requested native trackers. Prebid SDK supports inly image trackers according to the IAB spec.

version

Version of the Native Markup version in use. The default value is 1.2

context

The context in which the ad appears.

contextSubType

A more detailed context in which the ad appears.

placementType

The design/format/layout of the ad unit being offered.

placementCount

The number of identical placements in this Layout.

sequence

0 for the first ad, 1 for the second ad, and so on.

asseturlsupport

Whether the supply source/impression supports returning an assetsurl instead of an asset object. 0 or the absence of the field indicates no such support.

durlsupport

Whether the supply source / impression supports returning a dco url instead of an asset object. 0 or the absence of the field indicates no such support.

privacy

Set to 1 when the native ad supports buyer-specific privacy notice. Set to 0 (or field absent) when the native ad doesn’t support custom privacy links or if support is unknown.

ext

This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification

Step 2: Make a bid request

The fetchDemand method makes a bid request to the Prebid Server. You should provide a GAMRequest object to this method so Prebid SDK sets the targeting keywords of the winning bid for future ad requests.

Step 3: Configure and make a GAM ad request

Prepare the GADAdLoader and run ad request as described in the GMA SDK docs for the native ads.

If the GAMRequest contains targeting keywords the respective Prebid line item will be returned from GAM and GMA SDK will render its creative.

Be sure that you make the ad request with the same GAMRequest object that you passed to the fetchDemand method. Otherwise the ad request won’t contain targeting keywords and Prebid’s ad won’t ever be displayed.

Step 4: Implement GADCustomNativeAdLoaderDelegate protocol

In order to capture the native ad response you need to implement the GADCustomNativeAdLoaderDelegate protocol.

In the method -adLoader:didReceiveCustomNativeAd: you should pass the following Prebid functions:

Utils.shared.delegate = self
Utils.shared.findNative(adObject: customNativeAd)

Without it the SDK won’t be able to recognize the Prebid line item.

Step 5: Implement NativeAdDelegate

Once the Prebid line item is recognized, the NativeAdDelegate will be activated. The method nativeAdLoaded will be invoked and provide the NativeAd object with a description of all ad assets that should be rendered.

Further Reading