# Prebid Integration on iOS

This guide adds the Chartboost Prebid adapter to an iOS app that already runs Prebid Mobile. If you are new to the
adapter, read the [Prebid Integration Overview](/en/monetization/integrate/prebid/overview/) first.

<div class="alert alert-info" role="alert">
  <b>Note:</b> The iOS adapter is distributed through Swift Package Manager only. CocoaPods is not supported.
</div>

## Minimum Requirements

| Component | Version |
| --------- | ------- |
| Prebid Mobile SDK | See [Supported Prebid Mobile versions](#supported-prebid-mobile-versions) |
| iOS | 15.0+ |
| Xcode | 26.0+ |

The Swift Package resolves the Chartboost Monetization SDK for you, pinned to the minor of the version it is
certified against (9.14.0), so you do not pick
its version. If your app also depends on the Monetization SDK through SPM, your requirement has to overlap that
pinned minor: an `.exact()` pin elsewhere, or a lower bound above it, fails to resolve.

### Supported Prebid Mobile versions

The adapter's Swift Package pins Prebid Mobile to the range certified for each release. See its
[Package.swift](https://github.com/ChartBoost/chartboost-prebid-ios-adapter/blob/main/Package.swift)
for the current range. A Prebid Mobile minor release can change the plugin renderer contract, so a newer minor joins
the range in a later adapter release, once it is certified. If your own manifest requires a Prebid Mobile version
outside that range, the package fails to resolve.

## 1. Add the Swift Package

The adapter's Swift Package declares the Chartboost Monetization SDK and Prebid Mobile as dependencies, so adding
this one package resolves all three. You do not add Prebid Mobile or the Monetization SDK separately.

<ul class="tab" data-tab="dddb1f27-9bd1-4ae3-ba01-94b24fefafe7" data-name="prebidSPM">
  
      <li class="active">
          <a href="#">Xcode </a>
      </li>
  
      <li>
          <a href="#">Package.swift </a>
      </li>
  
</ul>
<ul class="tab-content" id="dddb1f27-9bd1-4ae3-ba01-94b24fefafe7" data-name="prebidSPM">
  
      <li class="active">
<p>In Xcode, choose <strong>File ▸ Add Package Dependencies…</strong>, enter the package URL, and add the
<code class="language-plaintext highlighter-rouge">ChartboostPrebidAdapter</code> library product to your app target:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://github.com/ChartBoost/chartboost-prebid-ios-adapter
</code></pre></div></div>
</li>
  
      <li>
<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">dependencies</span><span class="p">:</span> <span class="p">[</span>
    <span class="o">.</span><span class="nf">package</span><span class="p">(</span>
        <span class="nv">url</span><span class="p">:</span> <span class="s">"https://github.com/ChartBoost/chartboost-prebid-ios-adapter"</span><span class="p">,</span>
        <span class="nv">from</span><span class="p">:</span> <span class="s">"309.14.0"</span>
    <span class="p">),</span>
<span class="p">],</span>
<span class="nv">targets</span><span class="p">:</span> <span class="p">[</span>
    <span class="o">.</span><span class="nf">target</span><span class="p">(</span>
        <span class="nv">name</span><span class="p">:</span> <span class="s">"YourApp"</span><span class="p">,</span>
        <span class="nv">dependencies</span><span class="p">:</span> <span class="p">[</span>
            <span class="o">.</span><span class="nf">product</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"ChartboostPrebidAdapter"</span><span class="p">,</span> <span class="nv">package</span><span class="p">:</span> <span class="s">"chartboost-prebid-ios-adapter"</span><span class="p">),</span>
        <span class="p">]</span>
    <span class="p">),</span>
<span class="p">]</span>
</code></pre></div></div>
</li>
  
</ul>


The adapter version (`309.14.0`) encodes the Prebid Mobile major plus the
Monetization SDK version it is certified against, which is Monetization SDK
9.14.0 for this release.

<div class="alert alert-warning" role="alert">
  <b>Required:</b> Add <code>-ObjC</code> to your app target's <b>Other Linker Flags</b> (Build Settings). Without
  it the linker strips the Monetization SDK's Objective-C categories, which ship inside a static framework. See
  <a href="/en/monetization/integrate/ios/get-started/">Monetization SDK Get Started</a>.
