Native Ads

This guide shows how to integrate native ads of RTBSDK into your app.

Native ads are only supported starting versions 1.4.x of the RTB SDK

Create RTBNativeAdLoader

First, create an instance of RTBNativeAdLoader and set the delegate using an instance conforming to RTBNativeAdLoaderDelegate.

var nativeAdLoader: RTBNativeAdLoader? = RTBNativeAdLoader()
nativeAdLoader?.delegate = self

Request Ad

To load an ad, you will need to pass an instance of RTBNativeAdRequestConfiguration with placementID and the bundleId. Please get in touch with our support to get the needed IDs.

let requestConfiguration = RTBNativeAdRequestConfiguration(placementId: <PLACEMENT_ID>, iTunesAppId: "<ITUNES_APP_ID>")
nativeAdLoader?.load(configuration: requestConfiguration)

Request Ad (from background thread)

You can load a native ad from the background thread. To do so, use the other load API load(configuration: RTBNativeAdRequestConfiguration) passing the userAgent string and request configuration.

let requestConfiguration = RTBNativeAdRequestConfiguration(placementId: <PLACEMENT_ID>, iTunesAppId: "<ITUNES_APP_ID>")
nativeAdLoader?.load(configuration: requestConfiguration, userAgent: "<USER_AGENT>")

Retrieve Native Ad Assets

Once the ad is loaded and the method nativeAdDidReceiveAd is called, you can get the needed native ad assets and assemble your view.

func nativeAdDidReceiveAd(_ nativeAdLoader: RTBSDK.RTBNativeAdLoader, bidInfo: RTBSDK.RTBBidInfo, networkName: String) {
    guard let nativeAdData = nativeAd.getNativeAd() else {
        return
    }
    // Listen to ad interaction events
    nativeAdData.delegate = self
    // [IMPORTANT] Track the ad impression
    nativeAdData.trackImpression(view: containerView)
    // Ad title text
    let title = nativeAdData.title
    // Ad body text
    let body = nativeAdData.body
    // Ad sponsored text
    let sponsered = nativeAdData.sponsered
    // Ad CTA text
    let cta = nativeAdData.callToAction
    // Ad rating value
    let rating = nativeAdData.rating
    // Ad icon
    let iconUrl = nativeAdData.icon
    // Ad main image
    let mainImage = nativeAdData.image
}

(Optional) Use InteractionDelegate

If you are interested in native ad interaction events like clicks, you can pass optional RTBNativeAdInteractionDelegate to native ad instance

nativeAdData.delegate = self

Track Native Ad

To ensure impression reporting and click handling are handled, call trackImpression method on native ad instance, passing the view used for rendering it.

nativeAdData.trackImpression(view: containerView)

Complete Code Example

class ViewController: UIViewController {
    var nativeAdLoader: RTBNativeAdLoader? = RTBNativeAdLoader()
    var nativeAdData: RTBNativeAd?
    @IBOutlet weak var containerView: UIView!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var bodyLabel: UILabel!
    @IBOutlet weak var iconImageView: UIImageView!
    @IBOutlet weak var sponseredLabel: UILabel!
    @IBOutlet weak var ctaLabel: UILabel!
    @IBOutlet weak var mainImageView: UIImageView!
    @IBOutlet weak var ratingLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        nativeAdLoader?.delegate = self
        let requestConfiguration = RTBNativeAdRequestConfiguration(placementId: 1854, iTunesAppId: "449621749")
        nativeAdLoader?.load(configuration: requestConfiguration)
    }
}

extension ViewController: RTBNativeAdLoaderDelegate {
    func nativeAdDidReceiveAd(_ nativeAdLoader: RTBSDK.RTBNativeAdLoader, bidInfo: RTBSDK.RTBBidInfo, networkName: String) {
        // Received a native ad
        nativeAdData = nativeAd.getNativeAd()
        renderNativeAd()
    }
    
    func nativeAdView(_ nativeAd: RTBSDK.RTBNativeAdLoader, didFailToReceiveAd errorMessage: String, networkName: String) {
        // Failed to load a native ad
    }
}

extension ViewController: RTBNativeAdInteractionDelegate {
    func nativeAdView(_ nativeAd: RTBSDK.RTBNativeAd, didFailToRender errorMessage: String, networkName: String) {
        // Failed to render the native ad
    }

    func nativeAdDidRecordClick(_ nativeAd: RTBSDK.RTBNativeAd, networkName: String) {
        // User click is detected
    }

    func nativeAdDidPauseForAd(_ nativeAd: RTBSDK.RTBNativeAd, networkName: String) {
        // App paused after clicking on a native ad
    }

    func nativeAdDidResumeAfterAd(_ nativeAd: RTBSDK.RTBNativeAd, networkName: String) {
        // Back to the app after clicking on the ad
    }
    
    // Should be customised based on your IBOutlets
    func renderNativeAd() {
        guard let nativeAdData = nativeAdData else {
            return
        }
        nativeAdData.delegate = self
        nativeAdData.trackImpression(view: containerView)
        titleLabel.text = nativeAdData.title
        bodyLabel.text = nativeAdData.body
        sponseredLabel.text = nativeAdData.sponsered
        ctaLabel.text = nativeAdData.callToAction
        ratingLabel.text = "\(nativeAdData.rating ?? 0)"

        if let iconUrl = nativeAdData.icon {
            DispatchQueue.global(qos: .background).async {
                self.loadImage(from: iconUrl) { image in
                    self.iconImageView.image = image
                }
            }
        }
        if let mainImageUrl = nativeAdData.image {
            DispatchQueue.global(qos: .background).async {
                self.loadImage(from: mainImageUrl) { image in
                    self.mainImageView.image = image
                }
            }
        }
    }
    
    // A helper method that downloads an image from URL
    func loadImage(from urlString: String, completion: @escaping (UIImage?) -> Void) {
        guard let url = URL(string: urlString) else {
            completion(nil)
            return
        }
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Failed to load image: \(error.localizedDescription)")
                completion(nil)
                return
            }
            guard let data = data, let image = UIImage(data: data) else {
                print("No data or failed to convert data to image")
                completion(nil)
                return
            }
            DispatchQueue.main.async {
                completion(image)
            }
        }

        task.resume()
    }
}

Last updated