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