</div>

## 2. Register the adapter and initialize

Register the Chartboost plugin adapter **before the first ad load**. Registering before or right after
`Prebid.initializeSDK` both work. The Chartboost Monetization SDK is started separately, the same way as a
standalone Chartboost integration (see
[Monetization SDK Get Started](/en/monetization/integrate/ios/get-started/)).

<div class="alert alert-info" role="alert">
  <b>Note on nomenclature:</b> Prebid calls this kind of component a plugin renderer, and we call ours an adapter.
  Same thing, which is why the method you call is <code>registerPluginRenderer</code>.
</div>

Start the Monetization SDK before your first ad load, not just before your first show. The adapter reads the
Chartboost bidder token from the SDK each time Prebid builds a request, so before start there is no token and the
auction runs without Chartboost demand. The only trace is a `Bid token nil due to SDK not being initialized.`
warning from the Monetization SDK.

```swift
import ChartboostPrebidAdapter
import ChartboostSDK
import PrebidMobile

let myListener = MyListener() // hold this yourself; see step 4
let adapter = ChartboostPrebidAdapter()
adapter.eventListener = myListener // optional

// Attaches the Chartboost adapter name, version, and bidder token to every auction request.
Prebid.registerPluginRenderer(adapter)

// Point Prebid Mobile at your Prebid Server.
do {
    try Prebid.initializeSDK(serverURL: "https://<your-pbs-host>/openrtb2/auction")
} catch {
    print("Prebid init failed: \(error)")
}

// Start the Chartboost Monetization SDK.
Chartboost.start(withAppID: "<your-app-id>", appSignature: "<your-app-signature>") { error in
    if let error { print("Chartboost start failed: \(error)") }
}
```

## 3. Load ads as usual

Load a Prebid Mobile rendering ad unit (`BannerView`, `InterstitialRenderingAdUnit`, or `RewardedAdUnit`) exactly
as you would without the adapter. A Chartboost-flagged winning bid routes to the Chartboost adapter automatically;
everything else uses Prebid's default renderer. No per-ad-unit Chartboost code is required.

