Skip to main content

Installation

Prerequisites​

Before integrating the Flex Checkout iOS SDK, ensure your project meets the following requirements:

  • iOS 12.0+
  • Swift 5.9+
  • Xcode 15+
  • SwiftUI-based app (UIKit hosting is also supported)
info

The SDK can be integrated into iOS 12+ projects without build issues. However, checkout functionality requires iOS 13 or later — on iOS 12, opening checkout will invoke your onError callback with a message indicating the version requirement. The SwiftUI FlexSplitRentButton component also requires iOS 13+.


Swift Package Manager​

Add the Flex Checkout iOS SDK as a dependency in your Package.swift:

Swift
dependencies: [
.package(url: "https://github.com/flexapp/flex-checkout-ios.git", from: "1.6.0")
]

Or add it through Xcode:

  1. Go to File > Add Package Dependencies...
  2. Enter the repository URL: https://github.com/flexapp/flex-checkout-ios
  3. Select the version and add it to your target.

CocoaPods​

Alternatively, add the SDK to your Podfile:

RUBY
pod 'FlexCheckout', '~> 1.6.0'

Then run:

Bash
pod install

Initializing the SDK​

Initialize the Flex SDK once at app startup by calling Flex.initialize(config:) with a FlexConfig object. The SDK is a singleton — call this once, typically in your app delegate or top-level initialization code.

Swift
import FlexCheckout

let sdk = Flex.initialize(config: FlexConfig(
clientId: "your-flex-client-id",
environment: .int // use .prod for production
))
info

You can access the initialized SDK instance anywhere in your app via Flex.instance.

warning

Flex.initialize(config:) raises fatalError("FlexConfig.clientId must not be empty") immediately if clientId is empty — your app will crash. Ensure your clientId is set before calling initialize(config:).

FlexConfig Fields​

ParameterTypeDescription
clientIdStringRequired The client id provided by Flex which identifies your Flex client.
environmentFlexEnvironmentThe environment to use — either .int (testing) or .prod (production). Defaults to .int.
developerFlexDeveloperConfig?Developer tool configuration options. Only takes effect in non-production environments.

Developer Tools​

The optional developer field can be configured to enable verbose logging for debugging.

Swift
let sdk = Flex.initialize(config: FlexConfig(
clientId: "your-flex-client-id",
developer: FlexDeveloperConfig(logs: true)
))

Developer Fields​

Fields for the developer object.

ParameterTypeDescription
logsBoolDisplays informative logs for debugging the Flex iOS SDK in your Xcode console.

Environments​

There are only two environments for you to use:

EnvironmentUse it forDescription
.intTestingIntegration / sandbox environment. Use it for all development and testing.
.prodProductionProduction environment. Use it only for live, production traffic.
warning

.int and .prod are the only environments supported for partner integrations. Any other case on the FlexEnvironment enum is reserved for Flex-internal use and must not be used.


Token​

loadToken takes an async closure that the SDK calls to fetch a token from your backend.

Swift
sdk.loadToken {
let response = try await yourApi.getFlexToken()
return response.token
}
warning

loadToken must be called before checkout can be opened. The SDK will throw a FlexError.noTokenLoader error if no token provider has been registered.


Lifecycle Management​

User state (form input, scroll position, partial flow progress) is preserved across opens — if a user starts onboarding, closes the sheet, and reopens, they resume right where they left off.

Backgrounding the app and returning to it is also handled automatically — if checkout was open when the user switched away, it's re-shown in the same state when they return. You don't need to wire anything up in scenePhase.

Cleanup​

Call cleanup only when the user signs out of your app. The SDK's WebView retains the previous user's in-flight UI state (form input, partial flow, cached client-side data), so if the next user signs in without cleanup, they would land into the previous user's session inside the WebView. Calling cleanup on sign-out wipes that state.

Swift
func signOut() {
Flex.instance.cleanup()
// ...your sign-out logic
}

After cleanup, the SDK rebuilds itself the next time the user opens checkout — you do not need to call Flex.initialize again.

warning

Do not call cleanup from scenePhase background handlers, from a view's .onDisappear, or whenever the user navigates away from your checkout screen. Doing that loses the user's in-progress checkout state every time they re-enter — they'd have to restart onboarding from the beginning.

For most apps the sign-out hook is the only place cleanup is needed.


Analytics​

logImpression(data:)​

Logs an impression event when the Flex checkout entry point (button, screen, etc.) becomes visible to the user. Call this from onAppear or whenever the checkout entry point appears on screen.

Swift
Flex.instance.logImpression(data: [
"residentId": "xyz",
"propertyId": "prop-12345",
"placement": "homepage",
"element": "split_rent_button",
])

Recommended fields for impression data:

ParameterTypeDescription
residentIdStringid associated with the resident.
propertyIdStringid associated with the property.
placement"homepage"
"payments"
"checkout"
Where the user interaction takes place in your portal.
element"split_rent_button"
"learn_more"
"awareness_banner"
Element displayed for the interaction.

Error Reference​

Setup​

Flex.initialize raises fatalError("FlexConfig.clientId must not be empty") if clientId is blank. There are no other setup-time errors; everything else surfaces via onError at runtime.

Runtime (onError messages)​

The onError checkout callback receives a descriptive String whenever something goes wrong. For load failures, the SDK already displays its own retry UI inside the sheet (see Checkout → Error Handling) — these messages are for your logging and analytics.

MessageWhen it occurs
"No token loader provided. Call loadToken() before opening checkout."openCheckout invoked before loadToken was registered
"FlexCheckout not configured — call Flex.initialize first."openCheckout invoked before Flex.initialize
"Flex checkout host not ready. Try again momentarily."openCheckout invoked at app launch before the SDK's host has attached to the active scene
"Checkout is temporarily unavailable. Please try again later."Flex kill-switch is active for your client
"Checkout failed to load: <reason>"WebView load, JS handshake, or token loader failed — SDK shows its own retry UI in the sheet

For "Checkout failed to load: <reason>", the <reason> suffix is one of:

  • "The Internet connection appears to be offline." — no network (NSURLError -1009)
  • "Checkout did not load in time" — 15-second JS handshake timeout
  • "Failed to load token: <your loader's error>" — your loadToken closure threw
  • "Token loader returned an empty token" — your loadToken closure returned ""
Swift
sdk.checkout(CheckoutConfig(
onError: { error in
// Log + report — the SDK already shows the user-facing error UI.
analytics.track("flex_checkout_error", properties: ["message": error])
}
))

Next Steps​

Now that the SDK is installed and configured: