---
description: Integrate Infeed Banners
---

# Infeed Banner

Infeed banner placements are designed to serve ads in scrollable feeds (nevertheless, they can also be used in all other scenarios). This includes giving the app complete control over the lifecycle of a specific banner impression. The app can load an ad with a specific configuration and gets notified about the outcome of that specific load request (successful, failure). Hence, the usage of an infeed banner differs from using sticky banners.

### Create Placement

To create an instance of [AATInfeedBannerPlacement](https://ios-sdk.aatkit.com/references/documentation/aatkit/aatinfeedbannerplacement), use the following API:

{% tabs %}
{% tab title="Swift" %}
```swift
let configuration = AATBannerConfiguration()
let placement = AATSDK.createInfeedBannerPlacement(name: "<PLACEMENT_NAME>", configuration: configuration)
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
AATBannerConfiguration *configuration = [[AATBannerConfiguration alloc] init];
id bannerPlacement = [AATSDK createInfeedBannerPlacementWithName:@"<PLACEMENT_NAME>" configuration:configuration];
```
{% endtab %}
{% endtabs %}

#### **AATBannerConfiguration**

[AATBannerConfiguration](https://ios-sdk.aatkit.com/references/documentation/aatkit/aatbannerconfiguration) can be configured with the number of workers and whether manual ad space counting is enabled.

* Manual ad space counting (Please refer to our article about [Ad Spaces](../../advanced/ad-space-and-fill-rate).)
  * `false` (default): infeed banner placement counts an Ad Space every time the app requests an ad from it. Shall only be used, if the app is presenting banners immediately (= not caching them for later use).
  * `true`: the app needs to notify the infeed banner placement about every Ad Space it creates (= placement doesn’t count Ad Spaces itself). This is especially useful if the app implements its own banner caching (e.g. in order to create a smooth user experience for the feed). In this case, the app should notify the placement about an Ad Space only if the feed cell intended for presenting a banner is reaching the visible area of the screen (regardless of whether an ad was available for it or not). If this sounds interesting to you, we strongly advise visiting our chapter about AATKit’s [Banner Cache](banner-cache).
  * To manually count an ad space, call the following `AATInfeedBannerPlacement` API:

{% tabs %}
{% tab title="Swift" %}
```swift
// call it when Infeed Ad is about to be displayed
placement.countAdSpace()
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
// call it when Infeed Ad is about to be displayed
[self.placement countAdSpace];
```
{% endtab %}
{% endtabs %}

* Number of workers
  * Default: 3
  * Defines, how many ads can be loaded in parallel. Higher numbers will result in faster ad delivery but also in more CPU and network traffic consumption

### Listen to Callbacks (Optional)

Through the use of [AATInfeedBannerPlacementDelegate](https://ios-sdk.aatkit.com/references/documentation/aatkit/aatinfeedbannerplacementdelegate), you can listen to the different placement callbacks.

{% tabs %}
{% tab title="Swift" %}
```swift
placement.delegate = self
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
self.placement.delegate = self;
```
{% endtab %}
{% endtabs %}

### Request Ad

The infeed banner placement uses the request completion closure instead of delegate methods like other placements. To request a banner, use the [AATBannerRequest](https://ios-sdk.aatkit.com/references/documentation/aatkit/aatbannerrequest) default initializer that takes an instance implementing [AATBannerRequestDelegate](https://ios-sdk.aatkit.com/references/documentation/aatkit/aatbannerrequestdelegate) as a parameter.

#### **Configure AATBannerRequest**

The banner request can be configured with:

* A set of banner sizes of type [AATBannerSize](https://ios-sdk.aatkit.com/references/documentation/aatkit/aatbannersize).
* Targeting Information.
* Content-targeting URL.
* Multi-content targeting&#x20;

{% tabs %}
{% tab title="Swift" %}
```swift
let request = AATBannerRequest(delegate: self)
request.setRequestBannerSizes(sizes: Set([.banner320x53, .banner300x250]))
request.targetingInformation = ["key": ["value"]]
request.contentTargetingUrl = "http://example.com/similar/content"
OR
request.multiContentTargetingUrls = ["URL1", "URL2"]
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
AATBannerRequest *request = [[AATBannerRequest alloc] initWithDelegate:self];
NSSet *sizes = [[NSSet alloc] initWithArray:@[@(AATBannerSizeBanner320x53), @(AATBannerSizeBanner300x250), @(AATBannerSizeBanner320x100)]];
[request setRequestBannerSizes: sizes];
request.targetingInformation = @{@"Key": @[@"value"]};
request.contentTargetingUrl = @"http://example.com/similar/content";
OR
request.multiContentTargetingUrls = @[@"URL1", @"URL2"];
```
{% endtab %}
{% endtabs %}

#### **Perform Request**

{% hint style="info" %}
You can request multiple `AATBannerRequest` in parallel (i.e. the next one, before the previous one was completed).
{% endhint %}

{% tabs %}
{% tab title="Swift" %}
```swift
let request = AATBannerRequest(delegate: self)
placement?.requestAd(request: request, completion: {[weak self] bannerView, error in
    guard error == nil else {
        // Handle Error
        return
    }
    // Handle banner display
})
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
AATBannerRequest *request = [[AATBannerRequest alloc] initWithDelegate:self];
[self.bannerInContentFeedPlacement requestAdWithRequest:request
                                   completion:^(AATBannerPlacementWrapperView * _Nullable bannerView, AATBannerRequestError * _Nullable error) {
    if (error) {
      // Handle Error
      return;
    }
    // Handle banner display
}];
```
{% endtab %}
{% endtabs %}

### Cancel Request

There might be pending ad requests when the user navigates to a different view controller. To keep the existing lifecycle of the view controller, you need to cancel any pending requests.

{% tabs %}
{% tab title="Swift" %}
```swift
placement.cancel(request: request)
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
[self.placement cancelWithRequest:request];
```
{% endtab %}
{% endtabs %}

### Ad Info

After loading a banner view, you can access the loaded ad information by accessing the `adInfo` property of the loaded banner view:

{% tabs %}
{% tab title="Swift" %}
```swift
bannerPlacement?.requestAd(request: request) { [weak self] bannerView, error in
    guard let self = self else { return }
    if let adView = bannerView {
        let adInfo = adView.adInfo
        // Display the ad view
    }
}
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
AATBannerRequest *request = [[AATBannerRequest alloc] initWithDelegate:self];
[self.bannerInContentFeedPlacement requestAdWithRequest:request
                                   completion:^(AATBannerPlacementWrapperView * _Nullable bannerView, AATBannerRequestError * _Nullable error) {
    if (error) {
      // Handle Error
      return;
    }
    AATAdInfo *info = bannerView.adInfo;
    // Handle banner display
}];
```
{% endtab %}
{% endtabs %}

### Complete Code Example

{% tabs %}
{% tab title="Swift" %}
```swift
class ViewController: UIViewController {
    // Create the placement
    var placement: AATInfeedBannerPlacement?
 
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // [IMPORTANT] Notify AATKit about the currently active view controller
        AATSDK.controllerViewDidAppear(controller: self)
        
        let configuration = AATBannerConfiguration()
        placement = AATSDK.createInfeedBannerPlacement(name: "<PLACEMENT_NAME>", configuration: configuration)
        
        // Set placement delegate to listen to the callbacks
        placement.delegate = self
        
        // Create the banner request instance
        let request = AATBannerRequest(delegate: self)
        // Configure request banner sizes
        request.setRequestBannerSizes(sizes: Set([.banner320x53, .banner300x250]))
        // Configure request targeting information
        request.contentTargetingUrl = "http://example.com/similar/content"
        // OR
        request.multiContentTargetingUrls = ["URL1", "URL2"]
        // Configure request content targeting URL
        request.targetingInformation = ["key": ["value"]]
        // Perform the request
        placement?.requestAd(request: request, completion: {[weak self] bannerView, error in
            guard error == nil else {
                // Handle Error
                return
            }
            let adInfo = adView.adInfo
            // Handle banner display
        })
    }
    
    override func viewWillDisappear(_ animated: Bool) {
	super.viewWillDisappear(animated)
	// [IMPORTANT] Remove the currently active view controller
        AATSDK.controllerViewWillDisappear()
    }
}

// MARK: AATInfeedBannerPlacementDelegate
extension ViewController: AATInfeedBannerPlacementDelegate {
    func aatPauseForAd(placement: AATPlacement) {
        // Ad has been displayed on the screen
    }

    func aatResumeAfterAd(placement: AATPlacement) {
        // Back to the app after clicking on the ad
    }
}

// MARK: AATBannerRequestDelegate
extension ViewController: AATBannerRequestDelegate {
	func shouldUseTargeting(for request: AATBannerRequest, network: AATAdNetwork) -> Bool {
		return true
	}
}
```
{% endtab %}

{% tab title="Objective-C" %}
```objectivec
@interface ViewController () <AATInfeedBannerPlacementDelegate, AATBannerRequestDelegate>
@property id<AATInfeedBannerPlacement> placement;
@end

@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    // [IMPORTANT] Notify AATKit about the currently active view controller
    [AATSDK controllerViewDidAppearWithController:self];
    
    // Create the placement
    AATBannerConfiguration *configuration = [[AATBannerConfiguration alloc] init];
    return [AATSDK createInfeedBannerPlacementWithName:@"<PLACEMENT_NAME>" configuration:configuration];
    
    // Set placement delegate to listen to the callbacks
    self.placement.delegate = self;
    
    // Create the banner request instance
    AATBannerRequest *request = [[AATBannerRequest alloc] initWithDelegate:self];
    // Configure request banner sizes
    NSSet *sizes = [[NSSet alloc] initWithArray:@[@(AATBannerSizeBanner320x53), @(AATBannerSizeBanner300x250), @(AATBannerSizeBanner320x100)]];
    [request setRequestBannerSizes: sizes];
    // Configure request targeting information
    request.targetingInformation = @{@"Key": @[@"value"]};
    // Configure request content targeting URL
    request.contentTargetingUrl = @"http://example.com/similar/content";
    // OR
    request.multiContentTargetingUrls = @[@"URL1", @"URL2"];
    // Perform the request
    [self.placement requestAdWithRequest: request
                    completion:^(AATBannerPlacementWrapperView * _Nullable bannerView, AATBannerRequestError * _Nullable error) {
        if (error) {
            // Handle Error
            return;
        }
        AATAdInfo *info = bannerView.adInfo;
        // Handle banner display
    }];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    // [IMPORTANT] Remove the currently active view controller
    [AATSDK controllerViewWillDisappear];
}

#pragma mark - AATInfeedBannerPlacementDelegate
- (void)aatPauseForAdWithPlacement:(id<AATPlacement> _Nonnull)placement {
    // Ad has been displayed on the screen
}

- (void)aatResumeAfterAdWithPlacement:(id<AATPlacement>)placement {
    // Back to the app after clicking on the ad
}

#pragma mark - AATBannerRequestDelegate
- (BOOL)shouldUseTargetingFor:(AATBannerRequest * _Nonnull)request network:(enum AATAdNetwork)network {
    return YES;
}
@end
```
{% endtab %}
{% endtabs %}
