> For the complete documentation index, see [llms.txt](https://docs.caf.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.caf.io/caf-sdk/ios/standalone-modules/caffacelivenesslite/start-sdk.md).

# Start Liveness Verification

Quick links: [Overview](/caf-sdk/ios/standalone-modules/caffacelivenesslite.md) | [Building the SDK](/caf-sdk/ios/standalone-modules/caffacelivenesslite/builder.md) | [Start Liveness Verification](/caf-sdk/ios/standalone-modules/caffacelivenesslite/start-sdk.md) | [UI Customization](/caf-sdk/ios/standalone-modules/caffacelivenesslite/ui-customization.md) | [Installation](/caf-sdk/ios/standalone-modules/caffacelivenesslite/installation.md) | [Current Version](/caf-sdk/ios/standalone-modules/caffacelivenesslite/current-version.md) | [Requirements](/caf-sdk/ios/standalone-modules/caffacelivenesslite/requirements.md) | [Source Code](/caf-sdk/ios/standalone-modules/caffacelivenesslite/source-code.md) | [Result Reference](/caf-sdk/ios/standalone-modules/caffacelivenesslite/result-reference.md) | [Release Notes](/caf-sdk/ios/standalone-modules/caffacelivenesslite/release-notes.md) | [FAQ](/caf-sdk/ios/standalone-modules/caffacelivenesslite/faq_caf_face_liveness_sdk.md)

From **3.0.0** the flow has three steps: configure once with `setup`, optionally `prewarm` the session, then `startSDK` to present the capture screen.

{% hint style="warning" %}
**Breaking in 3.0.0:** configuration moved from `startSDK` to `setup`. The old `startSDK(viewController:mobileToken:personId:…)` overload was removed — existing calls will not compile. See the [migration guide](/caf-sdk/ios/standalone-modules/caffacelivenesslite/release-notes.md).
{% endhint %}

## Configuring with setup

Call `setup` before starting. It only stores your configuration — it performs no network request and presents nothing.

| Parameter                                 | Required | Description                                                                 |
| ----------------------------------------- | -------- | --------------------------------------------------------------------------- |
| `mobileToken: String`                     | Yes      | Usage token associated with your CAF account                                |
| `personId: String`                        | Yes      | User identifier                                                             |
| `customLocalization: String?`             | No       | Strings table name for custom iProov localization (e.g., "stringsBundle")   |
| `customLocalizationBundle: Bundle?`       | No       | Bundle containing the custom strings table (iProov `options.stringsBundle`) |
| `uiCustomization: CerttaUiCustomization?` | No       | Visual branding for the liveness screen (default: `nil`, no customization)  |
| `environment: CafEnvironment`             | No       | `.dev`, `.beta`, `.prod` (default: `.prod`)                                 |
| `loading: Bool`                           | No       | Show SDK loading screen (default: `true`)                                   |

You can call `setup` again to change any value — for example to switch `personId` between users. Doing so discards a previously prewarmed session whenever the credentials or environment differ.

## Prewarming the session (optional)

`prewarm()` performs the session request ahead of time so `startSDK` can open the camera without waiting on the network. Call it at any point where the user is already occupied — an instructions screen, a consent step, a form — and the round trip overlaps with their reading time instead of adding to it.

```swift
sdk.setup(mobileToken: "your_mobile_token", personId: "your_person_id")
sdk.prewarm()                       // e.g. when the instructions screen appears
// … user reads the instructions …
sdk.startSDK(viewController: self)  // consumes the prewarmed session
```

`prewarm()` returns immediately and reports nothing: it has no completion handler and never invokes the delegate. It is safe to call from any thread and safe to call more than once — while a request is in flight, or while a valid session is already cached, it does nothing rather than requesting a second session.

**Prewarming is always optional and can never break a capture.** If no valid session is available when `startSDK` runs — because prewarming failed, was never called, or the cached session is no longer usable — the SDK silently falls back to requesting the session inline, exactly as it did before 3.0.0.

A prewarmed session is discarded when:

| Condition                          | Detail                                                                                                     |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| It is older than **90 seconds**    | Start the capture within that window to benefit from prewarming                                            |
| Credentials or environment changed | A later `setup` with a different `mobileToken`, `personId` or `environment` invalidates it                 |
| The app was sent to the background | The cached session and the stored credentials are cleared                                                  |
| It was already used                | Each prewarmed session is consumed by a single `startSDK` call; call `prewarm()` again for another capture |

Two behaviors worth noting when you integrate:

* **No `loading()` / `loaded()` pair is emitted for the session request on the prewarmed path**, since there is nothing to wait for. From **3.1.0** none is emitted after the capture either, because the result is delivered immediately. Do not rely on `loading()` as a signal that capture has begun.
* `prewarm()` stores the mobile token and person ID in the keychain before issuing the request, because the request is authenticated from the keychain. They are removed if prewarming fails or the app is backgrounded.

## Calling startSDK

`startSDK` presents the capture screen using the configuration supplied to `setup`. It takes only the presenting view controller. Call it on the main thread.

| Parameter                          | Required | Description                    |
| ---------------------------------- | -------- | ------------------------------ |
| `viewController: UIViewController` | Yes      | The presenting view controller |

Calling `startSDK` without a prior `setup` does not present anything — it reports `didFinishWithError(type: .invalidOptionsException, description:)` instead. See [Result Reference](/caf-sdk/ios/standalone-modules/caffacelivenesslite/result-reference.md).

{% hint style="warning" %}
**Breaking in 2.0.0:** `executeFaceAuth` was removed. The SDK starts an async transaction and returns only `signedResponse`. Retrieve the final liveness outcome from your backend.
{% endhint %}

### Example

```swift
import CafFaceLivenessLite

class ViewController: UIViewController {
    private let sdk = CafFaceLivenessLiteSDK()

    override func viewDidLoad() {
        super.viewDidLoad()
        sdk.delegate = self

        sdk.setup(
            mobileToken: "your_mobile_token",
            personId: "your_person_id",
            customLocalization: nil,
            customLocalizationBundle: nil,
            environment: .prod,
            loading: true
        )
        sdk.prewarm()
    }

    func startLiteLiveness() {
        sdk.startSDK(viewController: self)
    }
}
```

### Custom localization with a framework bundle

When custom `Localizable.strings` ship inside a framework (or another non-main bundle), pass both the table name and the bundle:

```swift
sdk.setup(
    mobileToken: "your_mobile_token",
    personId: "your_person_id",
    customLocalization: "Localizable",
    customLocalizationBundle: Bundle(for: CafFaceLivenessLiteSDK.self),
    environment: .prod,
    loading: true
)
sdk.startSDK(viewController: self)
```

Localization reference: [iProov Localization](https://github.com/iProov/ios/wiki/Localization)

### UI customization

To brand the liveness screen — header bar, guidance prompt, area around the face oval and font — pass a `CerttaUiCustomization` through the `uiCustomization` parameter of `setup`. Available from **2.1.0** and fully optional. See [UI Customization](/caf-sdk/ios/standalone-modules/caffacelivenesslite/ui-customization.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.caf.io/caf-sdk/ios/standalone-modules/caffacelivenesslite/start-sdk.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