Two ad-unit choices do affect Chartboost, so settle them before you finalize your units: your slot size decides
which Chartboost banner size can fill it, and the Prebid config ID you pass becomes the Chartboost ad location. See
[Banner sizes](#banner-sizes) and [Configuration and logging](#configuration-and-logging).

## 4. Observe the adapter's own ad lifecycle (optional)

Set `eventListener` on the adapter to see what the Chartboost adapter specifically did, separately from Prebid's
per-ad-unit delegates. It is the usual way to confirm that Chartboost rendered a bid rather than Prebid's default
renderer. The property is `weak`, so keep a strong reference of your own or the callbacks stop arriving.

Every method is optional, so implement only the ones you need, and because they are optional a wrong signature
compiles cleanly and then never fires. Copy these signatures rather than retyping them. `onAdDismissed` and
`onUserEarnedReward` are fullscreen-only and never fire for banners. Subclassing `NSObject` is the safe default for
optional `@objc` dispatch.

```swift
final class MyListener: NSObject, ChartboostPrebidAdapterEventListener {
    func onAdLoaded(format: ChartboostPrebidAdapterAdFormat) {}
    func onAdDisplayed(format: ChartboostPrebidAdapterAdFormat) {}
    func onAdClicked(format: ChartboostPrebidAdapterAdFormat) {}
    func onAdFailed(format: ChartboostPrebidAdapterAdFormat, error: Error) {}
    func onAdDismissed(format: ChartboostPrebidAdapterAdFormat) {}
    func onUserEarnedReward(format: ChartboostPrebidAdapterAdFormat) {}
}
```

## 5. Verify the integration

Prebid routes a bid to the Chartboost adapter only when the bid's `ext.prebid.meta.rendererName` and
`ext.prebid.meta.rendererVersion` match the registered plugin, and a mismatch is silent. See
[How rendering is routed](/en/monetization/integrate/prebid/overview/#how-rendering-is-routed).

The version needs no coordination. The Chartboost bidder on Prebid Server echoes back the version your registered
plugin declared, so the two match by construction and there is no constant to keep in sync. The name is derived
server-side, and for iOS traffic it is `Chartboost-iOS-SDK`. Read both back if you want to see what the client
registered:

```swift
import ChartboostPrebidAdapter

print("\(ChartboostPrebidAdapter.pluginName) \(ChartboostPrebidAdapter.pluginVersion)")
```

The real confirmation is at runtime: `onAdLoaded` on the adapter's `eventListener` (step 4) fires only when
Chartboost rendered the bid.

## Banner sizes

The Chartboost Monetization SDK renders a banner at one of its own `CHBBannerSize` dimensions and nothing else:

| Size | Dimensions |
| ---- | ---------- |
| `CHBBannerSizeStandard` | 320x50 |
| `CHBBannerSizeMedium` | 300x250 |
| `CHBBannerSizeLeaderboard` | 728x90 |
| `CHBBannerSizeHalfPage` | 300x600 |

Given a winning bid's negotiated width and height, the adapter selects the size with the **largest area that fits
entirely inside** them. A full-width bid of, say, 412x50 renders 320x50 within it, the same way a fixed size is
fitted into an adaptive banner slot. Largest by area, not by width: a 728x250 bid renders 300x250 rather than
728x90. The adapter never renders a size larger than the space it was given, because that would count a billable
impression while overflowing your layout.

If nothing fits, the adapter fails the load instead of rendering at the wrong size. A 320x49 bid is a no-fill,
because even the shortest Chartboost banner needs 50 points of height.

The candidate list is compiled into the adapter rather than read from the host SDK at runtime, so a size the
Monetization SDK adds later needs a new adapter release before it becomes selectable. Your Prebid Server has to
offer a size in the auction as well.

## Configuration and logging

The iOS adapter takes no configuration object and no separate Chartboost ad location setting. It passes the Prebid
config ID you supply when you build the ad unit straight through as the Chartboost ad location, with no override.

<div class="alert alert-warning" role="alert">
  <b>Caution:</b> Chartboost named locations cannot be longer than 20 characters, and they are meant to be created
  in the dashboard before use. Nothing in the adapter or the SDK truncates or validates the value, so a long or
  unregistered Prebid config ID (a UUID, for example) may not report the way you expect. Keep the config IDs you use
  for Chartboost-eligible inventory short and registered. See
  <a href="/en/monetization/integrate/ios/named-locations/">Named Locations</a>.
</div>

The adapter has no log level of its own. It logs through Prebid Mobile, so `Prebid.shared.logLevel` governs its
output, but that output is only a few warnings for calls made in the wrong state. There is no per-event logging, so
raising the level will not produce a load or show trace. For the rendering side, set the Monetization SDK's own
level with `Chartboost.setLoggingLevel(_:)`; see
[SDK Configuration Methods](/en/monetization/integrate/ios/get-started/#sdk-configuration-methods).

## Consent and privacy

This adapter does not collect, store, or forward any consent signals. GDPR, US Privacy (CCPA), COPPA, and GPP are
owned by the Chartboost Monetization SDK, which collects these signals if available from your consent management
platform. Configure your regulatory signals before loading ads, exactly as you would for any other Chartboost
integration; see [SDK Privacy Methods](/en/monetization/integrate/ios/sdk-privacy-methods/) for how.
Plugin-rendered ads render through that same SDK instance, so its consent state applies to them too.

## Troubleshooting

**A Chartboost-flagged bid renders through Prebid's default renderer.** The plugin name or version does not match
your Prebid Server's `ext.prebid.meta` stamp. See [Verify the integration](#5-verify-the-integration).

**Banners no-fill with a size message.** The bid's negotiated size is too small for any Chartboost banner size. See
[Banner sizes](#banner-sizes). Most size mismatches are filtered server-side before they reach the device, so a
client-side no-fill points at a bid whose size the auction should not have offered.

**The app crashes with `unrecognized selector` at `Chartboost.start`.** The `-ObjC` linker flag is missing, so the
Monetization SDK's Objective-C categories were stripped. See [step 1](#1-add-the-swift-package).
