# Flutter

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

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

## Package Installation

Cactusverify SDK should be integrated into the existing Flutter project (more information regarding creating Flutter projects is here: [Flutter - Get Started](https://flutter.dev/docs/get-started/))

At the root level of your project, find the pubspec.yaml file and add the following line in the dependencies section:

{% code title="pubspec.yaml" %}

```dart
dependencies:
  kvalifika_sdk: ^0.12.1
```

{% endcode %}

### iOS Specific Steps

If there is no Podfile in `ios` folder, run `flutter build ios` in the terminal of the project folder.

Add sources to Podfile and use minimum iOS version **11.0.**

{% code title="Podfile" %}

```dart
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'
```

{% endcode %}

Then navigate to `ios` folder and run `pod install`.

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

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 following code:

{% code title="Info.plist" %}

```aspnet
<!-- 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>
```

{% endcode %}

### Android Specific Steps

Open `android/app/build.gradle` file and set `minSdkVersion` to **21**.

{% code title="android/build.gradle" %}

```dart
android {
    ...
    defaultConfig {
        ...
        minSdkVersion 21
        ...
  }
  ...
}
```

{% endcode %}

## Initialize the SDK

To initialize Cactusverify SDK, it first should be imported:

```dart
import 'package:kvalifika_sdk/kvalifika_sdk.dart';
```

After this, it is needed to initialize SDK with your appId:

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

```dart
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Kvalifika'),
        ),
        body: KvalifikaSdk(
          appId: "YOUR APP ID",
          locale: KvalifikaSdkLocale.EN,
          builder: (context, sdk) => Center(
            child: ElevatedButton(
              onPressed: () {
                sdk.startSession();
              },
              child: Text('Start Verification'),
            ),
          ),
        ),
      ),
    );
  }
}
```

## Start Verification

Call `sdk.startSession()` on button click:

```dart
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Kvalifika'),
        ),
        body: KvalifikaSdk(
          appId: "YOUR APP ID",
          locale: KvalifikaSdkLocale.EN,
          builder: (context, sdk) => Center(
            child: ElevatedButton(
              onPressed: () {
                // Start session on button press
                sdk.startSession();
              },
              child: Text('Start Verification'),
            ),
          ),
        ),
      ),
    );
  }
}
```

## Handling Verifications

It's useful to know that if 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 initializes                                                                            |
| onStart      | This callback method is triggered when user starts verification                                                                   |
| onFinish     | This callback method is triggered when user completes verification. Get session data here                                         |
| onError      | This callback method is triggered on error (see [Error Codes](/kvalifika/mobile-sdk/flutter.md#error-codes) for more information) |

```dart
KvalifikaSdk(
  appId: "YOUR APP ID",
  onInitialize: (context, sdk) {
    // Start session after initialization
    sdk.startSession();
  },
  onStart: (context, sessionId) {

  },
  onFinish: (context, sessionId) {
    // Fetch session data from your backend server here
  },
  onError: (context, 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.UNKNOWN_INTERNAL_ERROR) {

    }
  },
  builder: (context, sdk) => Center(
    child: ElevatedButton(
      onPressed: () {
        sdk.startSession();
      },
      child: Text('Start Verification'),
    ),
  ),
)
```

### Error Codes

| Error Code                       | Description                                                                                          |
| -------------------------------- | ---------------------------------------------------------------------------------------------------- |
| INVALID\_APP\_ID                 | Kvalifika AppId (Application ID) is incorrect                                                        |
| USER\_CANCELLED                  | User cancelled the session before completing verification                                            |
| TIMEOUT                          | Session is cancelled 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 session is cancelled because the device is in landscape mode                            |
| REVERSE\_PORTRAIT\_NOT\_ALLOWED  | Verification session is cancelled because 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.                                |
| UNKNOWN\_INTERNAL\_ERROR         | Verification session failed because of an unhandled internal error. This error comes with a message. |

## UI Customizations

### Appearance

It is possible to customize logo and icons for the application.

In Flutter 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 %}

```dart
KvalifikaSdk(
  appId: "YOUR APP ID",
  logo: "logo",
  documentIcon: "document_icon",
  cancelIcon: "cancel_icon",
  activeFlashIcon: "active_flash_icon",
  inactiveFlashIcon: "inactive_flash_icon",
  builder: (context, sdk) => Center(
    child: ElevatedButton(
      onPressed: () {
        sdk.startSession();
      },
      child: Text('Start Verification'),
    ),
  ),
)
```

### Language

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

| Code | Language |
| ---- | -------- |
| EN   | English  |
| GE   | Georgian |

```dart
KvalifikaSdk(
  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>

```
KvalifikaSdk(
  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:

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kvalifika.gitbook.io/kvalifika/mobile-sdk/flutter.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
