# React Native

Before integrating Cactusverify, it is recommended to follow the steps described in [Integration Guide](https://kvalifika.gitbook.io/kvalifika/integration/integration-guide) and [Initial Setup](https://kvalifika.gitbook.io/kvalifika/integration/initial-setup).

{% hint style="warning" %}
Naming of the properties and functions might be slightly modified depending on the version.
{% endhint %}

## Installation

Add NPM dependency by running

```javascript
npm install @kvalifika/react-native-sdk
```

or

```javascript
yarn add @kvalifika/react-native-sdk
```

### For React Native <0.60

If your React Native version is larger than >= 0.60, you can ignore this step. Otherwise, please run the following command:

`react-native link @kvalifika/react-native-sdk`

### iOS Specific Steps

&#x20;Add sources to Podfile and use minimum iOS version `11.0`

```javascript
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/Kvalifika/kvalifika-cocoapods-specs.git'
source 'https://github.com/Kvalifika/zoom-cocoapods-specs.git'

platform :ios, '11.0'
```

&#x20;Then navigate to `ios` folder and run `pod install`

{% hint style="warning" %}
`pod install` might take a long time!
{% endhint %}

### App Permissions

Please add the following permissions to your app's *Info.plist*, so that the Cactusverify iOS SDK can access a user's camera to run a verification. You can do this in the property list view or by code. Right-click on *Info.plist* and select Open As -> Source Code. Add the lines below somewhere inside the file:

```markup
<!-- permission strings to be include in info.plist -->
<key>NSCameraUsageDescription</key>
<string>Please give us access to your camera, to complete the verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Please give us access to your photo library to verify you.</string>
```

### **Create Objective C Bridging Header**

After the pods are installed, open your project's `.xcworkspace` file in Xcode. Add a blank Swift file to your project (File -> New -> Swift File), with a bridging header (it will prompt you to auto-create one).

Righ&#x74;**-**&#x63;lick on the project's name & select a new file.

![Creating Objective C Bridging Header - new file](https://724774130-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MVNVgV6Dh2kMg2n55Z5%2F-Me567P88nP-l5MszmN-%2F-Me5Bc7jqZPXgPqyEdj4%2Fimage.png?alt=media\&token=520717be-6490-4e40-90e5-ee15bc7e4b79)

1. Choose and create an empty Swift file:

![Creating Objective C Bridging Header - Swift file](https://724774130-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MVNVgV6Dh2kMg2n55Z5%2F-Me567P88nP-l5MszmN-%2F-Me5CYT42L_FidL0K9gc%2Fimage.png?alt=media\&token=bef81803-fd3c-4ae2-ab4c-0fc4e5200e8a)

2\. Give the name to your file:

![Creating Objective C Bridging Header - naming Swift file](https://724774130-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MVNVgV6Dh2kMg2n55Z5%2F-Me5Ce2PVuZstEumD6QL%2F-Me5CnGB1Wgw5vbn9obz%2Fimage.png?alt=media\&token=2a878bd8-85b7-4780-8b4c-b1bff7161ebb)

3\. Select `Create Bridging Header`:

![Creating Objective C Bridging Header - final step](https://724774130-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MVNVgV6Dh2kMg2n55Z5%2F-Me5Ce2PVuZstEumD6QL%2F-Me5DD5Wvd4lugqZudsX%2Fimage.png?alt=media\&token=4a7c2b9a-744e-4962-8a9c-8ddafb3cc498)

### Android Specific Parts

After installing NPM package, please do the following steps to set up the Android environment:

1. Please add the following lines to `android/build.gradle` file:
   1. Set `minSdkVersion` to `21` or higher
   2. Add maven URL to repositories: `maven { url 'https://s3.eu-central-1.amazonaws.com/com.kvalifika.sdk' }`

**Code Example**

```javascript
// Top-level build.gradle file

buildscript {
  ext {
    minSdkVersion = 21
  }
}

allprojects {
  repositories {
    google()
    jcenter()
    maven { url 'https://s3.eu-central-1.amazonaws.com/com.kvalifika.sdk' }
  }
}
```

## Initialize the SDK

```javascript
import {
  KvalifikaSDK,
  KvalifikaSDKLocale,
  KvalifikaSDKError,
} from '@kvalifika/react-native-sdk';
```

&#x20;After that, you need to initialize SDK in`useEffect`with **your appId.**

{% hint style="info" %}
appId is Application ID, generated from Admin Panel. See [Initial Setup](https://kvalifika.gitbook.io/kvalifika/integration/initial-setup#retrieve-application-ids) for details.
{% endhint %}

```javascript
const App = () => {
  useEffect(() => {
    KvalifikaSDK.initialize({
      appId: 'YOUR APP ID',
      locale: KvalifikaSDKLocale.EN,
    });
  }, []);

  return (
    <View>
      <Text>Kvalifika SDK Sample</Text>
    </View>
  );
};
```

## **Start Verification**

&#x20;Call `KvalifikaSDK.startSession()` on button pres&#x73;**:**

```javascript
const App = () => {
  useEffect(() => {
    KvalifikaSDK.initialize({
      appId: 'YOUR APP ID',
      locale: KvalifikaSDKLocale.EN,
    });
  }, []);

  return (
    <View>
      <Button
        onPress={() => KvalifikaSDK.startSession()}
        title="Start Session"
      />
    </View>
  );
};
```

## Handling Verifications

It's useful to know that whether a user has completed the verification flow or canceled it. For this, you can implement the callback methods.

### Callback Methods

| Method       | Description                                                                                        |
| ------------ | -------------------------------------------------------------------------------------------------- |
| onInitialize | This callback method is triggered when SDK is initialized.                                         |
| onStart      | This callback method is triggered when the user starts verification.                               |
| onFinish     | This callback method is triggered when the user completes verification. Get session data here.     |
| onError      | This callback method is triggered on error  (see [Error Codes](#error-codes) for more information) |

{% hint style="warning" %}
KvalifikaSDK uses NativeEventEmitter to communicate between Android and iOS native modules. **Make sure to remove callbacks on unmount.**
{% endhint %}

```javascript
const App = () => {
  useEffect(() => {
    KvalifikaSDK.onInitialize(() => {
      Alert.alert('Kvalifika', 'Kvalifika SDK Initialized');
    });

    KvalifikaSDK.onStart(sessionId => {
      console.log(`Started with id: ${sessionId}`);
    });

    KvalifikaSDK.onFinish(sessionId => {
      Alert.alert('Kvalifika', `Session finished with id: ${sessionId}`);
    });

    KvalifikaSDK.onError((error, message) => {
      console.log(error, message);

      if (error === KvalifikaSDKError.INVALID_APP_ID) {
      }

      if (error === KvalifikaSDKError.USER_CANCELLED) {
      }

      if (error === KvalifikaSDKError.TIMEOUT) {
      }

      if (error === KvalifikaSDKError.USER_CANCELLED) {
      }

      if (error === KvalifikaSDKError.SESSION_UNSUCCESSFUL) {
      }

      if (error === KvalifikaSDKError.ID_UNSUCCESSFUL) {
      }

      if (error === KvalifikaSDKError.CAMERA_PERMISSION_DENIED) {
      }

      if (error === KvalifikaSDKError.LANDSCAPE_MODE_NOT_ALLOWED) {
      }

      if (error === KvalifikaSDKError.REVERSE_PORTRAIT_NOT_ALLOWED) {
      }

      if (error === KvalifikaSDKError.FACE_IMAGES_UPLOAD_FAILED) {
      }

      if (error === KvalifikaSDKError.DOCUMENT_IMAGES_UPLOAD_FAILED) {
      }
      
      if (error === KvalifikaSDKError.NO_MORE_ATTEMPTS) {
      }

      if (error === KvalifikaSDKError.UNKNOWN_INTERNAL_ERROR) {
      }
    });

    return () => {
      // Remove callbacks to avoid duplicate listeners if useEffect runs multiple times or remounts
      KvalifikaSDK.removeCallbacks();
    };
  }, []);

  useEffect(() => {
    KvalifikaSDK.initialize({
      appId: 'YOUR APP ID',
      locale: KvalifikaSDKLocale.EN,
    });
  }, []);

  return (
    <View>
      <Button
        onPress={() => KvalifikaSDK.startSession()}
        title="Start Session"
      />
    </View>
  );
};
```

## Error Codes

| Error Code                       | Description                                                                              |
| -------------------------------- | ---------------------------------------------------------------------------------------- |
| INVALID\_APP\_ID                 | Kvalifika App Id is incorrect                                                            |
| USER\_CANCELLED                  | User canceled before completing verification.                                            |
| TIMEOUT                          | Canceled due to inactivity.                                                              |
| SESSION\_UNSUCCESSFUL            | The Session was not performed successfully.                                              |
| ID\_UNSUCCESSFUL                 | The ID Scan was not performed successfully and identity document data was not generated. |
| CAMERA\_PERMISSION\_DENIED       | Camera is required but access is prevented by user settings.                             |
| LANDSCAPE\_MODE\_NOT\_ALLOWED    | Verification was canceled because the device is in landscape mode.                       |
| REVERSE\_PORTRAIT\_NOT\_ALLOWED  | Verification was canceled because the device is in reverse portrait mode.                |
| FACE\_IMAGES\_UPLOAD\_FAILED     | Could not upload face images. Internal request failed.                                   |
| DOCUMENT\_IMAGES\_UPLOAD\_FAILED | Could not upload ID card or passport images. Internal request failed.                    |
| NO\_MORE\_ATTEMPTS               | User has reached maximum limit of attempts                                               |
| UNKNOWN\_INTERNAL\_ERROR         | Session failed because of an unhandled internal error. This error comes with a message.  |

## UI Customizations

### Appearance

It is possible to customize the logo and icons.

In React Native we need to add the images in `android` and `ios` subfolders in the project directory.

{% hint style="info" %}
Open `android` subfolder in Android Studio and drag the image to `res/drawable` folder.
{% endhint %}

{% hint style="info" %}
Open `ios` subfolder in XCode. Open `Assets.xcassets` folder and drag the image.
{% endhint %}

{% hint style="warning" %}
An image name in `android` and `ios` subfolders must match.
{% endhint %}

```typescript
KvalifikaSDK.initialize({
  appId: 'YOUR APP ID',
  locale: KvalifikaSDKLocale.EN,
  logo: 'logo',
  documentIcon: 'document_icon',
  cancelIcon: 'cancel_icon',
  activeFlashIcon: 'active_flash_icon',
  inactiveFlashIcon: 'inactive_flash_icon',
});
```

### Language

It is possible to set locale when initializing SDK. Supported locales are:

| Code | Language |
| ---- | -------- |
| EN   | English  |
| GE   | Georgian |
| RU   | Russian  |
| SP   | Spanish  |

```javascript
KvalifikaSDK.initialize({
  appId: 'YOUR APP ID',
  locale: KvalifikaSDKLocale.EN,
});
```

## Development Mode

Without specifying mode SDK uses <https://api.kvalifika.com>

With development mode ON SDK uses <https://apistaging.kvalifika.com>

```typescript
KvalifikaSDK.initialize({
  appId: 'YOUR APP ID',
  development: true,
});
```

## ProGuard (Android)

If ProGuard is used in Android release build, it is possible to add the following options to ProGuard file:

```javascript
-keep class com.facetec.sdk.** { *; }
```
