FlowSession and binding it to the .flowPresenter view modifier. Setting the binding presents the flow; the SDK clears it and calls your onResult closure when the flow ends. You can also embed a FlowPresenterView directly when you want the flow inline in your own view hierarchy.
The SDK must be configured first.
FlowPilot.shared is nil until you call FlowPilot.configure(_:) at launch. See Configuration.Create a session
There are two ways to get aFlowSession, both on FlowPilot and both @MainActor.
createSessionthrows aFlowPilotErrorwhen no flow can be resolved. Use it when a missing flow is an error you want to handle.resolveSessionis the non-throwing counterpart. It walks the full fallback chain (fresh cache, live resolve with a hard timeout, stale cache, bundled default) and returnsnilwhen FlowPilot has nothing to present, at which point you render your own native UI. Use it when a missing flow is a normal no-op.
additionalContext(SDKContextis[String: Any]): values merged on top of the SDK-wide context for this session only, readable by the flow as App Parameter variables. See Variables and SDK context.preloadMedia: override the configured media preloading for this session. Defaults to the value set in Configuration. See Media preloading.
Present with the .flowPresenter modifier
FlowSession state. Setting that state to a session presents the flow full screen over your UI; when the flow ends, the SDK sets the binding back to nil and calls onResult with the FlowResult.
Embed a FlowPresenterView directly
When you want the flow inline rather than presented modally, build aFlowPresenterView from a session and place it in your hierarchy.
resolveSession, which lets you fall back to your own view when there is no flow:
FlowPresenterView starts navigation itself when it appears, so you do not call startNavigation() by hand. To learn the result when embedding, read the session’s published state (below) or await session.waitForCompletion().
Hosting in UIKit
For UIKit apps that want to host the SwiftUI presenter directly (rather than callingpresentPlacement), FlowHostingController is a public UIHostingController subclass:
presentPlacement, which uses this controller internally.
Observing FlowSession state
FlowSession is an ObservableObject. These published properties are public and useful to drive UI:
| Property | Type | Meaning |
|---|---|---|
currentScreen | ScreenNode? | The screen currently shown. currentScreen?.id and currentScreen?.name are available. nil before the first screen appears. |
isActive | Bool | true while the flow is presenting, false once it has finished. |
mediaPreloadProgress | Double | Media preload progress, 0.0 to 1.0. |
isMediaPreloaded | Bool | true once media preloading has finished (or was disabled). |
Common mistakes
- Not retaining the session. Store it in
@State(or an@StateObject-owned model), not a local variable. See the warning above. - Using
createSessionwhere a missing flow is normal.createSessionthrows, so an absent flow becomes an error path. UseresolveSession(returnsnil) when “no flow” should just fall through to your own UI. - Blocking the main thread on media preload. Preloading runs in the background. If you choose to wait for it (
session.waitForMediaPreload()), do it in aTask, and show progress withmediaPreloadProgressrather than freezing the UI. See Media preloading. - Calling
createSession/resolveSessionoff the main actor. Both are@MainActor. Call them from a.task {}, aButtonaction’sTask {}, or another main-actor context.