> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK

> Migrate the FlowX iOS renderer SDK from 5.1.x LTS to 5.9.x.

## iOS SDK migration guide

5.9 bumps the `FlowXRenderer` pod from the 9.x line to the 10.x line. The host-app surface that changes is small: a new mandatory `organizationId` on `FXConfig`, one breaking signature on the callback-based `startProcess`, one new case on `CustomLoaderType`, and a few additive APIs around UI Flows and process-start callbacks.

### Prerequisites and version range

| Requirement     | 5.1.x    | 5.9.x     |
| --------------- | -------- | --------- |
| `FlowXRenderer` | `~> 9.0` | `~> 10.3` |
| Minimum iOS     | iOS 15   | iOS 15    |
| Swift           | 5.9      | 5.9       |
| Xcode           | 18+      | 26+       |

### Configuration changes

#### New mandatory `FXConfig.organizationId`

5.9 introduces `organizationId` as a mandatory `FXConfig` property. It carries the FlowX-issued organization UUID. The same value used to backfill `organization_id` columns during the backend upgrade (see [License and organization configuration](./organization-deployment)).

```swift v9.x theme={"system"}
FXConfig.sharedInstance.configure { config in
    config.baseURL = myBaseURL
    config.enginePath = "engine"
    config.imageBaseURL = myImageBaseURL
    // ...
}
```

```swift v10.x theme={"system"}
FXConfig.sharedInstance.configure { config in
    config.baseURL = myBaseURL
    config.enginePath = "engine"
    config.imageBaseURL = myImageBaseURL
    config.organizationId = myOrganizationUuid
    // ...
}
```

### Breaking API changes

#### `startProcess` (workspaceId callback variant): completion signature

The `completion` closure of the navigation-agnostic `startProcess(workspaceId:projectId:...)` now receives the started process instance UUID alongside the root view controller.

```swift v9.x theme={"system"}
public func startProcess(workspaceId: String,
                         projectId: String,
                         name: String,
                         params: [String: Any]?,
                         isModal: Bool = false,
                         showLoader: Bool = false,
                         completion: ((UIViewController?) -> Void)?,
                         onProcessEnded: (() -> Void)? = nil)
```

```swift v10.x theme={"system"}
public func startProcess(workspaceId: String,
                         projectId: String,
                         name: String,
                         params: [String: Any]?,
                         isModal: Bool = false,
                         showLoader: Bool = false,
                         completion: ((UIViewController?, String) -> Void)?,
                         onProcessEnded: (() -> Void)? = nil)
```

Update the closure to accept the second argument. The UUID is an empty string if the process failed to start.

```swift theme={"system"}
FlowX.sharedInstance.startProcess(workspaceId: workspaceUuid,
                                  projectId: applicationUuid,
                                  name: processName,
                                  params: [:],
                                  isModal: true,
                                  showLoader: true) { rootViewController, processInstanceUuid in
    // present rootViewController; persist processInstanceUuid if you need to resume later
}
```

The other two `startProcess` variants (`navigationController:` and `tabBarController:`) keep the same shape. They only gain an optional `onProcessStarted` callback, which has a default of `nil` and is non-breaking.

#### `CustomLoaderType`: new `.upload` case

A fourth case is added to the enum returned by `FXDataSource.customLoader(type:)`.

```swift v9.x theme={"system"}
public enum CustomLoaderType {
    case startProcess
    case reloadProcess
    case action(String?)
}
```

```swift v10.x theme={"system"}
public enum CustomLoaderType {
    case startProcess
    case reloadProcess
    case action(String?)
    case upload(String?)
}
```

Exhaustive `switch` statements on `CustomLoaderType` stop compiling until `.upload` is handled. Return `nil` to keep the built-in upload loader, or return a custom view to override it.

```swift theme={"system"}
func customLoader(type: CustomLoaderType) -> AnyView? {
    switch type {
    case .startProcess:        return AnyView(MyStartProcessLoader())
    case .reloadProcess:       return AnyView(MyReloadLoader())
    case .action(let name):    return AnyView(MyActionLoader(actionName: name))
    case .upload(let name):    return AnyView(MyUploadLoader(actionName: name))
    }
}
```

The associated `String?` on `.upload` is the upload action name as configured in the process definition.

### App-side migration steps

<Steps>
  <Step title="Bump the pod">
    In your `Podfile`, point `FlowXRenderer` to the version shipped with 5.9 (see *Release Notes → 5.9 Deployment guidelines → Component versions*) and run `pod install`:

    ```ruby theme={"system"}
    pod 'FlowXRenderer', '~> <version>'  # see Release Notes → 5.9 Deployment guidelines
    ```
  </Step>

  <Step title="Set organizationId in FXConfig">
    In the existing `FXConfig.sharedInstance.configure { ... }` block, set `config.organizationId` to your FlowX-issued organization UUID. Apply this before starting the first FlowX session.
  </Step>

  <Step title="Update startProcess call sites">
    For every call to `FlowX.sharedInstance.startProcess(workspaceId:projectId:...)`, update the trailing `completion` closure to accept `(UIViewController?, String)` instead of `(UIViewController?)`.
  </Step>

  <Step title="Handle the new CustomLoaderType.upload case">
    In each `FXDataSource.customLoader(type:)` implementation, add a branch for `.upload(let actionName)`. Return `nil` to keep the default loader.
  </Step>

  <Step title="Rebuild and run">
    `pod install` then a clean build (`Cmd+Shift+K`, then `Cmd+B`). Resolve any remaining type-mismatch warnings the compiler surfaces around the two changed signatures.
  </Step>
</Steps>

### Verification

<Check>
  Start a process from the host app and confirm the `completion` closure receives a non-empty `processInstanceUuid`. Persist it, kill the app, and resume with `FlowX.sharedInstance.continueExistingProcess(uuid:name:...)`. The previously running task should reopen at the correct screen.
</Check>

<Check>
  Trigger a file upload action on a screen that exposes one. With a custom loader registered, confirm `.upload(actionName)` is hit (e.g. by setting a breakpoint or logging the case). Without a custom loader, confirm the built-in upload spinner appears.
</Check>

## New capabilities

These are additive in 5.9; existing 5.1 integrations keep working without adopting them. See the [iOS SDK reference](/5.9/sdks/ios-renderer) for full signatures and samples.

* **UI Flows**. `FlowX.sharedInstance.startUIFlow(workspaceId:projectId:name:params:isModal:showLoader:completion:)` starts a UI Flow defined in the FlowX Designer. UI Flows run client-side over a data model and do not require a BPMN process instance on the engine.
* **`onProcessStarted` callback**. `startProcess(navigationController:)` and `startProcess(tabBarController:)` accept an optional `onProcessStarted: ((String) -> Void)?` that fires with the new process instance UUID once the engine has accepted the start request.

## Related resources

<CardGroup cols={2}>
  <Card title="iOS SDK reference" icon="apple" href="/5.9/sdks/ios-renderer">
    iOS renderer SDK documentation
  </Card>

  <Card title="Migration overview" icon="arrow-up-right-from-square" href="./overview">
    Full 5.1.x LTS → 5.9.x upgrade guide
  </Card>
</CardGroup>
