# Native Ads

{% hint style="info" %}
Native ads are only supported starting versions 1.4.x of the RTB SDK
{% endhint %}

### Create RTBNativeAdLoader <a href="#create-rtbnativeadloader" id="create-rtbnativeadloader"></a>

First, create an instance of [`RTBNativeAdLoader`](https://ios-sdk-rtb.gravite.net/references/documentation/rtbsdk/rtbnativeadloader) and set the delegate using an instance conforming to [`RTBNativeAdLoaderDelegate`](https://ios-sdk-rtb.gravite.net/references/documentation/rtbsdk/rtbnativeadloaderdelegate).

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

### Request Ad <a href="#request-a-d" id="request-a-d"></a>

To load an ad, you will need to pass an instance of [`RTBNativeAdRequestConfiguration`](https://ios-sdk-rtb.gravite.net/references/documentation/rtbsdk/rtbnativeadrequestconfiguration) with `placementID` and the `bundleId`. Please get in touch with our [support](mailto:support@gravite.net) to get the needed IDs.&#x20;

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

### Request Ad (from background thread) <a href="#request-a-d" id="request-a-d"></a>

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.

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

### **Optional - set user targeting**

You can pass user targeting data to each request, allowing ads to be more relevant to your audience. Each field in [RTBUserTargeting](https://ios-sdk-rtb.gravite.net/references/documentation/rtbsdk/rtbusertargeting) is optional.

```swift
let configuration = RTBNativeAdRequestConfiguration(placementId: <PLACEMENT_ID>, iTunesAppId: "<ITUNES_APP_ID>")
configuration.userTargeting = .init(userId: "<USER_ID>", gender: .male, yearOfBirth: 1999, keywords: ["keyword1", "keyword2"])
// yearOfBirth must be a 4-digit number, otherwise, it will be ignored
```

### Retrieve Native Ad Assets <a href="#retrieve-native-a-d-assets" id="retrieve-native-a-d-assets"></a>

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

```swift
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 <a href="#optional-use-interactiondelegate" id="optional-use-interactiondelegate"></a>

If you are interested in native ad interaction events like clicks, you can pass optional [`RTBNativeAdInteractionDelegate`](https://ios-sdk-rtb.gravite.net/references/documentation/rtbsdk/rtbnativeadinteractiondelegate) to native ad instance

```
nativeAdData.delegate = self
```

### Track Native Ad <a href="#track-native-a-d" id="track-native-a-d"></a>

To ensure impression reporting and click handling are handled, call `trackImpression` method on [native ad](https://ios-sdk-rtb.gravite.net/references/documentation/rtbsdk/rtbnativead) instance, passing the view used for rendering it.

```swift
nativeAdData.trackImpression(view: containerView)
```

### Complete Code Example <a href="#complete-code-example" id="complete-code-example"></a>

```swift
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()
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aatkit.gitbook.io/rtbsdk-ios-integration/formats/native-ads.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
