FlowResult when the user finishes.
All of the present methods are declared @MainActor, so call them from the main actor (for example from a view controller method, inside a Task {}). They are only available where UIKit is (#if canImport(UIKit)); for SwiftUI, see SwiftUI integration.
The SDK must be configured first.
FlowPilot.shared is nil until you call FlowPilot.configure(_:) at launch. See Configuration.The three present overloads
FlowPilot exposes three presentPlacement overloads. They all resolve and present the same way; they differ in how they hand back the result and how they behave when there is no flow.
Awaited result (throws)
FlowPilotError when no flow could be resolved (no default flow, audience mismatch, offline with no cache, and so on), so wrap it in do/catch.
Callback variant (throws)
FlowResult is delivered to completion after the flow dismisses instead of being returned. You still try await the call.
Never-throws fallback variant
resolveTimeout, then stale cache, then a bundled default flow). If none of those produce a presentable flow, it presents the view controller you return from fallback (your app’s own native onboarding) instead. The fallback closure runs on the main actor.
When it has to fall back to your view controller, the returned FlowResult has outcome == .error and a populated error. This is the resilient choice for onboarding, because integrating FlowPilot can never leave the user on a blank screen. See the fail-safe fallback chain.
Presentation options
Pass aPresentationOptions to add per-presentation context or turn off the present animation.
additionalContext(SDKContextis[String: Any]) is merged on top of the SDK-wide context for this presentation only. Use it to pass values the flow can read as App Parameter variables (for example which button opened a paywall). See Variables and SDK context.animatedcontrols whether the modal present and dismiss are animated. Defaults totrue.
Example
Present fromviewDidAppear, inside a Task, with all three styles shown.
Common mistakes
- Calling off the main thread. The present methods are
@MainActor. Call them from the main actor (UIKit lifecycle methods already run there). A backgroundTaskthat calls them without hopping to the main actor will not compile cleanly or will assert. - Not awaiting the call.
presentPlacementisasync. Wrap it in aTask {}andawaitit; do not call it and walk away. - Presenting before
configure.FlowPilot.sharedisniluntilFlowPilot.configure(_:)runs. GuardFlowPilot.sharedor your call is a silent no-op. - Not handling the “no flow” case. The throwing overloads throw when there is nothing to show. Either
catchit, use thefallback:overload, or checkisPlacementReadyfirst. - Expecting
presentationStyleto change the modal. It does not (see the warning above). Flows present full screen today.
Troubleshooting
The throwing overloads threw, or the fallback overload returned.error:
See Error handling for every error code.