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

# iOS SDK

Integrate VOVE ID verification in a native iOS application.

Use the SDK version your team has tested and approved. Swift Package Manager requires Swift 5.3 or later. Run verification tests on a physical device because camera and document features are hardware-dependent.

## Install

### CocoaPods

```ruby
pod 'VoveSDK'
```

Then run:

```bash
pod install
```

Open the generated `.xcworkspace`.

### Swift Package Manager

In Xcode, choose **File → Add Package Dependencies** and add:

```
https://github.com/vove-id/vove-id-ios
```

Select the `VoveSDK` product and a dependency rule compatible with your release policy.

## Camera permission

Add a clear, user-facing reason to `Info.plist`:

```xml
<key>NSCameraUsageDescription</key>
<string>We use the camera to verify your identity.</string>
```

Request permission before launching the journey and provide a recovery path when the user denies it.

## Initialize

Initialize once with the client-safe public key:

```swift
import VoveSDK

Vove.initialize(
    publicKey: "PUBLIC_KEY",
    environment: "ENVIRONMENT"
) { result in
    switch result {
    case .success:
        print("VOVE ID initialized")
    case .failure:
        showInitializationError()
    }
}
```

Keep the public key, session token, and environment aligned. VOVE ID environments are Sandbox and Production.

## Start a verification

Retrieve the session token from your backend immediately before starting:

```swift
let configuration = VoveStartConfiguration(
    showUI: true,
    maxAttemptsActionCallback: {
        showSupportOptions()
    },
    exitAfterEachStep: false
)

Vove.start(
    sessionToken: sessionTokenFromBackend,
    configuration: configuration
) { payload in
    guard let payload else {
        showJourneyError()
        return
    }

    switch payload.result {
    case .success:
        showAwaitingServerConfirmation()
    case .pending:
        showPendingReview()
    case .failure:
        showVerificationFailed()
    case .canceled:
        showVerificationCanceled()
    case .maxAttempts:
        showSupportOptions()
    case .inProgress:
        if let nextStep = payload.nextStep {
            storeNextStep(nextStep)
        }
    }
}
```

The completion payload drives app UI only. Your backend should verify the webhook and retrieve the current KYC resource before making a final decision.

## Documented values

The verification result values are `.success`, `.failure`, `.pending`, `.canceled`, `.maxAttempts`, and `.inProgress`.

`VoveStartConfiguration` accepts `showUI`, `maxAttemptsActionCallback`, and `exitAfterEachStep`. Supported locale values are `.en`, `.fr`, `.de`, `.ar`, and `.arMA`. Use the declarations shipped with your installed SDK as the compile-time authority.

## Step-by-step journeys

Set `exitAfterEachStep` to `true` when your app needs to regain control between configured verification steps:

```swift
let configuration = VoveStartConfiguration(
    showUI: false,
    maxAttemptsActionCallback: nil,
    exitAfterEachStep: true
)

Vove.start(sessionToken: token, configuration: configuration) { payload in
    guard let payload else { return }

    if payload.result == .inProgress {
        routeToInterstepScreen(nextStep: payload.nextStep)
    }
}
```

Persist the server-side `refId`, not only the client-side next step. A new app launch should retrieve current state rather than assuming the previous callback was delivered.

## Locale and vocal guidance

```swift
Vove.setLocal(local: .fr)
Vove.setVocalGuidanceEnabled(true)
```

Supported locales are:

| Value   | Language        |
| ------- | --------------- |
| `.en`   | English         |
| `.fr`   | French          |
| `.de`   | German          |
| `.ar`   | Arabic          |
| `.arMA` | Moroccan Arabic |

Test right-to-left layouts when using `.ar` or `.arMA`, and make sure spoken guidance does not conflict with your accessibility experience.

## NFC-enabled flows

If your approved flow includes NFC document reading, add only the capabilities, entitlements, and ISO 7816 identifiers supplied for that flow. Broad or speculative entitlement declarations can delay App Store review.

## Troubleshooting

| Symptom                   | Check                                                                                                 |
| ------------------------- | ----------------------------------------------------------------------------------------------------- |
| Module cannot be imported | Confirm the package product is linked to the app target and clean Xcode's package cache if necessary. |
| Camera is unavailable     | Test on a physical device, confirm `NSCameraUsageDescription`, and inspect authorization state.       |
| Initialization fails      | Confirm the public key, session token, and environment match.                                         |
| Session immediately exits | Confirm token freshness and that it was created for the same environment.                             |
| No `nextStep` is returned | It is expected only for a step-by-step journey when another step remains.                             |

See [SDK compatibility](/docs/sdks/compatibility.md), [session creation](/docs/kyc-api/verification-session.md), and [production readiness](/docs/production-readiness.md).
