> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adrop.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Native Ads

> Guide to implementing native ads in iOS.

## Overview

Native ads are ad formats that naturally integrate with your app's UI. You can freely customize ad elements (title, image, description, etc.) to match your app design.

### Key Features

* Custom design that perfectly integrates with app UI
* Individual access and placement of ad elements
* Option to display advertiser profile information
* Support for additional custom fields

***

## Implementation Steps

Native ad implementation proceeds in the following steps:

1. Load ad
2. Create custom view
3. Bind view
4. Handle delegates

***

## 1. Load Ad

Create an `AdropNativeAd` instance and load the ad.

<CodeGroup>
  ```swift Swift theme={null}
  import AdropAds

  class MyViewController: UIViewController {
      private var nativeAd: AdropNativeAd?

      override func viewDidLoad() {
          super.viewDidLoad()

          // Create native ad
          nativeAd = AdropNativeAd(unitId: "YOUR_NATIVE_UNIT_ID")
          nativeAd?.delegate = self

          // Load ad
          nativeAd?.load()
      }
  }
  ```

  ```objc Objective-C theme={null}
  @import AdropAds;

  @interface MyViewController () <AdropNativeAdDelegate>
  @property (nonatomic, strong) AdropNativeAd *nativeAd;
  @end

  @implementation MyViewController

  - (void)viewDidLoad {
      [super viewDidLoad];

      // Create native ad
      self.nativeAd = [[AdropNativeAd alloc] initWithUnitId:@"YOUR_NATIVE_UNIT_ID"];
      self.nativeAd.delegate = self;

      // Load ad
      [self.nativeAd load];
  }

  @end
  ```
</CodeGroup>

### Set Context ID

