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

# Showing your first ad

> Create a session, feed messages, mount InlineAdUIView, and observe events.

This is the 5-minute integration walkthrough. Before you start, make sure you've completed [Installation](/sdk/swift/installation).

## 1. Create a session

The entry point is `KontextAds.createSession(_:)`, which returns a `Session` you'll use for the rest of the conversation lifecycle.

```swift theme={null}
import KontextSwiftSDK

let session = KontextAds.createSession(SessionOptions(
    publisherToken: "<your-publisher-token>",
    userId: "user-1234",
    conversationId: "conv-5678",
    character: Character(
        id: "character-1234",
        name: "John Doe",
        avatarUrl: URL(string: "https://example.com/avatar.png")!,
        greeting: "Hello, how can I help you today?"
    ),
    advertisingId: nil, // optional — pass an IDFA you collected manually (SDK auto-collects when nil)
    vendorId: nil, // optional — pass an IDFV you collected manually (SDK auto-collects when nil)
    onEvent: { event in
        // Handle ad lifecycle events
        print("[kontext] \(event.name)")
    }
))
```

The session keeps `userId`, `conversationId`, and `publisherToken` fixed for its lifetime. Recreate the session when any of those change (e.g. when the user starts a new chat).

<Note>
  `Session` is `@MainActor` — call its methods from the main actor (default in SwiftUI views and `@MainActor`-isolated view controllers).
</Note>

## 2. Feed conversation messages

Add every message to the session as it appears. User messages trigger a debounced preload in the background; assistant messages let the SDK link the matched ad to the corresponding placement.

```swift theme={null}
session.addMessage(Message(
    id: "msg-1",
    role: .user,
    content: "Hello, how are you?",
    createdAt: Date()
))

session.addMessage(Message(
    id: "msg-2",
    role: .assistant,
    content: "I am good, thank you!",
    createdAt: Date()
))
```

`addMessage` returns synchronously. The preload result is delivered later via the `onEvent` callback (`.filled`, `.noFill`, `.error`, …) — not via a return value.

## 3. Render the ad

Use `session.createAd(messageId:)` to obtain an `Ad` for an assistant message, then render it with `InlineAdUIView`.

`createAd` is idempotent: calling it repeatedly with the same `messageId` returns the same `Ad`. Cache the returned instance so view-controller / cell reuse doesn't recreate it.

```swift theme={null}
let ad = session.createAd("msg-2")
let adView = InlineAdUIView(ad: ad)
adView.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(adView)

// Inside a UITableView/UICollectionView cell, observe the height for proper sizing.
adView.onHeightChange = { [weak self] height in
    self?.updateRowHeight(height)
}
```

## 4. Tear down

Call `destroy()` when the conversation ends or the view disappears. Idempotent and required to cancel pending network requests and release web view resources.

```swift theme={null}
session.destroy()
```

## Observing events

Two equivalent ways to consume `AdEvent`s — pick whichever fits your codebase.

### `onEvent` callback

```swift theme={null}
let session = KontextAds.createSession(SessionOptions(
    publisherToken: "...",
    userId: "...",
    conversationId: "...",
    onEvent: { event in
        switch event {
        case .filled(let data):
            print("ad filled: \(data.bidId) revenue=\(data.revenue ?? 0)")
        case .clicked(let data):
            print("clicked: \(data.url)")
        default: break
        }
    }
))
```

### Combine publisher

```swift theme={null}
import Combine

var cancellables: Set<AnyCancellable> = []

session.eventPublisher
    .sink { event in
        print("event: \(event.name)")
    }
    .store(in: &cancellables)
```

Both deliver the same events on the main thread. The complete event list lives in the [API reference](/sdk/swift/api).
