Skip to content

running features

Joseph Samir edited this page Jun 21, 2026 · 2 revisions

Running Features

Features are resolved through variations of relevant experiences. When you run a feature, the SDK finds all experiences whose variations include a fullStackFeature change linked to that feature, evaluates targeting rules, buckets the visitor, and returns the resolved feature status and variable values. See the data model for the full resolution chain.

Run a Single Feature

Returns a single feature's status and variable values for the current visitor. Always returns a non-nil Feature: when the visitor is not bucketed or the SDK is not ready, a disabled feature is returned rather than nil or an error.

// Async/await
let feature = await ctx.runFeature("feature-key")

if feature.status == .enabled {
    let ctaColor = feature.variable("ctaColor", as: String.self) ?? "#0066ff"
}

Parameters:

Parameter Type Required Description
key String Yes The feature's unique key

Returns: Feature — the resolved feature. Never nil and never throws: a disabled Feature is returned when the visitor does not qualify, the feature is absent from config, or the SDK is not ready yet.

Note: Unlike runExperience, there is no enableTracking parameter on runFeature. Feature evaluation delegates to the underlying experience bucketing, which tracks per its own contract. This matches the Android SDK's API surface (Android parity, F-171).

Run All Features

Returns every feature in the config with its status and variable values for the current visitor.

let features = await ctx.runFeatures()

for feature in features where feature.status == .enabled {
    print("enabled: \(feature.key)")
}

Parameters: None.

Returns: [Feature] — one entry per feature in config order. Returns [] when the SDK is not yet ready.

Feature Fields

Each resolved feature is returned as a Feature with the following fields:

Field Type Description
id String The feature ID
key String The feature key
status FeatureStatus .enabled or .disabled
variables [String: FeatureVariable] The feature variables keyed by variable name

FeatureStatus

switch feature.status {
case .enabled:
    // Feature is on for this visitor
case .disabled:
    // Feature is off; variables are empty
}

Feature Variables

Variables are accessed via the typed variable(_:as:) accessor, which returns nil when the key is absent or the type does not match — it never throws.

// String variable
let color = feature.variable("buttonColor", as: String.self) ?? "blue"

// Boolean variable
let isOn = feature.variable("darkMode", as: Bool.self) ?? false

// Integer variable
let timeout = feature.variable("timeoutMs", as: Int.self) ?? 3000

// Float / Double variable
let multiplier = feature.variable("priceMultiplier", as: Double.self) ?? 1.0

// JSON variable (returned as Data; decode at the call site)
if let data = feature.variable("config", as: Data.self) {
    let decoded = try? JSONDecoder().decode(MyConfig.self, from: data)
}

Variable cases in FeatureVariable: .boolean(Bool), .integer(Int), .float(Double), .string(String), .json(Data).

Complete Example

End-to-end flow: initialize the SDK, create a visitor context, run a feature, and use its status and variables.

import ConvertSwiftSDK

let sdk = ConvertSwiftSDK(configuration: ConvertConfiguration(sdkKey: "YOUR_SDK_KEY"))

Task {
    try await sdk.ready()
    let ctx = sdk.createContext(visitorId: "user-unique-id")
    let feature = await ctx.runFeature("new-checkout")

    if feature.status == .enabled {
        let primaryColor = feature.variable("primaryColor", as: String.self) ?? "#0066ff"
        showNewCheckout(color: primaryColor)
    } else {
        showLegacyCheckout()
    }
}

Clone this wiki locally