vlens 0.1.11
vlens: ^0.1.11 copied to clipboard
VLens Flutter SDK provides seamless integration for biometric verification.
VLens Flutter SDK Documentation #
Overview #
VLens Flutter SDK provides seamless integration for biometric verification and identity scanning in your Flutter applications. This SDK supports National ID scanning and liveness detection.
Installation #
To install VLens, add the following dependency to your pubspec.yaml file:
dependencies:
vlens: latest_version
Run the following command to fetch the package:
flutter pub get
Usage #
Import the Package #
import 'package:vlens/vlens.dart';
Initialize the SDK #
To initialize VLens, configure the SDK settings and call VLensManager().init().
final sdkConfig = SdkConfig(
transactionId: 'your_transaction_id',
isLivenessOnly: false,
isNationalIdOnly: false,
logoPath: "your_asset_path",
env: EnvironmentConfig(
apiBaseUrl: "https://api.vlenseg.com",
accessToken: "your_access_token",
refreshToken: "your_refresh_token",
apiKey: "your_api_key",
tenancyName: "your_tenancy_name",
),
defaultLocale: "en",
colors: ColorsConfig(
light: ColorConfig(
accent: "#4E5A78",
primary: "#397374",
secondary: "#FF4081",
background: "#FEFEFE",
dark: "#000000",
light: "#FFFFFF",
),
dark: ColorConfig(
accent: "#FFC107",
primary: "#2196F3",
secondary: "#FF4081",
background: "#000000",
dark: "#FFFFFF",
light: "#000000",
),
),
errorMessages: [
ApiError(
errorCode: 101,
errorMessageEn: "Network error",
errorMessageAr: "\u062E\u0637\u0623 \u0641\u064A \u0627\u0644\u0634\u0628\u0643\u0629",
),
],
onSuccess: (extractedData) {
// Handle success
Logger().d("verification success ${extractedData?.idFrontData?.name}");
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Success Verified!")),
);
},
onFailure: (String errorCode, String errorMsg) {
// Handle failure
Logger().d("Main verification failed due to: $errorMsg, Code: $errorCode");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(errorMsg)),
);
},
detectionRetryCounter: 5,
getExtractedData: true,
disableAutoCapture: false,
enableSounds: true,
);
VLensManager().init(context, sdkConfig);
To make it work on Android 13 and up, set this to false in the Android manifest:
android:enableOnBackInvokedCallback="false"
Example Project #
import 'package:flutter/material.dart';
import 'package:vlens/vlens.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'VLens Flutter SDK Demo',
home: const VLensDemoScreen(),
);
}
}
class VLensDemoScreen extends StatefulWidget {
const VLensDemoScreen({super.key});
@override
State<VLensDemoScreen> createState() => _VLensDemoScreenState();
}
class _VLensDemoScreenState extends State<VLensDemoScreen> {
final TextEditingController _transactionIdController = TextEditingController();
final TextEditingController _accessTokenController = TextEditingController();
bool _isDataComplete = false;
void _getStarted() {
final sdkConfig = SdkConfig(
transactionId: _transactionIdController.text,
isLivenessOnly: false,
isNationalIdOnly: false,
logoPath: "your_asset_path",
env: EnvironmentConfig(
apiBaseUrl: "https://api.vlenseg.com",
accessToken: _accessTokenController.text,
refreshToken: "your-refresh-token",
apiKey: "your-api-key",
tenancyName: "your-tenancy-name",
),
defaultLocale: "en",
colors: ColorsConfig(
light: ColorConfig(
accent: "#4E5A78",
primary: "#397374",
secondary: "#FF4081",
background: "#FEFEFE",
dark: "#000000",
light: "#FFFFFF",
),
dark: ColorConfig(
accent: "#FFC107",
primary: "#2196F3",
secondary: "#FF4081",
background: "#000000",
dark: "#FFFFFF",
light: "#000000",
),
),
errorMessages: [
ApiError(
errorCode: 101,
errorMessageEn: "Network error",
errorMessageAr: "خطأ في الشبكة",
),
],
onSuccess: (extractedData) {
// Handle success
Logger().d("verification success ${extractedData?.idFrontData?.name}");
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Success Verified!")),
);
},
onFailure: (String errorCode, String errorMsg) {
// Handle failure
Logger().d("Main verification failed due to: $errorMsg, Code: $errorCode");
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(errorMsg)),
);
},
detectionRetryCounter: 5,
getExtractedData: true,
disableAutoCapture: false,
enableSounds: true,
);
VLensManager().init(context, sdkConfig);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('VLens Flutter SDK Demo')),
body: Center(
child: ElevatedButton(
onPressed: _isDataComplete ? _getStarted : null,
child: const Text('Get Started'),
),
),
);
}
}
Configuration Options #
SdkConfig #
transactionId(String): Unique identifier for the transaction.isLivenessOnly(Boolean): Enables or disables liveness detection mode.isNationalIdOnly(Boolean): Enables or disables national ID scanning mode.nfcPassport(Boolean): Iftrue(default), the NFC passport chip reading step is included in the passport flow. Iffalse, the NFC step is skipped in OCR mode (no access token) and the flow goes straight to face validation. Ignored when an access token is set; NFC always runs in that case.logoPath(String?): Path to the logo image.- Example: "assets/images/your_logo_name.png".
- Default value : VLens logo.
env(EnvironmentConfig): Contains API-related configurations.apiBaseUrl(String): Base URL for the VLens API.accessToken(String): Access token for authentication.refreshToken(String): Token for refreshing access when expired.apiKey(String): API key for the VLens service.tenancyName(String): Name of the tenant using the service.
defaultLocale(String): Specifies the default language (e.g.,"en"for English,"ar"for Arabic).colors(Colors): Theming configuration for light and dark modes.light(ColorConfig): Color palette for light mode.dark(ColorConfig): Color palette for dark mode.
errorMessages(List: Custom error messages.errorCode(Int): Error code returned from the API.errorMessageEn(String): Error message in English.errorMessageAr(String): Error message in Arabic.
retryCounter(Int): Specifies the number of allowed retries for detection before failing.- default value is = 5
getExtractedData(Boolean): Iftrue, the SDK will return extracted data after successful scanning.disableAutoCapture(Boolean): Iftrue, the sdk will disable the auto capture for national id front and back (default valuefalse).enableSounds(Boolean): Iftrue, the SDK will play instruction and success sounds during face validation (default valuetrue).onSuccess((extractedData) -> {}): Lambda triggered when the initialization succeeds. Returns an extractData object.onFailure((errorCode, errorMsg) -> {}): Lambda triggered when the initialization fails. Returns an error code and error message.
ExtractData #
-
isDigitalIdentityVerified: Boolean -
isVerificationProcessCompleted: Boolean -
deviceInfo: String -
user: {
-id: Int
-name: String
-surname: String
-fullName: String
-userName: String
-emailAddress: String
-phoneNumber: String
-idNumber: String
-address: String
} -
idFrontData: {
-nameEnglish: String
-firstNameEnglish: String
-lastNamesEnglish: String
-name: String
-address: String
-firstName: String
-lastName: String
-govern: String
-idKey: String
-address1: String
-address2: String
-addressEnglish: String
-address1English: String
-address2English: String
-governEnglish: String
-city: String
-district: String
-dateOfBirth: String
-idNumber: String
-gender: String
-clientTransactionId: String
-requestId: String
-transactionId: String
} -
idBackData: {
-maritalStatus: String
-job: String
-jobTitle: String
-religion: String
-husbandName: String
-releaseDate: String
-idExpiry: String
-maritalStatusEnglish: String
-religionEnglish: String
-genderEnglish: String
-husbandNameEnglish: String
-jobEnglish: String
-jobTitleEnglish: String
-idNumber: String
-gender: String
-clientTransactionId: String
-requestId: String
-transactionId: String
}
Android Troubleshooting (Dependency Conflicts) #
If your app build fails with duplicate-class errors (typically in apps that also use firebase_messaging), add the following to your app-level android/app/build.gradle (Groovy DSL) or android/app/build.gradle.kts (Kotlin DSL).
The VLens plugin itself already excludes the conflicting BouncyCastle artifacts from its own dependencies, so the BouncyCastle block below is a safety net — only needed if other dependencies in your app also pull in
bcprov-jdk15on. The Firebase exclusion is required for any app usingfirebase-messaging23+.
1. Firebase conflict (firebase-iid / FirebaseInstanceIdReceiver) #
The ML Kit object-detection plugin transitively pulls in com.google.mlkit:linkfirebase:17.0.0, which brings the legacy firebase-iid:20.1.5. linkfirebase is only needed for Firebase-hosted custom ML models, which VLens does not use, so it can be safely excluded. This resolves the duplicate com.google.firebase.iid.FirebaseInstanceIdReceiver class error against firebase-messaging 23+.
2. BouncyCastle conflict (duplicate org.bouncycastle.* classes) #
The document-verification stack (jmrtd / cert-cvc, used for ICAO/passport inspection) transitively pulls in bcprov-jdk15on:1.68, which duplicates the bcprov-jdk18on:1.78 that VLens uses. Unify on jdk18on:1.78.
Groovy DSL (build.gradle):
configurations.all {
// ML Kit linkfirebase is unused by VLens; removes legacy firebase-iid:20.1.5
exclude group: 'com.google.mlkit', module: 'linkfirebase'
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'org.bouncycastle') {
def name = details.requested.name.replace('-jdk15on', '-jdk18on')
details.useTarget("org.bouncycastle:${name}:1.78")
}
}
resolutionStrategy.force 'org.bouncycastle:bcprov-jdk18on:1.78'
resolutionStrategy.force 'org.bouncycastle:bcpkix-jdk18on:1.78'
}
Kotlin DSL (build.gradle.kts):
configurations.all {
exclude(group = "com.google.mlkit", module = "linkfirebase")
resolutionStrategy.eachDependency {
if (requested.group == "org.bouncycastle") {
val name = requested.name.replace("-jdk15on", "-jdk18on")
useTarget("org.bouncycastle:$name:1.78")
because("Unify BouncyCastle on jdk18on 1.78 (VLens SDK)")
}
}
resolutionStrategy.force("org.bouncycastle:bcprov-jdk18on:1.78")
resolutionStrategy.force("org.bouncycastle:bcpkix-jdk18on:1.78")
}
If you still see duplicate META-INF entries (BouncyCastle jars are signed), add packaging excludes:
Groovy DSL (build.gradle):
android {
packagingOptions {
excludes += ['META-INF/MANIFEST.MF',
'META-INF/versions/9/OSGI-INF/MANIFEST.MF',
'META-INF/*.SF',
'META-INF/*.DSA',
'META-INF/*.RSA']
}
}
Kotlin DSL (build.gradle.kts):
android {
packaging {
resources {
excludes += "META-INF/MANIFEST.MF"
excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
excludes += "META-INF/*.SF"
excludes += "META-INF/*.DSA"
excludes += "META-INF/*.RSA"
}
}
}
After adding the block, run flutter clean and rebuild.
Error Handling #
Define custom error messages using ApiError:
ApiError(
errorCode: 101,
errorMessageEn: "Network error",
errorMessageAr: "\u062E\u0637\u0623 \u0641\u064A \u0627\u0644\u0634\u0628\u0643\u0629",
);
Support #
For questions and support, contact the VLens team at support@vlens.com.