Getting started / Platform support
Platform support
One renderer, written once in Swift. Everything below follows from that.
| Platform | Status | How |
|---|---|---|
| iOS, native | Shipped | Swift package, SwiftUI, iOS 16+ |
| iOS, Flutter | Shipped | uplift_funnel_flutter, which hosts the Swift engine |
| Android | Not yet | What happens today |
| React Native | Not yet | What exists today |
| Web | Not planned | The editor's preview is web; the product is not |
Why the Flutter SDK is iOS-only
The renderer is one Swift engine. The Flutter package does not reimplement it in Dart — it hosts it, so a Flutter app and a native app draw the same document with the same code and cannot drift. That is the whole reason the two agree pixel for pixel, and it is also why there is no Android target: there is no engine there to host.
What happens off iOS
Nothing silent. UpliftFunnel.isSupported is false, and every SDK call throws UpliftFunnelUnsupportedPlatform rather than pretending to work.
// Every SDK call throws this off iOS rather than silently doing nothing.
try {
await UpliftFunnel.configure(apiKey: 'fnl_pk_…');
} on UpliftFunnelUnsupportedPlatform {
// Android, web, desktop.
}A rendered flow is not something to fall back from mid-way, so guard at the call site — decide once, before you present anything:
// The Swift package is iOS-only; there is nothing to guard on iOS itself.
// If you share a codebase with macOS or watchOS targets, keep the flow
// behind the platform check you already have.
#if os(iOS)
UpliftFunnelFlowView(flowKey: "welcome") { result in save(result.variables) }
#endif// One check, at the call site. Do not present a flow you cannot render.
if (UpliftFunnel.isSupported) {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const OnboardingPage()),
);
} else {
// Your own onboarding, or straight into the app.
Navigator.of(context).pushReplacementNamed('/home');
}UpliftFunnelFlow also takes an unsupportedBuilder for the case where the widget is already in the tree. Left out, it renders nothing — an empty box rather than a crash — but a host that reaches that has usually skipped the check above.
Analytics and the dashboard
Everything except rendering is platform-neutral: the API, the editor, experiments and analytics do not care where a flow ran. What you will not see is data from platforms that cannot render one, because no session ever starts there.