You can set a Context ID for [contextual targeting](/sdk/ios/targeting#contextual-targeting).

<CodeGroup>
  ```swift Swift theme={null}
  // contextId is read-only — set via initializer
  let nativeAd = AdropNativeAd(unitId: "YOUR_UNIT_ID", contextId: "article_123")
  ```

  ```objc Objective-C theme={null}
  // contextId is read-only — set via initializer
  AdropNativeAd *nativeAd = [[AdropNativeAd alloc] initWithUnitId:@"YOUR_UNIT_ID" contextId:@"article_123"];
  ```
</CodeGroup>

<Note>
  Use test unit IDs during development. See the [Test Unit IDs](#test-unit-ids) section.
</Note>

***

## 2. Create Custom View

Compose your native ad view using Storyboard or code.

### UIKit (Storyboard/XIB)

Create `AdropNativeAdView` in Storyboard and connect ad elements as IBOutlets.

```swift theme={null}
import AdropAds

class NativeAdViewCell: UITableViewCell {
    @IBOutlet weak var nativeAdView: AdropNativeAdView!
    @IBOutlet weak var iconImageView: UIImageView!
    @IBOutlet weak var headlineLabel: UILabel!
    @IBOutlet weak var bodyLabel: UILabel!
    @IBOutlet weak var mediaView: UIView!
    @IBOutlet weak var callToActionButton: UIButton!

    // Advertiser profile (optional)
    @IBOutlet weak var advertiserLogoImageView: UIImageView!
    @IBOutlet weak var advertiserNameLabel: UILabel!

    func configure(with ad: AdropNativeAd) {
        // View binding (see next section)
    }
}
```

### UIKit (Code)

```swift theme={null}
import AdropAds

class NativeAdView: UIView {
    let nativeAdView = AdropNativeAdView()
    let iconImageView = UIImageView()
    let headlineLabel = UILabel()
    let bodyLabel = UILabel()
    let mediaView = UIView()
    let callToActionButton = UIButton()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    private func setupViews() {
        addSubview(nativeAdView)
        nativeAdView.addSubview(iconImageView)
        nativeAdView.addSubview(headlineLabel)
        nativeAdView.addSubview(bodyLabel)
        nativeAdView.addSubview(mediaView)
        nativeAdView.addSubview(callToActionButton)

        // Auto Layout setup
        // ...
    }
}
```

***

## 3. Bind View

Bind ad elements to `AdropNativeAdView` to display ad data.

```swift theme={null}
func configure(with ad: AdropNativeAd) {
    // Bind each element to AdropNativeAdView
    nativeAdView.setIconView(iconImageView)
    nativeAdView.setHeadLineView(headlineLabel)
    nativeAdView.setBodyView(bodyLabel)
    nativeAdView.setMediaView(mediaView)
    nativeAdView.setCallToActionView(callToActionButton)

    // Advertiser profile (optional)
    if let advertiserLogoView = advertiserLogoImageView,
       let advertiserNameView = advertiserNameLabel {
        nativeAdView.setProfileLogoView(advertiserLogoView)
        nativeAdView.setProfileNameView(advertiserNameView)
    }

    // Set ad data (automatically displayed in bound views)
    nativeAdView.setNativeAd(ad)
}
```

### Binding Methods

| Method                            | Description                                                                                                                                                                                                          | Required |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `setIconView(_:onClick:)`         | Set icon image view. `onClick: ((AdropNativeAd?, UIView) -> Void)? = nil`                                                                                                                                            | Optional |
| `setHeadLineView(_:onClick:)`     | Set title label. `onClick: ((AdropNativeAd?, UIView) -> Void)? = nil`                                                                                                                                                | Optional |
| `setBodyView(_:)`                 | Set description label                                                                                                                                                                                                | Optional |
| `setMediaView(_:)`                | Set main image/video view. **Required for video creatives** — VTR and `onAdVideoStart` / `onAdVideoEnd` only fire when the SDK's media surface is bound here. See [Video Tracking and VTR](#video-tracking-and-vtr). | Optional |
| `setCallToActionView(_:onClick:)` | Set CTA button. `onClick: ((AdropNativeAd?, UIView) -> Void)? = nil`                                                                                                                                                 | Optional |
| `setAdvertiserView(_:onClick:)`   | Set advertiser view. `onClick: ((AdropNativeAd?, UIView) -> Void)? = nil`                                                                                                                                            | Optional |
| `setProfileLogoView(_:onClick:)`  | Set advertiser logo image view. `onClick: ((AdropNativeAd?, UIView) -> Void)? = nil`                                                                                                                                 | Optional |
| `setProfileNameView(_:onClick:)`  | Set advertiser name label. `onClick: ((AdropNativeAd?, UIView) -> Void)? = nil`                                                                                                                                      | Optional |
| `setNativeAd(_:)`                 | Set ad data                                                                                                                                                                                                          | Required |

<Note>
  The `onClick` closure is called when the user taps the bound view. It receives the current `AdropNativeAd?` instance and the tapped `UIView` as parameters. If not provided, the default click behavior (opening the destination URL) is used.
</Note>

<Note>
  To display advertiser profile, you must enable <strong>Show Advertiser Profile</strong> for the ad unit in Ad Control Console.
</Note>

***

## 4. Handle Delegates

Implement `AdropNativeAdDelegate` to handle ad events.

<CodeGroup>
  ```swift Swift theme={null}
  extension MyViewController: AdropNativeAdDelegate {
      // Ad received successfully
      func onAdReceived(_ nativeAd: AdropNativeAd) {
          print("Native ad received successfully")

          // Access ad data (properties are non-optional)
          print("Title: \(nativeAd.headline)")
          print("Description: \(nativeAd.body)")
          print("CTA: \(nativeAd.callToAction)")

          // Bind ad to view
          configureNativeAdView(with: nativeAd)
      }

      // Ad receive failed
      func onAdFailedToReceive(_ nativeAd: AdropNativeAd, _ errorCode: AdropErrorCode) {
          print("Native ad failed to receive: \(errorCode)")
      }

      // Ad clicked (optional)
      func onAdClicked(_ nativeAd: AdropNativeAd) {
          print("Native ad clicked")
      }

      // Ad impression (optional)
      func onAdImpression(_ nativeAd: AdropNativeAd) {
          print("Native ad impression")
      }
  }
  ```

  ```objc Objective-C theme={null}
  #pragma mark - AdropNativeAdDelegate

  // Ad received successfully
  - (void)onAdReceived:(AdropNativeAd *)nativeAd {
      NSLog(@"Native ad received successfully");

      // Access ad data
      if (nativeAd.headline) {
          NSLog(@"Title: %@", nativeAd.headline);
      }

      if (nativeAd.body) {
          NSLog(@"Description: %@", nativeAd.body);
      }

      if (nativeAd.callToAction) {
          NSLog(@"CTA: %@", nativeAd.callToAction);
      }

      // Bind ad to view
      [self configureNativeAdViewWith:nativeAd];
  }

  // Ad receive failed
  - (void)onAdFailedToReceive:(AdropNativeAd *)nativeAd :(AdropErrorCode)errorCode {
      NSLog(@"Native ad failed to receive: %ld", (long)errorCode);
  }

  // Ad clicked (optional)
  - (void)onAdClicked:(AdropNativeAd *)nativeAd {
      NSLog(@"Native ad clicked");
  }

  // Ad impression (optional)
  - (void)onAdImpression:(AdropNativeAd *)nativeAd {
      NSLog(@"Native ad impression");
  }
  ```
</CodeGroup>

### Delegate Methods

| Method                      | Required | Description                             |
| --------------------------- | -------- | --------------------------------------- |
| `onAdReceived(_:)`          | Required | Called when ad loads successfully       |
| `onAdFailedToReceive(_:_:)` | Required | Called when ad fails to load            |
| `onAdClicked(_:)`           | Optional | Called when user clicks the ad          |
| `onAdImpression(_:)`        | Optional | Called when ad is displayed             |
| `onAdVideoStart(_:)`        | Optional | Called when a video ad starts playing   |
| `onAdVideoEnd(_:)`          | Optional | Called when a video ad finishes playing |

***

## Closure Callbacks

As an alternative to delegates, you can use closure-based callbacks.

```swift theme={null}
let nativeAd = AdropNativeAd(unitId: "YOUR_UNIT_ID")

nativeAd.onAdReceived = { ad in
    print("Native ad received")
}

nativeAd.onAdFailedToReceive = { ad, errorCode in
    print("Native ad failed: \(errorCode)")
}

nativeAd.onAdImpression = { ad in
    print("Native ad impression")
}

nativeAd.onAdClicked = { ad in
    print("Native ad clicked")
}

nativeAd.onAdVideoStart = { ad in
    print("Native ad video started")
}

nativeAd.onAdVideoEnd = { ad in
    print("Native ad video ended")
}
```

<Note>
  If both a delegate and closures are set, both will be called.
</Note>

***

## Ad Properties

You can access ad data through the `AdropNativeAd` object.

### Basic Properties

```swift theme={null}
// When ad is received successfully
func onAdReceived(_ nativeAd: AdropNativeAd) {
    // Title
    print("Title: \(nativeAd.headline)")

    // Description
    print("Description: \(nativeAd.body)")

    // CTA button text
    print("CTA: \(nativeAd.callToAction)")

    // Main image/video
    print("Media URL: \(nativeAd.asset)")
}
```

### Advertiser Profile

```swift theme={null}
// Advertiser information (profile and its properties are non-optional)
let profile = nativeAd.profile
print("Advertiser logo: \(profile.displayLogo)")
print("Advertiser name: \(profile.displayName)")

// Profile link (optional — links to the advertiser's page)
if let link = profile.link {
    print("Profile link: \(link)")
}
```

### Custom Fields

You can access additional text items set in Ad Control Console.

```swift theme={null}
// Additional text items (extra is non-optional [String: String])
let extra = nativeAd.extra
if !extra.isEmpty {
    // Example: Price information
    if let price = extra["price"] {
        print("Price: \(price)")
    }

    // Example: Discount rate
    if let discount = extra["discount"] {
        print("Discount: \(discount)")
    }

    // Example: Rating
    if let rating = extra["rating"] {
        print("Rating: \(rating)")
    }
}
```

<Note>
  The `extra` field uses additional text item IDs defined in the ad unit settings in Ad Control Console as keys.
</Note>

### Property List

| Property         | Type                   | Description                         |
| ---------------- | ---------------------- | ----------------------------------- |
| `unitId`         | `String`               | Ad unit ID                          |
| `contextId`      | `String`               | Context ID for contextual targeting |
| `headline`       | `String`               | Ad title                            |
| `body`           | `String`               | Ad description                      |
| `callToAction`   | `String`               | CTA button text                     |
| `icon`           | `String`               | Icon image URL                      |
| `cover`          | `String`               | Cover image URL                     |
| `asset`          | `String`               | Main image/video URL                |
| `creative`       | `String`               | Creative HTML content               |
| `creativeSize`   | `CGSize`               | Creative content size               |
| `advertiser`     | `String`               | Advertiser name                     |
| `advertiserURL`  | `String`               | Advertiser URL                      |
| `profile`        | `AdropNativeAdProfile` | Advertiser profile information      |
| `extra`          | `[String: String]`     | Additional custom fields            |
| `accountTag`     | `[String: Any]`        | Account-level tag data              |
| `creativeTag`    | `[String: Any]`        | Creative-level tag data             |
| `destinationURL` | `String?`              | Ad destination URL                  |
| `txId`           | `String`               | Transaction ID                      |
| `campaignId`     | `String`               | Campaign ID                         |
| `creativeId`     | `String`               | Creative ID                         |
| `browserTarget`  | `BrowserTarget?`       | How to open URLs on ad click        |
| `isLoaded`       | `Bool`                 | Whether ad is loaded                |
| `isBackfilled`   | `Bool`                 | Whether ad is a backfill ad         |

### AdropNativeAdProfile

| Property      | Type      | Description                   |
| ------------- | --------- | ----------------------------- |
| `displayLogo` | `String`  | Advertiser logo image URL     |
| `displayName` | `String`  | Advertiser display name       |
| `link`        | `String?` | Link to the advertiser's page |

***

## Custom Click

You can use Custom Click to handle ad click behavior yourself instead of using the default behavior (opening the destination URL).

### Setup

<CodeGroup>
  ```swift Swift theme={null}
  let nativeAd = AdropNativeAd(unitId: "YOUR_UNIT_ID")
  nativeAd.useCustomClick = true
  ```

  ```objc Objective-C theme={null}
  AdropNativeAd *nativeAd = [[AdropNativeAd alloc] initWithUnitId:@"YOUR_UNIT_ID"];
  nativeAd.useCustomClick = YES;
  ```
</CodeGroup>

### Entire Click Area

Use `setIsEntireClick(_:)` to make the entire `AdropNativeAdView` clickable.

```swift theme={null}
nativeAdView.setIsEntireClick(true)
```

<Note>
  When `useCustomClick` is `true`, `setIsEntireClick(true)` is automatically called in `setNativeAd(_:)`.
</Note>

### Manual Click

Use `performClick()` to manually trigger a click event.

```swift theme={null}
nativeAdView.performClick()
```

### Open URL

Use `open(_:useInAppBrowser:)` to open a URL programmatically.

```swift theme={null}
// Open destination URL
nativeAd.open(nativeAd.destinationURL)

// Open in in-app browser
nativeAd.open(nativeAd.destinationURL, useInAppBrowser: true)
```

***

## Video Tracking and VTR

Adrop measures video metrics for native creatives — including impression-to-completion (VTR), `onAdVideoStart`, and `onAdVideoEnd` — only when the video is rendered through the SDK's media surface (a `UIView` bound via `AdropNativeAdView.setMediaView(_:)`).

The `AdropNativeAd.asset` property returns a URL pointing to the underlying image or video file. It is exposed as supplementary metadata (for example, for thumbnails or your own analytics); it is **not** intended to drive playback.

<Warning>
  Do not feed the `asset` URL into a custom video player (`AVPlayer`, `AVPlayerViewController`, or any third-party player) for a video native ad. When the SDK's media surface is bypassed:

  * **VTR (Video Through Rate) is not collected** for that placement.
  * `onAdVideoStart` / `onAdVideoEnd` callbacks **never fire**.
  * Aggregate video performance for the unit will under-report or report zero.

  Click (`onAdClicked`) and impression (`onAdImpression`) tracking still work because they are wired to the container view, but the video-specific signals are lost.
</Warning>

### Recommended pattern

Bind the SDK media surface for every video native:

<CodeGroup>
  ```swift Swift theme={null}
  nativeAdView.setMediaView(mediaView)    // Required for video tracking
  nativeAdView.setNativeAd(ad)
  ```

  ```objc Objective-C theme={null}
  [self.nativeAdView setMediaView:self.mediaView];    // Required for video tracking
  [self.nativeAdView setNativeAd:ad];
  ```
</CodeGroup>

<Note>
  If a placement absolutely requires a custom player and you accept that VTR will not be measured, you can still surface click and impression attribution by keeping the ad bound to `AdropNativeAdView`. In that case, treat the placement as **non-VTR inventory** in your internal reporting and avoid mixing it with SDK-measured video performance.
</Note>

***

## Best Practices

### Error Handling

Display fallback UI when ad fails to load to maintain user experience.

```swift theme={null}
func onAdFailedToReceive(_ nativeAd: AdropNativeAd, _ errorCode: AdropErrorCode) {
    print("Native ad failed to receive: \(errorCode)")

    // Hide ad area
    nativeAdContainerView.isHidden = true

    // Or display fallback content
    showFallbackContent()
}
```

***

## Test Unit IDs

Use the following test unit IDs during development and testing.

| Ad Type             | Test Unit ID                            |
| ------------------- | --------------------------------------- |
| Native (Image)      | `PUBLIC_TEST_UNIT_ID_NATIVE`            |
| Native Video (16:9) | `PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_16_9` |
| Native Video (9:16) | `PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_9_16` |

```swift theme={null}
// Load test ad
nativeAd = AdropNativeAd(unitId: AdropUnitId.PUBLIC_TEST_UNIT_ID_NATIVE)
```

<Warning>
  Make sure to use actual unit IDs created in Ad Control Console for production deployment.
</Warning>

***

## Batch Loading (loads)

Use `AdropNativeAd.loads(...)` to request multiple native ads in a single batched call. This is useful for prefetching a pool of ads to insert into feeds, carousels, or paginated lists.

### Signature

<CodeGroup>
  ```swift Swift theme={null}
  AdropNativeAd.loads(
      unitId: String,
      contextId: String = "",
      delegate: AdropNativeAdDelegate
  )
  ```

  ```objc Objective-C theme={null}
  [AdropNativeAd loadsWithUnitId:@"YOUR_UNIT_ID"
                       contextId:@""
                        delegate:delegate];
  ```
</CodeGroup>

### Usage

<CodeGroup>
  ```swift Swift theme={null}
  class ViewController: UIViewController {
      private var ads: [AdropNativeAd] = []

      override func viewDidLoad() {
          super.viewDidLoad()
          AdropNativeAd.loads(unitId: "YOUR_UNIT_ID", delegate: self)
      }
  }

  extension ViewController: AdropNativeAdDelegate {
      // Required single-load callbacks — unused on the batch path.
      func onAdReceived(_ ad: AdropNativeAd) { /* batch path */ }
      func onAdFailedToReceive(_ ad: AdropNativeAd, _ errorCode: AdropErrorCode) {}

      // Batch success — each ad is fully rendered and ready to bind.
      func onAdsReceived(_ ads: [AdropNativeAd]) {
          self.ads = ads
          ads.forEach { ad in
              bind(ad)  // Bind to an AdropNativeAdView.
          }
      }

      // Batch failure
      func onAdsFailedToReceive(_ errorCode: AdropErrorCode) {
          print("Batch load failed: \(errorCode)")
      }

      // Click / impression / video callbacks still fire per instance.
      func onAdClicked(_ ad: AdropNativeAd) {
          print("Native clicked")
      }

      func onAdImpression(_ ad: AdropNativeAd) {
          print("Native impression")
      }
  }
  ```

  ```objc Objective-C theme={null}
  @interface ViewController () <AdropNativeAdDelegate>
  @property (nonatomic, strong) NSArray<AdropNativeAd *> *ads;
  @end

  @implementation ViewController

  - (void)viewDidLoad {
      [super viewDidLoad];
      [AdropNativeAd loadsWithUnitId:@"YOUR_UNIT_ID" contextId:@"" delegate:self];
  }

  #pragma mark - AdropNativeAdDelegate

  - (void)onAdReceived:(AdropNativeAd *)ad { /* batch path */ }
  - (void)onAdFailedToReceive:(AdropNativeAd *)ad :(AdropErrorCode)errorCode {}

  - (void)onAdsReceived:(NSArray<AdropNativeAd *> *)ads {
      self.ads = ads;
      for (AdropNativeAd *ad in ads) {
          [self bindNativeAd:ad];
      }
  }

  - (void)onAdsFailedToReceive:(AdropErrorCode)errorCode {
      NSLog(@"Batch load failed: %ld", (long)errorCode);
  }

  - (void)onAdClicked:(AdropNativeAd *)ad {
      NSLog(@"Native clicked");
  }

  - (void)onAdImpression:(AdropNativeAd *)ad {
      NSLog(@"Native impression");
  }

  @end
  ```
</CodeGroup>

### Delegate Methods

| Method                                                               | When it fires                                                                                  |
| -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `onAdsReceived(_:)`                                                  | Batch delivered. **Every ad is fully rendered** — creative is ready to bind.                   |
| `onAdsFailedToReceive(_:)`                                           | Request rejected, network failure, or no fillable ads were returned (`ERROR_CODE_AD_NO_FILL`). |
| `onAdClicked` / `onAdImpression` / `onAdVideoStart` / `onAdVideoEnd` | Fire on each returned ad just like a single `load()`.                                          |

<Warning>
  The singular `onAdReceived(_:)` / `onAdFailedToReceive(_:_:)` callbacks are **not** invoked on the `loads` path. Use `onAdsReceived(_:)` / `onAdsFailedToReceive(_:)` as the sole batch signals.
</Warning>

### Constants

<ParamField body="AdropNativeAd.maxLoadsBatch" type="Int" default="5">
  Upper bound on ads returned from a single `loads(...)` call.
</ParamField>

### Constraints

* **Maximum 5 ads per call.** If the server returns more, only the first 5 are delivered.
* **Backfill is not applied.** If no direct ads fill, `onAdsFailedToReceive` is called with `ERROR_CODE_AD_NO_FILL` regardless of backfill configuration.
* Unlike `AdropBanner.loads(...)`, the native batch waits for every returned ad to finish rendering before firing `onAdsReceived(_:)`, so each instance is fully rendered on delivery.
* Hold strong references to the returned ads. If they deallocate before being bound to an `AdropNativeAdView`, they're silently dropped.

***

## Backfill Ads

When backfill ads are enabled, backfill ads are automatically loaded when direct ads are unavailable. Use the `isBackfilled` property to check if the ad is a backfill ad.

<CodeGroup>
  ```swift Swift theme={null}
  class ViewController: UIViewController, AdropNativeAdDelegate {
      private var nativeAd: AdropNativeAd?

      func onAdReceived(_ nativeAd: AdropNativeAd) {
          if nativeAd.isBackfilled {
              print("Backfill ad loaded")
          } else {
              print("Direct ad loaded")
          }
      }

      func onAdFailedToReceive(_ nativeAd: AdropNativeAd, _ errorCode: AdropErrorCode) {
          switch errorCode {
          case .ERROR_CODE_AD_NO_FILL:
              print("No direct ad, requesting backfill...")
          case .ERROR_CODE_AD_BACKFILL_NO_FILL:
              print("No backfill ad available")
              // Hide ad area
          default:
              print("Ad load failed: \(errorCode)")
          }
      }
  }
  ```

  ```objc Objective-C theme={null}
  @interface ViewController () <AdropNativeAdDelegate>
  @property (nonatomic, strong) AdropNativeAd *nativeAd;
  @end

  @implementation ViewController

  - (void)onAdReceived:(AdropNativeAd *)nativeAd {
      if (nativeAd.isBackfilled) {
          NSLog(@"Backfill ad loaded");
      } else {
          NSLog(@"Direct ad loaded");
      }
  }

  - (void)onAdFailedToReceive:(AdropNativeAd *)nativeAd :(AdropErrorCode)errorCode {
      if (errorCode == AdropErrorCodeAdNoFill) {
          NSLog(@"No direct ad, requesting backfill...");
      } else if (errorCode == AdropErrorCodeBackfillNoFill) {
          NSLog(@"No backfill ad available");
          // Hide ad area
      } else {
          NSLog(@"Ad load failed: %ld", (long)errorCode);
      }
  }

  @end
  ```
</CodeGroup>

### AdChoices Position

For backfill native ads, you can choose which corner displays the AdChoices badge. Set `preferredAdChoicesPosition` on the `AdropNativeAd` instance before calling `load()`.

<CodeGroup>
  ```swift Swift theme={null}
  import AdropAds

  let nativeAd = AdropNativeAd(unitId: "YOUR_UNIT_ID")
  nativeAd.preferredAdChoicesPosition = .bottomRight
  nativeAd.load()
  ```

  ```objc Objective-C theme={null}
  @import AdropAds;

  AdropNativeAd *nativeAd = [[AdropNativeAd alloc] initWithUnitId:@"YOUR_UNIT_ID"];
  nativeAd.preferredAdChoicesPosition = AdropAdChoicesPositionBottomRight;
  [nativeAd load];
  ```
</CodeGroup>

| Value          | Description                |
| -------------- | -------------------------- |
| `.topLeft`     | Top-left corner            |
| `.topRight`    | Top-right corner (default) |
| `.bottomLeft`  | Bottom-left corner         |
| `.bottomRight` | Bottom-right corner        |

<Note>
  This setting is a preferred hint for the backfill network and applies only to backfill native ads — direct ads are not affected. The value must be set before `load()` is called. The backfill network may override the position depending on its policy.
</Note>

<Note>
  To use backfill ads, add the `AdropAds-Backfill` dependency. See [Getting Started](/sdk/ios/overview).
</Note>

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Getting Started" href="/sdk/ios">
    SDK installation and initialization
  </Card>

  <Card title="Banner Ads" href="/sdk/ios/banner">
    Implementing banner ads
  </Card>

  <Card title="Interstitial Ads" href="/sdk/ios/interstitial">
    Implementing interstitial ads
  </Card>

  <Card title="Rewarded Ads" href="/sdk/ios/rewarded">
    Implementing rewarded ads
  </Card>
</CardGroup>
