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

# iOS

> Install the Legal Talent SDK with Swift Package Manager and present the KYC flow

## Requirements

* iOS 15 or later
* Xcode 16 or later
* A physical device for capture steps: the simulator can load the flow but cannot use the camera

## 1. Get access to the package

The SDK is distributed from a private GitHub repository while in partner beta. Ask your Legal Talent contact to add your GitHub users to the partner team, then authenticate Xcode with a **classic** personal access token with `repo` (read) scope:

<Tabs>
  <Tab title="Xcode">
    Xcode → Settings → Accounts → **+** → GitHub, and paste the token.
  </Tab>

  <Tab title="~/.netrc (CI)">
    ```
    machine github.com
      login YOUR_GITHUB_USERNAME
      password ghp_...
    ```

    With `xcodebuild`, add `-scmProvider system` so it uses these credentials.
  </Tab>
</Tabs>

## 2. Add the package

File → Add Package Dependencies, then enter:

```
https://github.com/legal-talent/legaltalent-ios
```

Or in `Package.swift`:

```swift theme={null}
dependencies: [
    .package(url: "https://github.com/legal-talent/legaltalent-ios", from: "0.1.0")
]
```

Link `LegalTalentUI` for the drop-in flow, or `LegalTalentCore` for a headless integration.

## 3. Declare permissions

Add to your app's `Info.plist` the keys for the features your workflows use:

| Key                                         | When                                           |
| ------------------------------------------- | ---------------------------------------------- |
| `NSCameraUsageDescription`                  | Always (document capture, selfie, liveness)    |
| `NSPhotoLibraryUsageDescription`            | If document upload from the gallery is enabled |
| `NFCReaderUsageDescription` + ISO 7816 AIDs | Only if you read eMRTD chips                   |

## 4. Create a session on your backend

Your backend creates the session with its API key and returns only the `access_token` to the app:

```bash theme={null}
curl -X POST https://kyc.legaltalent.ai/kyc/sessions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "YOUR_WORKFLOW_ID",
    "client_id": "your-internal-user-id"
  }'
```

Return `data.access_token` to the app. See [Create Session](/api-reference/sessions#create-session) for every parameter.

<Warning>
  Never call `POST /kyc/sessions` from the app, and never embed the API key in the binary.
</Warning>

## 5. Present the flow

```swift theme={null}
import LegalTalentUI
import SwiftUI

struct OnboardingView: View {
    let accessToken: String
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        LegalTalentFlowView(
            accessToken: accessToken,
            environment: .production,
            onExit: { dismiss() },
            onComplete: { session in
                // The applicant finished. The decision arrives on your backend.
                dismiss()
            }
        )
    }
}
```

<Note>
  `environment` defaults to `.dev`. Always pass it explicitly: `.staging` while you integrate, `.production` when you go live. The token must come from the same environment.
</Note>

Present it however your app navigates: a `fullScreenCover`, a pushed view, or a hosting controller in UIKit:

```swift theme={null}
let flow = LegalTalentFlowView(accessToken: token, environment: .production, onComplete: { _ in })
present(UIHostingController(rootView: flow), animated: true)
```

## 6. Handle the result

`onComplete` fires once, after the last step is submitted. Treat it as a UX signal:

1. Dismiss the flow and show a "verification in progress" screen.
2. Wait for your backend to receive [`kyc.session.processed`](/api-reference/webhooks/sessions) (or the manual `approved` / `rejected` events), or poll [`GET /kyc/sessions/{id}`](/api-reference/sessions#get-session-details) from your backend.
3. Update the app from your backend's state.

If the applicant closes the flow, `onExit` fires after a confirmation dialog. The session stays open until it expires, so you can present the flow again with the same token and the applicant resumes where they left off.

## Headless

For a custom UI, use `LegalTalentClient` directly:

```swift theme={null}
import LegalTalentCore

let client = LegalTalentClient(accessToken: accessToken, environment: .production)
let session = try await client.getSession()
let workflow = try await client.getWorkflow()
```

The client maps the [public session API](/api-reference/sessions-public): uploads, step completion and polling. Errors are thrown as `LegalTalentError`; see [Reference](/mobile-sdk/reference#errors).

## Localize the liveness screens

The face-liveness detector is rendered by AWS Amplify, which ships English only. To show it in Spanish or Portuguese, copy the `en.lproj`, `es.lproj` and `pt.lproj` folders from `liveness-strings/` in the SDK repository into your app target and list `es` and `pt` as app localizations. See [Customization](/mobile-sdk/customization#liveness-screens).
