> For the complete documentation index, see [llms.txt](https://aatkit.gitbook.io/rtbsdk-ios-integration/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://aatkit.gitbook.io/rtbsdk-ios-integration/formats/advanced/separate-loading-and-rendering-of-banner-ads.md).

# Separate Loading and Rendering of Banner Ads

The [`RTBBannerAdProvider`](https://docs.gravite.net/rtbsdk/ios/docs/documentation/rtbsdk/rtbbanneradprovider) offers the app full control over the lifecycle of individual banner ad impressions. It allows the app to load a banner ad independently, with the option to render it at a later time. By loading an ad with a specific configuration, the app receives notifications about the result of that load request through the [`RTBBannerAdLoadDelegate`](https://docs.gravite.net/rtbsdk/ios/docs/documentation/rtbsdk/rtbbanneradloaddelegate). As a result, the `RTBBannerAdProvider` is used differently from the `RTBBannerView.`

### Request Ad

To load a banner ad, you will need to pass an instance of [RTBBannerRequestConfiguration](https://docs.gravite.net/rtbsdk/ios/docs/documentation/rtbsdk/rtbbannerrequestconfiguration) with `placementID` and the `bundleId`. Please contact our [support](mailto:support@gravite.net) to get the needed IDs.

```swift
let configuration = RTBBannerRequestConfiguration(placementId: <PLACEMENT_ID>, iTunesAppId: <ITUNES_APP_ID>)
configuration.sellerId = "<SELLERID>" // Optional
configuration.bidFloor = <BID_FLOOR>  // Optional (in USD)
RTBBannerAdProvider.load(configuration: configuration, size: .banner320x50, userAgent: "<USER_AGENT>", loadDelegate: self)
```

You will be notified about the loading success or failure through the [RTBBannerAdLoadDelegate](https://docs.gravite.net/rtbsdk/ios/docs/documentation/rtbsdk/rtbbanneradloaddelegate) instance passed as `loadDelegate`. If the ad loads successfully, you will obtain `RTBBannerBid` instance that can later be used to obtain the banner view.

### **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://docs.gravite.net/rtbsdk/ios/docs/documentation/rtbsdk/rtbusertargeting) is optional.

```swift
let configuration = RTBBannerRequestConfiguration(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
```

### Get Loaded Banner View

Once the banner is loaded and the method `bannerAdDidReceiveAd(bannerBid: RTBBannerBid)` is called, you can get the loaded banner view by calling the `RTBBannerAdProvider.getBannerView(bannerBid: bannerBid, delegate: self)` method passing the received [`RTBBannerBid`](https://docs.gravite.net/rtbsdk/ios/docs/documentation/rtbsdk/rtbbannerbid) instance. You can also pass optional [`RTBBannerAdInteractionDelegate`](https://docs.gravite.net/rtbsdk/ios/docs/documentation/rtbsdk/rtbbanneradinteractiondelegate) that will be notified about banner events like clicks.

```swift
func bannerAdDidReceiveAd(bannerBid: RTBSDK.RTBBannerBid) {
    DispatchQueue.main.async {
        guard let bannerView = RTBBannerAdProvider.getBannerView(bannerBid: bannerBid, delegate: self) else {
            return
        }
        let price = bannerBid.priceCPM // in USD
        let bidder = bannerBid.bidder
        // Adjust and display the banner view
    }
}
```

> The currency of `bidFloor` and `priceCPM` parameters is USD.

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

```swift
import RTBSDK

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // Prepare request configurations
        let configuration = RTBBannerRequestConfiguration(placementId: <PLACEMENT_ID>, iTunesAppId: <ITUNES_APP_ID>)
        configuration.sellerId = "<SELLERID>" // Optional
        configuration.bidFloor = <BID_FLOOR>  // Optional

        // Request a banner ad
        RTBBannerAdProvider.load(configuration: configuration, size: .banner320x50, userAgent: "<USER_AGENT>", loadDelegate: self)
    }
}

extension ViewController: RTBBannerAdLoadDelegate {
    func bannerAdDidReceiveAd(bidInfo: RTBBidInfo, networkName: String) {
        // A banner ad has been loaded
        guard let bannerView = RTBBannerAdProvider.getBannerView(bannerBid: bannerBid, delegate: self) else {
            return
        }
        // Display the banner view
    }
}

extension ViewController: RTBBannerAdInteractionDelegate {
    func bannerAdDidRecordClick() {
        // The banner received a click
    }

    func bannerAdDidPauseForAd() {
        // The app paused after the user clicked on the ad and opened Safari app
    }

    func bannerAdDidResumeAfterAd() {
        // The app resumed after returning from Safari as a result of user click
    }

    func bannerAdDidFailToRender(error: String) {
       // Failed to render e banner ad
    }
}

```
