-
Notifications
You must be signed in to change notification settings - Fork 0
iOS Usage
Featured exposes its Kotlin API to Swift via SKIE. No Kotlin toolchain is needed in Xcode — the framework is built by the KMP Gradle build and consumed as a prebuilt XCFramework or Swift Package.
Import the module:
import FeaturedCoreFeaturedCore is the Swift product name. CoreConfigParam is the Kotlin ConfigParam<T> type as seen from Swift.
Call initialize() before serving any screen, then trigger a background fetch:
@MainActor
class AppState: ObservableObject {
let configValues: ConfigValues
init() {
configValues = ConfigValues(
localProvider: nil,
remoteProvider: nil,
onProviderError: { error in print("Featured error: \(error)") }
)
}
func setup() async {
do {
try await configValues.initialize()
try await configValues.fetch()
} catch {
print("Featured setup error: \(error)")
}
}
}Pass provider instances to localProvider and remoteProvider as needed. At least one must be non-nil.
let configValue = try await configValues.getValue(param: FeatureFlags.shared.newCheckout)
let isEnabled: Bool = configValue.valueFeatureFlags.shared.newCheckout is a CoreConfigParam<KotlinBoolean> — the Kotlin-generated ConfigParam accessed through the Swift wrapper your team writes (see Declaring Flags).
SKIE bridges the Kotlin Flow as an AsyncStream:
for await configValue in configValues.observe(param: FeatureFlags.shared.newCheckout) {
updateUI(configValue.value)
}Use this inside a Task tied to your view's lifetime:
.task {
for await configValue in configValues.observe(param: FeatureFlags.shared.newCheckout) {
isNewCheckoutEnabled = configValue.value
}
}Build a Combine publisher on top of AsyncStream:
import Combine
class CheckoutViewModel: ObservableObject {
@Published var isNewCheckoutEnabled: Bool = false
private let configValues: ConfigValues
init(configValues: ConfigValues) {
self.configValues = configValues
}
func startObserving() {
Task {
for await configValue in configValues.observe(param: FeatureFlags.shared.newCheckout) {
await MainActor.run {
self.isNewCheckoutEnabled = configValue.value
}
}
}
}
}If your Swift wrapper exposes a publisher(for:) method:
featureFlags.publisher(for: newCheckoutFlag)
.receive(on: DispatchQueue.main)
.sink { isEnabled in updateUI(isEnabled) }
.store(in: &cancellables)struct CheckoutView: View {
@StateObject private var viewModel: CheckoutViewModel
var body: some View {
Group {
if viewModel.isNewCheckoutEnabled {
NewCheckoutFlow()
} else {
LegacyCheckoutFlow()
}
}
.onAppear { viewModel.startObserving() }
}
}For release builds, Featured can physically strip code behind disabled flags at compile time. A flag declared with default = false in the KMP module generates an xcconfig condition DISABLE_<FLAG_KEY> that feeds into Xcode as a Swift compilation condition. See iOS — xcconfig DCE for the setup procedure.