# Installation

This page covers everything you need to add the Incode iOS SDK to your project. It covers build requirements, variant versioning, distribution channels, On-Demand Resources, required permissions, NFC entitlements, the privacy manifest, initializing the SDK, and enabling test mode.

***

## Build Requirements

Ensure your build environment meets the following minimum requirements:

- **iOS deployment target**: 13.0.
- **Swift language mode**: 5.0 (`SWIFT_VERSION = 5.0`).
- **Xcode**: 15.0 or higher.
- **Swift Package Manager**: If used, SSH/Git credentials configured for authentication to the distribution repo.
- **CocoaPods**: 1.15+, if you're installing via CocoaPods. You must also have SSH access to the private specs repository.

Also, ensure your devices meet the [device requirements](https://developer.incode.com/docs/ios-sdk#device-requirements). Then complete the following steps in order.

***

## Format a Variant Version

The Incode iOS SDK ships in [build variants](https://developer.incode.com/docs/ios-sdk#distribution-and-variants). A variant is a linking type plus a set of optional features. Not every module is compiled into every variant, and calling an API for a feature that is not included triggers a runtime variant assertion. Pin the **exact variant version**; there is no Bill of Materials. Choose the smallest variant that includes the features your flow needs to keep binary size down.

```
MAJOR.MINOR.PATCH-LinkingType[-Feature…]
```

- `LinkingType` is `d` (dynamic, default) or `s` (static).
- Features are appended as suffixes: `vc`, `l`, `m`, `nfc`, `ra`, `sna`, `tri`.

Examples: `5.31.0-d` (dynamic), `5.31.1-d-l` (dynamic + login), `5.31.0-s` (static).

***

## Choose a Distribution Channel

The Incode iOS SDK is distributed as `IncdOnboarding.xcframework` through three channels: Swift Package Manager, CocoaPods, or a manual binary. Pick the channel that matches your project's dependency management setup. Use the exact [variant version string](#format-a-variant-version) for whichever method you choose.

### Install via Swift Package Manager

Add the distribution package and pin the exact variant version:

```
https://github.com/Incode-Technologies-Example-Repos/IncdOnboarding-distribution.git
```

1. In Xcode, go to **File** > **Add Package Dependencies**.
2. Paste the URL above.
3. Select the version matching your variant: for example, `5.31.1-d`.

### Install via CocoaPods

The pods are published to a private specs repo. Reference both the specs source and the pod with the variant version.

1. Add the specs source and the pod to your `Podfile`:
   ```ruby
   source 'git@github.com:Incode-Technologies-Example-Repos/IncdDistributionPodspecs.git'
   source 'https://cdn.cocoapods.org/'

   target 'YourApp' do
     use_frameworks!
     pod 'IncdOnboarding', '5.31.0-d'
   end
   ```

2. Run:
   ```sh
   pod install
   ```

### Embed the Binary Manually

1. Download `IncdOnboarding.xcframework` for your variant.
2. Drag it into your target and set it to **Embed & Sign**.
3. For video variants (`-vc`), also add the required `OpenTok` dependency at the version pinned for your SDK release. Verify the exact OpenTok version for the release you integrate.

***

## Manage On-Demand Resources (ODR)

The static variant can download its ML resources at runtime instead of bundling them, reducing app size. ODR requires the static variant; the dynamic variant bundles resources in the framework.

1. Check whether resources are already available:
   ```swift
   let manager = IncdOnboardingManager.shared

   manager.checkOnDemandResourcesAvailablity { available in
       guard !available else { return }
   		// proceed to download below
   }
   ```

2. Download the resources if they're not available:
   ```swift
       manager.downloadOnDemandResources(
           showUI: true,
           vc: self, // required when showUI is true, otherwise the download UI is not shown
           onProgress: { progress in /* 0.0…1.0 */ },
           onCompleted: { /* ready */ },
           onError: { error in /* handle */ }
       )
   ```
   `downloadOnDemandResources` parameters:
   | Parameter     | Type                  | Default | Notes                                                                           |
   | ------------- | --------------------- | ------- | ------------------------------------------------------------------------------- |
   | `showUI`      | `Bool?`               | `nil`   | Show the built-in downloading UI. When `true`, `vc` must also be set.           |
   | `vc`          | `UIViewController?`   | `nil`   | Parent view controller for the downloading UI. Only used if `showUI` is `true`. |
   | `onProgress`  | `((Double) -> Void)?` | `nil`   | Called as progress changes, from `0.0` to `1.0`.                                |
   | `onCompleted` | `(() -> Void)?`       | `nil`   | Called when the download completes or resources are already present.            |
   | `onError`     | `((Error) -> Void)?`  | `nil`   | Called when an error occurs.                                                    |

3. Free disk space when you're done with the resources:
   ```swift
   manager.removeOnDemandResources()
   ```

***

## Add Required Permissions

Add the following usage-description keys to your `Info.plist` for the modules your flow uses. iOS rejects the app at runtime and in App Review if a capability is used without its key.

| Key                                   | Required For                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NSCameraUsageDescription`            | [ID Capture](https://developer.incode.com/docs/module-id-scan), [Selfie](https://developer.incode.com/docs/module-selfie), [Face Authentication](https://developer.incode.com/docs/module-face-authentication), [QR Scan](https://developer.incode.com/docs/module-qr-scan), [Video Conference](https://developer.incode.com/docs/module-conference), and [Video Selfie](https://developer.incode.com/docs/module-video-selfie) |
| `NSMicrophoneUsageDescription`        | [Video Conference](https://developer.incode.com/docs/module-conference); [Video Selfie](https://developer.incode.com/docs/module-video-selfie) when audio or voice consent is enabled                                                                                                                                                                                                                                                                                                   |
| `NSLocationWhenInUseUsageDescription` | [Geolocation](https://developer.incode.com/docs/module-geolocation)                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `NFCReaderUsageDescription`           | [NFC](https://developer.incode.com/docs/module-nfc-scan)                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `NSPhotoLibraryAddUsageDescription`   | Saving captured images to the photo library                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

Example:

```xml
<key>NSCameraUsageDescription</key>
<string>We use the camera to capture your ID and a selfie for identity verification.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We use the microphone to record your voice consent.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We use your location to verify your address.</string>
```

Provide your own wording. These strings are shown in the system permission prompt.

***

## Enable NFC Entitlements (`-nfc` variant only)

For NFC reading, enable the **Near Field Communication Tag Reading** capability and declare the ISO 7816 application identifiers the SDK reads. For example:

```
A0000002471001
A0000002472001
00000000000000
```

The NFC module reads e-passport chips using AES/3DES (DESede) secure messaging; see [Security](https://developer.incode.com/docs/ios-security#nfc).

***

## Ship the Privacy Manifest (`PrivacyInfo.xcprivacy`)

The SDK ships a privacy manifest. It declares no tracking (`NSPrivacyTracking = false`) and the following collected data types, all linked to the user and used for app functionality (not tracking):

- Name
- Phone number
- Physical address
- Precise location
- Photos or videos
- User ID
- Device ID

Declared required-reason API usage:

- `NSPrivacyAccessedAPICategoryUserDefaults`: Reason `1C8F.1` (SDK preference storage)
- `NSPrivacyAccessedAPICategoryFileTimestamp`: Reasons `C617.1`, `3B52.1` (resource validation/TRI)

When you submit your app, make sure your app-level privacy disclosures on App Store Connect are consistent with the data your chosen flow collects.

***

## Initialize the SDK

Initialize the SDK once, early in the app lifecycle. The idiomatic place is `application(_:didFinishLaunchingWithOptions:)` in your `AppDelegate`, or your SwiftUI `App` startup. Call `initIncdOnboarding` on the shared manager:

```swift
import IncdOnboarding

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
    IncdOnboardingManager.shared.initIncdOnboarding(
        url: "<YOUR_API_URL>",
        apiKey: "<YOUR_API_KEY>"
    ) { success, error in
        // `success` is `true` once the SDK is ready; `error` is an `IncdInitError` on failure.
    }
    return true
}
```

- `url`: Your Incode API base URL, provided by Incode.
- `apiKey`: Your API key, provided by Incode.
- `e2eeURL`: An optional separate endpoint for [end-to-end encryption](https://developer.incode.com/docs/ios-security#end-to-end-encryption-e2ee).
- `clientExperimentId`: An optional A/B experiment identifier.
- `loggingEnabled`: SDK diagnostic logging. Defaults to `true`; set to `false` to disable logs.
- `testMode`: Run against simulators. Defaults to `false`; see [Enable Test Mode](#enable-test-mode).

The trailing completion closure reports `(Bool?, IncdInitError?)`. You can only make SDK API calls after initialization succeeds.

In `-tri` builds, an additional overload accepts a `triConfiguration: IncdTRIConfiguration?` parameter before the completion closure. This parameter sets the Transactional Risk Intelligence (TRI) variant configuration.

```swift
public func initIncdOnboarding(
    url: String? = nil,
    e2eeURL: String? = nil,
    apiKey: String? = nil,
    clientExperimentId: String? = nil,
    loggingEnabled: Bool = true,
    testMode: Bool = false,
    _ completion: ((Bool?, IncdInitError?) -> Void)? = nil
)

public func initIncdOnboarding(
    url: String? = nil,
    e2eeURL: String? = nil,
    apiKey: String? = nil,
    clientExperimentId: String? = nil,
    loggingEnabled: Bool = true,
    testMode: Bool = false,
    triConfiguration: IncdTRIConfiguration? = nil,
    _ completion: ((Bool?, IncdInitError?) -> Void)? = nil
)
```

### Initialize with an External Token

You can key a session to an identifier from your own system rather than relying only on a session token. On iOS, this is expressed as two properties on `IncdOnboardingSessionConfiguration`:

```swift
let session = IncdOnboardingSessionConfiguration(
    externalId: "<YOUR_EXTERNAL_ID>"
)
```

- `externalId`: An ID used outside the Incode Platform. If a session with the same `externalId` already exists, it is resumed instead of creating a new one.
- `externalCustomerId`: Similar to `externalId`, but always creates a new session instead of resuming.

Pass the configuration when you start a flow. See [Integration Approaches](https://developer.incode.com/docs/ios-flow-configuration).

### Check Initialization

```swift
let status = IncdOnboardingManager.shared.isSDKEntierlyInitialized
if !status.flag { print(status.error?.description ?? "") }
```

The "Entierly" spelling is the real, shipping property name.

This verifies init, resource availability, and jailbreak state.

***

## Enable Test Mode

Test Mode lets you run the SDK on the iOS Simulator during development. Enable it by passing `testMode: true` to `initIncdOnboarding`:

```swift
IncdOnboardingManager.shared.initIncdOnboarding(
    url: "<YOUR_API_URL>",
    apiKey: "<YOUR_API_KEY>",
    testMode: true // enable Test Mode for Simulator runs
)
```

`testMode` defaults to `false`. Set it to `true` only to run on simulators during development.

<Callout icon="❗" theme="error">
  ### **Warning**

  Remove `testMode: true` (or set it back to `false`) before you build for production. Test Mode is for development only.
</Callout>

***

## What's Next

Choose your [integration approach](https://developer.incode.com/docs/ios-flow-configuration).
