## Variant Explanation  
The SDK is published as `@incode-sdks/react-native-incode-sdk`. Pick the version suffix that matches your feature set.

| Variant | Example dependency | Use when you need |
| --- | --- | --- |
| Standard | `"[VERSION]"` | Base onboarding modules. |
| Streaming | `"[VERSION]-vc"` | Camera frame streaming for ID/Selfie capture. |
| Face Login | `"[VERSION]-l"` | `startFaceLogin()` and locally stored identity flows. |
| NFC | `"[VERSION]-nfc"` | `NFCScan` and NFC-based face match flows. |

## Environment Setup

### Requirements  
- React Native app with Android and/or iOS targets.
- Xcode 15.0.1+.
- Swift 5.5+.
- CocoaPods 1.11+.
- iOS 13+.
- Android `minSdkVersion` 23+; use 24+ when using the video-streaming dependency.
- Android `compileSdkVersion` 35+.

## Installation  
Install the standard package:

Shell

```shell
npm i @incode-sdks/react-native-incode-sdk
```

Or pin the dependency in `package.json`:

JSON

```json
{
  "dependencies": {
    "@incode-sdks/react-native-incode-sdk": "[VERSION]"
  }
}
```

Use a variant suffix when needed:

JSON

```json
{
  "dependencies": {
    "@incode-sdks/react-native-incode-sdk": "[VERSION]-vc"
  }
}
```

## SDK Modes  
`initialize()` accepts `sdkMode`, and `setSdkMode()` can change the mode after initialization.

| Mode | Description |
| --- | --- |
| `standard` | Default capture and validation behavior. |
| `captureOnly` | Offline capture mode for ID and Selfie without validation. |
| `submitOnly` | Submit previously captured data without new capture steps. |

```ts
await IncodeSdk.initialize({
  testMode: false,
  sdkMode: 'standard',
  apiConfig: {
    key: 'YOUR_API_KEY',
    url: 'YOUR_API_URL',
  },
});

await IncodeSdk.setSdkMode('captureOnly');
```

## Additional Setup Instructions

### Additional setup for iOS  
Set the deployment target to iOS 13 or higher:

Diff

```diff
-platform :ios, '10.0'
+platform :ios, '13.0'
```

Add the CocoaPods sources at the top of your `Podfile`:

Ruby

```ruby
source 'https://cdn.cocoapods.org/'
source 'git@github.com:Incode-Technologies-Example-Repos/IncdDistributionPodspecs.git'
```

For React Native 0.69 and newer, autolinking is enough. For older React Native versions, add the package path manually:

Ruby

```ruby
pod 'react-native-incode-sdk', :path => '../node_modules/@incode-sdks/react-native-incode-sdk/'
```

Add an empty Swift file to the native project in Xcode. When prompted, create the bridging header.

Run CocoaPods:

Shell

```shell
cd ios
pod install
cd ..
```

Add these `Info.plist` usage descriptions:
- `NSCameraUsageDescription`. The SDK uses the camera in order to verify the identity of the customer, for example in ID scan and Selfie scan.
- `NSLocationWhenInUseUsageDescription`. The SDK uses the current user location for the Geolocation step.
- `NSMicrophoneUsageDescription`. The SDK uses the microphone during video conference and video selfie flows.

Add the required linker flags in the app target's Build Settings > Other Linker Flags:

Text

```text
$(inherited) -all_load -ObjC -l "stdc++" -l "iconv"
```

### Additional setup for Android  
Set Android SDK versions:

Gradle

```groovy
minSdkVersion = 23
compileSdkVersion = 35
```

Use `minSdkVersion = 24` when enabling video streaming.

Enable multidex:

Diff

```diff
defaultConfig {
+  multiDexEnabled true
}
```

Add the multidex dependency:

Gradle

```groovy
implementation 'com.android.support:multidex:1.0.3'
```

Make the application extend `MultiDexApplication`:

Java

```java
import androidx.multidex.MultiDexApplication;

public class MyApplication extends MultiDexApplication implements ReactApplication {
}
```

Add the Incode Maven repository and credentials to the project `build.gradle`:

Gradle

```groovy
allprojects {
  repositories {
    maven { url "https://jitpack.io" }
    maven {
      url = uri("https://maven.pkg.github.com/Incode-Technologies-Example-Repos/android-omni-packages")
      credentials {
        username = "incode-customers"
        password = "GITHUB_TOKEN"
      }
    }
  }
}
```

Prefer environment or Gradle properties for real credentials. Do not commit tokens.

## Expo SDK Installation  
Install the Expo configuration plugin:

Shell

```shell
npx expo install @incode-sdks/expo-incode-sdk-configuration
```

Add it to `app.json` or `app.config.js`:

JSON

```json
{
  "expo": {
    "plugins": [
      [
        "@incode-sdks/expo-incode-sdk-configuration",
        {
          "cameraUsageDescription": "The SDK uses the camera in order to verify the identity of the customer.",
          "locationWhenInUseUsageDescription": "The SDK uses the current user location for Geolocation steps.",
          "microphoneUsageDescription": "The SDK uses the microphone for video conference or video selfie.",
          "allowBackupOverride": true,
          "koinVersion": "3.5.3",
          "iosPodspecSource": "ssh",
          "addStreaming": false,
          "addDynamicLocalization": false,
          "addVoiceConsentFaceRecognition": false,
          "addNfc": false
        }
      ]
    ]
  }
}
```

Android builds need GitHub Packages credentials:

Shell

```shell
export GITHUB_USERNAME="<github-username>"
export GITHUB_TOKEN="<github-token>"
```

Then prebuild and run:

Shell

```shell
npx expo prebuild --clean --platform android
npx expo run:android --device
```

`iosPodspecSource` can be `ssh` or `https`. When using HTTPS, configure GitHub authentication outside the project with GitHub CLI, Git Credential Manager, macOS Keychain, or `~/.netrc`.

## First Flow   
The basic integration sequence is:
1. Explicitly initialize `IncodeSdk`.
2. After the SDK is initialized, configure the onboarding flow by selecting the modules you need.
3. Register listeners for step-related events, such as step completion and errors.
4. Start the onboarding flow.

```ts
import IncodeSdk from '@incode-sdks/react-native-incode-sdk';

await IncodeSdk.initialize({
  testMode: false,
  apiConfig: {
    key: 'YOUR_API_KEY',
    url: 'YOUR_API_URL',
  },
});

const result = await IncodeSdk.startOnboarding({
  flowConfig: [
    { module: 'IdScan' },
    { module: 'SelfieScan' },
    { module: 'FaceMatch' },
  ],
});

console.log(result.status);
```

Register listeners before starting the flow:

```ts
const unsubscribe = IncodeSdk.onStepCompleted({
  module: 'SelfieScan',
  listener: (event) => {
    console.log(event.result);
  },
});
```

Return the unsubscriber from your component cleanup.
