FlwKit
Sdk

Configuration

Configure the FlwKit iOS SDK and display flows in your app.

Basic setup

Call FlwKit.configure() once at app startup. Place it in your @main App init() or AppDelegate.application(_:didFinishLaunchingWithOptions:) — before any view appears.

import SwiftUI
import FlwKit_ios
 
@main
struct MyApp: App {
    init() {
        FlwKit.configure(apiKey: "your-api-key")
    }
 
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

configure() triggers a background prefetch of the active flow immediately. By the time a user reaches FlwKitFlowView, the flow is typically already cached and renders with no loading state.


FlwKit.configure()

public static func configure(
    apiKey: String,
    userId: String? = nil,
    baseURL: String? = nil
)
ParameterTypeRequiredDefaultDescription
apiKeyStringYesYour app's API key from the dashboard.
userIdString?NonilStable identifier for the current user. Used to tie analytics events and A/B test assignments to a specific user. Pass nil to use an anonymous session.
baseURLString?Nohttps://api.flwkit.comOverride the API base URL. Only needed when self-hosting the FlwKit backend.

FlwKitFlowView

Add FlwKitFlowView to any SwiftUI view. The active flow is fetched automatically.

// Minimal
FlwKitFlowView()
 
// With completion handler
FlwKitFlowView { result in
    // navigate away
}
 
// Full control
FlwKitFlowView(
    attributes: ["plan": "pro"],
    onComplete: { result in },
    onExit: { }
)
ParameterTypeRequiredDefaultDescription
attributes[String: Any]No[:]Key-value data passed into the flow. Accessible in conditional transitions via attributes.{key}.
onComplete((FlwKitCompletionResult) -> Void)?NonilCalled when the flow reaches a terminal complete action.
onExit(() -> Void)?NonilCalled when the user exits mid-flow.

FlwKitCompletionResult

PropertyTypeDescription
flowIdStringThe flow key identifier.
variantIdString?A/B test variant ID, or nil if the user was not in a test.
completedAtDateTimestamp of completion.
answers[String: Any]All answers keyed by block key. Choice answers are mapped to option labels, not raw values.

FlwKit.present() — UIKit

Use FlwKit.present() to get the flow view programmatically and embed it in a UIHostingController.

FlwKit.present(
    attributes: [:],
    onComplete: { result in
        DispatchQueue.main.async { self.dismiss(animated: true) }
    },
    completion: { result in
        switch result {
        case .success(let flowView):
            let host = UIHostingController(rootView: flowView)
            host.modalPresentationStyle = .fullScreen
            self.present(host, animated: true)
        case .failure(let error):
            print(error.localizedDescription)
        }
    }
)
ParameterTypeRequiredDefaultDescription
attributes[String: Any]No[:]Same as FlwKitFlowView.attributes.
onComplete(FlwKitCompletionResult) -> VoidNono-opSame as FlwKitFlowView.onComplete.
onExit(() -> Void)?NonilSame as FlwKitFlowView.onExit.
completion(Result<AnyView, Error>) -> VoidYesReceives the flow view or an error.

Error handling

All errors conform to LocalizedError. Check error.localizedDescription for a human-readable message.

When flowNotFound or a network error occurs, the SDK automatically falls back to the most recently cached flow. The error is only surfaced if no cache exists.


Caching

The SDK caches the active flow in UserDefaults after the first successful fetch.

SituationBehavior
Cache exists on launchFlow renders immediately; cache refreshes in the background.
No cache, network availableFlow fetches with a loading indicator.
No cache, network unavailableFlwKitFlowView shows an error state with a retry button.

User progress (current screen and answers) is also persisted and restored automatically if the user closes the app mid-flow.


Next steps

On this page