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.
这是 5 分钟接入的完整流程。开始之前,请确认你已经完成 安装。
1. 创建会话
入口是 KontextAds.createSession(_:),它返回一个 Session——后续整个对话生命周期都通过它来操作。
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, // 可选——你自行收集的 IDFA(为 nil 时 SDK 会自动收集)
vendorId: nil, // 可选——你自行收集的 IDFV(为 nil 时 SDK 会自动收集)
onEvent: { event in
// 处理广告生命周期事件
print("[kontext] \(event.name)")
}
))
会话在其生命周期内会固定 userId、conversationId 和 publisherToken。当这些值变化时(例如用户开始新对话),请重建会话。
Session 是 @MainActor 隔离的——请在 main actor 上调用其方法(SwiftUI 视图和 @MainActor 隔离的 view controller 默认满足)。
2. 喂入对话消息
每条消息出现时都要 add 到会话中。用户消息会在后台触发一次防抖后的预加载;助手消息让 SDK 把匹配到的广告绑定到对应的广告位上。
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 是同步返回的。预加载的结果会稍后通过 onEvent 回调送达(.filled、.noFill、.error ……)——不会通过返回值返回。
3. 渲染广告
使用 session.createAd(messageId:) 为某条助手消息获取一个 Ad,再用 InlineAdUIView 渲染。
createAd 是幂等的:对同一个 messageId 多次调用会返回同一个 Ad。请缓存返回的实例,避免 view controller / cell 复用时重复创建。
let ad = session.createAd("msg-2")
let adView = InlineAdUIView(ad: ad)
adView.translatesAutoresizingMaskIntoConstraints = false
container.addSubview(adView)
// 在 UITableView / UICollectionView 的 cell 中,观察高度变化以正确撑开尺寸。
adView.onHeightChange = { [weak self] height in
self?.updateRowHeight(height)
}
4. 释放资源
对话结束或视图消失时调用 destroy()。该方法是幂等的,且是取消待处理网络请求、释放 web view 资源的必要操作。
订阅事件
接收 AdEvent 有两种等价方式——任选其一。
onEvent 回调
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
import Combine
var cancellables: Set<AnyCancellable> = []
session.eventPublisher
.sink { event in
print("event: \(event.name)")
}
.store(in: &cancellables)
两种方式都会在主线程上送达相同的事件。完整事件列表见 API 参考。