SDKsiOS

Reference

Theme properties, fonts, card options, configuration, and size constants for the Koah iOS SDK.

Theme properties

Set these on a KoahTheme applied via .koahTheme(_:).

PropertyTypeDefaultDescription
colorSchemeKoahColorScheme.auto.light / .dark / .auto (follow device)
accentColorColor?nil → #0D0D0DCTA button and accent color. Text-on-accent is computed automatically for contrast — never expose it.
fontKoahFont?nil (inherits from app)Typeface, optional uniform weight override, and optional Font.Design. Sizes are SDK-locked per element.
cornerRadiusCGFloat19Card corner radius.

Text colors, spacing, and component-level radii are derived internally from these inputs and are not publicly configurable. KoahColorScheme.auto resolves at render time via SwiftUI's \.colorScheme environment, so flipping the device theme re-resolves naturally.

Fonts

KoahFont gives explicit control over typeface, weight, and Font.Design while keeping per-element font sizes locked by the SDK:

// System font (default San Francisco)
.koahTheme(KoahTheme(font: .system(weight: .regular)))

// System font with a design variant
.koahTheme(KoahTheme(font: .system(weight: .medium, design: .rounded)))

// Custom font shipped with your app
.koahTheme(KoahTheme(font: .custom("Inter", weight: .regular)))

Card sizing

Bound each axis of a KoahCard with the width and height parameters, both KoahAxisSize?:

KoahCard(
    adContext: .conversation(question: q, answer: a),
    width: .fill,
    height: .range(max: 420),
    cacheKey: "msg-1"
)
ValueBehavior
nil (omit)Unbounded — the card wraps its content within the parent's own bounds, keeping the most formats in play.
.fixed(320)Force the axis to an exact size in points.
.range(min:max:)Wrap content within bounds; min is a floor, max a pure ceiling. .range(max:) / .range(min:) set a single bound.
.fillFill the parent's available space along this axis. Requires the parent to bound that axis — traps at layout on a scroll axis.

An ad is never shown clipped — if the slot turns out too short for the format the server picked, it renders nothing and .slotTooSmall fires once. Leaving axes unbounded allows more ad formats, improving fill.

Presentation and performance

Starting with 1.1.0, server-controlled presentation on iOS lets us test and refine ad experiences faster. Keep using the existing KoahCard API; no additional integration step is needed.

Image caching improves performance automatically, with no additional configuration.

Event handling

The onEvent callback on KoahCard reports ad lifecycle events. Handle the cases your surface cares about:

KoahCard(
    adContext: .conversation(question: q, answer: a),
    cacheKey: messageId,
    onEvent: { event in
        switch event {
        case .noAdFill: break               // no inventory
        case .adServed: break               // ad delivered
        case .impressionTracked: break      // impression accepted by Koah
        case .adViewed: break               // 50% visible for 1 second
        case .adClicked: break              // user tapped
        case .inAppBrowserClosed: break     // in-app browser dismissed
        case .slotTooSmall: break           // ad can't fit the slot; nothing renders
        default: break
        }
    }
)

Configuration

Pass these to Koah.shared.configure:

Koah.shared.configure(
    publisherId: "your-publisher-id",         // Required
    baseUrl: "https://staging.koahlabs.app",  // Optional — defaults to production
    logLevel: .debug                          // Optional — defaults to .none
)
ParameterTypeDefaultDescription
publisherIdString—Required. From your publisher dashboard.
baseUrlStringproductionOverride for staging or local environments.
logLevelKoahLogLevel.noneLogging verbosity: .none / .error / .warning / .info / .debug.

Sample ads

The KoahSampleAd family renders a representative ad with no network fetch — for SwiftUI previews, demo galleries, and snapshot tests. Construct one by hand or use the ready-made specimens, then pass it to KoahCard(sample:):

KoahCard(sample: .poll, cacheKey: "preview", koah: .preview)

Specimens: .card, .image, .poll, .expandable. Sample-backed cards never call the network and never report impressions.

Age range buckets

Available KoahAgeRange buckets for visitor attributes:

.under13<13
.age13To1513–15
.age16To1716–17
.age18To2018–20
.age21To2421–24
.age25To2925–29
.age30To3430–34
.age35To3935–39
.age40To4440–44
.age45To4945–49
.age50To5450–54
.age55To5955–59
.age60To6460–64
.age65To6965–69
.age70To7470–74
.age75Plus75+

.under13 is accepted for compatibility but ignored by SDK versions later than 0.10.0 — see Children's privacy.

Gender and income values

Available values for visitor attributes:

AttributeTypeValues
GenderKoahGender.male / .female / .unknown
IncomeKoahIncomeBracket.under50k / .income50kTo100k / .income100kTo150k / .income150kTo200k / .income200kPlus / .unknown

Brackets are annual household income in thousands of USD. .unknown clears the locally stored value.

Was this helpful?