trustchex_flutter_sdk 1.533.0 copy "trustchex_flutter_sdk: ^1.533.0" to clipboard
trustchex_flutter_sdk: ^1.533.0 copied to clipboard

Identity verification and face authentication SDK with document scanning, liveness detection, NFC/eID reading, and biometric technology for Flutter apps.

example/lib/main.dart

import 'dart:async';

import 'package:app_links/app_links.dart';
import 'package:flutter/material.dart';
import 'package:trustchex_flutter_sdk/trustchex_flutter_sdk.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // MASAK 4/C(1)(e) geolocation needs no app-side setup: the SDK captures a
  // coarse fix natively (iOS Core Location / Android LocationManager) when a
  // workflow step enables collectGeolocation. The host only declares the OS
  // permission strings (see Info.plist / AndroidManifest.xml).
  runApp(const TrustchexExampleApp());
}

class TrustchexExampleApp extends StatelessWidget {
  const TrustchexExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Trustchex SDK Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
            seedColor: const Color.fromARGB(255, 14, 11, 11)),
        useMaterial3: true,
        scaffoldBackgroundColor: Colors.white,
      ),
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: const ExampleHomeScreen(),
    );
  }
}

class ExampleHomeScreen extends StatefulWidget {
  const ExampleHomeScreen({super.key});

  @override
  State<ExampleHomeScreen> createState() => _ExampleHomeScreenState();
}

class _ExampleHomeScreenState extends State<ExampleHomeScreen> {
  final AppLinks _appLinks = AppLinks();
  StreamSubscription<Uri>? _linkSubscription;
  String _baseUrl = 'https://app.trustchex.com';
  String _sessionId = '';
  String? _lastHandledUrl;

  @override
  void initState() {
    super.initState();
    _initDeepLinks();
  }

  Future<void> _initDeepLinks() async {
    // Cold start: the app was launched by the deep link.
    final initialUri = await _appLinks.getInitialLink();
    if (initialUri != null) {
      _processDeepLink(initialUri.toString());
    }

    // Warm start: the link arrives while the app is already running. app_links
    // delivers both custom-scheme opens and universal links here — including
    // when the app is already open — by handling onNewIntent (Android) and the
    // scene/URL callbacks (iOS) natively. This is the case that leaves the user
    // stuck on the first screen if it is not wired up.
    _linkSubscription = _appLinks.uriLinkStream.listen(
      (uri) => _processDeepLink(uri.toString()),
      onError: (_) {},
    );
  }

  void _processDeepLink(String url) {
    // Ignore re-processing the same URL (getInitialLink can replay on resume).
    if (url == _lastHandledUrl) return;
    final parsed = DeeplinkUtils.parseQrCodeUrl(url);
    final sessionId = parsed['sessionId'];
    final baseUrl = parsed['baseUrl'];
    if (sessionId != null &&
        sessionId.isNotEmpty &&
        baseUrl != null &&
        baseUrl.isNotEmpty) {
      setState(() {
        _lastHandledUrl = url;
        _baseUrl = baseUrl;
        _sessionId = sessionId;
      });
    }
  }

  @override
  void dispose() {
    _linkSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TrustchexView(
      baseUrl: _baseUrl,
      sessionId: _sessionId.isEmpty ? null : _sessionId,
      branding: const TrustchexBranding(
        primaryColor: Colors.black,
        secondaryColor: Color(0xFFCCCCCC),
        tertiaryColor: Colors.red,
      ),
      locale: TrustchexLocale.en,
      enableAnalytics: true,
      isDebugMode: true,
      onDocumentRead: (result) {
        debugPrint('=== onDocumentRead ===');
        debugPrint('documentType: ${result.document.documentType.name}');
        debugPrint('issuingCountry: ${result.document.issuingCountry}');
        debugPrint('nationality: ${result.document.nationality}');
        debugPrint('documentNumber: ${result.document.documentNumber}');
        debugPrint('dateOfBirth: ${result.document.dateOfBirth}');
        debugPrint('dateOfExpiry: ${result.document.dateOfExpiry}');
        debugPrint('sex: ${result.document.sex.name}');
        debugPrint('rawLast: ${result.name.rawLast}  rawFirst: ${result.name.rawFirst}');
        debugPrint('displayLast: ${result.name.displayLast}  displayFirst: ${result.name.displayFirst}');
        debugPrint('nameSource: ${result.name.source.name}');
        debugPrint('hasFace: ${result.face != null}');
        debugPrint('======================');
      },
      onCompleted: () {},
      onError: (error) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Error: $error'),
            backgroundColor: Colors.red,
          ),
        );
      },
    );
  }
}