Flutter integration

Updated at:

The Financial-grade Real-Person Authentication service provides a Flutter client SDK for implementing the face authentication feature in your app. This topic describes how to integrate the Flutter client with a code sample.

Limitations

  • Debugging and running on a simulator are not supported. You must use a real device for development and functional testing.

  • The SDK supports only smartphones and tablets running iOS 9.0 or later, or Android 5.0 or later.

Dependency configuration

  1. Download and unzip the Flutter SDK.

    Note
    • This Flutter SDK uses the Financial-grade Real-Person Authentication SDK, version 2.3.39.

    • For more information about the interfaces in the Flutter SDK, see API Reference.

  2. Copy the unzipped Flutter SDK to your project.

    ALIYUN_FACE_DEMO/
    ├── .dart_tool/
    ├── .idea/
    ├── aliyun_face_plugin/
    ├── android/
    ├── build/
    ├── ios/
    ├── lib/
    │   └── main.dart
    ├── linux/
    ├── macos/
    ├── test/
    ├── web/
    ├── windows/
    ├── .flutter-plugins
    ├── .flutter-plugins-dependencies
    ├── .gitignore
    ├── .metadata
    ├── aliyun_face_demo.iml
    ├── analysis_options.yaml
    ├── pubspec.lock
    ├── pubspec.yaml
    └── README.md
  3. Open the pubspec.yaml file in your project and add the Aliyun Face Plugin dependency under the dependencies field.

    aliyun_face_plugin:
        path: aliyun_face_plugin

Android configuration

Add module dependencies

Open the /android/build.gradle file in your project and add the flatDir configuration to the allprojects field.

flatDir {
    dirs project(':aliyun_face_plugin').file('libs')
}
Note

If you use a later version of Flutter and encounter the following error:Namespace not specified. Specify a namespace in the module's build file.

In the /android/build.gradle file, you can add namespace = com.aliyun.face.aliyun_face_plugin to the android field.

Configure Proguard rules

If you have configured Proguard for code obfuscation in release builds, you must add the following rules to the android/app/proguard-rules.pro file in your project:

# This must be added to your app's obfuscation rules.
-keepclassmembers,allowobfuscation class * {
     @com.alibaba.fastjson.annotation.JSONField <fields>;
}
-keep class net.security.device.api.** {*;}
-keep class face.security.device.api.** {*;}
-keep class com.alipay.deviceid.** { *; }
-keep class org.json.** { *;}
-keep class com.alibaba.fastjson.** {*;}

# SDK obfuscation configuration
-keep class com.alipay.face.api.** {*;}
-keep class com.alipay.zoloz.toyger.**{*;}
-keep class com.dtf.face.api.** {*;}
-keep class com.dtf.face.ocr.verify.DTFOcrFacade { *; }
-keep class com.dtf.face.verify.** {*;}
-keep class com.dtf.face.network.model.** {*;}
-keep class com.dtf.face.network.APICallback {*;}
-keep class com.dtf.face.config.**{*;}
-keep class com.dtf.face.log.** {*;}
-keep class com.dtf.face.ui.overlay.** {*;}
-keep class com.dtf.face.ui.widget.ToygerWebView {*;}
-keep class com.dtf.face.utils.ClientConfigUtil{
   boolean needUploadPreviewTrace*();
   boolean needVideoExDegrade*();
   boolean isCfgVideoExDevice*();
}
-keep class com.dtf.toyger.base.** {*;}
-keep class com.dtf.face.network.mpass.biz.model.** { *; }
-keep class com.dtf.face.utils.LogUtils { *; }
-keep class com.dtf.wish.api.** { *; }
-keep class com.dtf.wish.ui.** { *; }
-keep class com.dtf.wish.ui.WishFragment{*;}
-keep class com.dtf.voice.api.** { *; }
-keep class xnn.* { *; }
-keep class facadeverify.** { *; }
-keep class baseverify.** { *; }
-keep class faceverify.** { *; }
-keep class ocrverify.** { *; }
-keep class wishverify.** { *; }

# R8 compilation and obfuscation configuration
-keep class com.dtf.face.ui.toyger.FaceLoadingFragment{ *; }
-keep class com.dtf.face.ui.toyger.FaceShowFragment{*;}
-keep class com.dtf.face.ui.toyger.FaceShowElderlyFragment{*;}
-keepclassmembers class com.dtf.face.camera.ICameraCallback{
   void onPreviewFrame*(*);
}

# NFC compilation configuration
-keep class com.dtf.face.nfc.verify.DTFNfcFacade { *; }
-keep class com.eidlink.**{*;}
-keep class net.sf.**{*;}
-keep class org.**{*;}
-keep class cn.**{*;}
-keep class com.froad.**{*;}
-keep class com.huawei.**{*;}
-keep class com.eidlink.**{*;}
-keep class org.ejbca.cvc.**{*;}
-keep class org.jmrtd.**{*;}
-keep public class com.netease.nis.sdkwrapper.Utils {public <methods>;}
-keep class net.sf.scuba.**{*;}
-keep class org.eid_bc.bouncycastle.jcajce.provider.symmetric.**{*;}

# Ignore warnings
-dontwarn okio.**
-dontwarn org.apache.commons.codec.binary.**

iOS configuration

Add camera permission

  1. Use Xcode to open the Runner project (project/ios/Runner.xcworkspace).

  2. Add the camera permission to the Info.plist file of the Runner project.

    Add the Privacy - Camera Usage Description key and set its value according to your app's requirements.

Frameworks

In the Link Binary With Libraries section, add the SDK framework and system dependency libraries. The framework is located at the aliyun_face_plugin/ios/Products/ path within the unzipped Flutter SDK directory.

SDK frameworks:

AliyunFaceAuthFacade.framework
APBToygerFacade.framework
APPSecuritySDK.framework
BioAuthEngine.framework
faceguard.framework
DTFIdentityManager.framework
DTFUtility.framework
MultiFactorFacade.framework
OCRDetectSDKForTech.framework
ToygerNative.framework
ToygerService.framework
VerifyNativeAbility.framework

System dependency libraries:

CoreGraphics.framework
Accelerate.framework
SystemConfiguration.framework
AssetsLibrary.framework
CoreTelephony.framework
QuartzCore.framework
CoreFoundation.framework
CoreLocation.framework
ImageIO.framework
CoreMedia.framework
CoreMotion.framework
AVFoundation.framework
WebKit.framework
libresolv.tbd
libz.tbd
libc++.tbd
libc++.1.tbd
libc++abi.tbd
AudioToolbox.framework
CFNetwork.framework
MobileCoreServices.framework
libz.1.2.8.tbd
AdSupport.framework
ReplayKit.framework

Bundles

In the Copy Bundle Resources build phase, add the following Bundles. The Bundles are located in the aliyun_face_plugin/ios/Products/ directory of the unzipped Flutter SDK.

  • ToygerService.bundle: Located in ToygerService.framework.

  • APBToygerFacade.bundle: Located in APBToygerFacade.framework.

  • APBToygerFacadeSuitable.bundle: Located in APBToygerFacade.framework.

  • OCRXMedia.bundle: Located in OCRDetectSDKForTech.framework.

  • BioAuthEngine.bundle: Located in BioAuthEngine.framework.

In Xcode, select the Runner target, go to the Build Phases tab, expand the Copy Bundle Resources section, and add the bundle files to the list.

-ObjC linker flag

Add the -ObjC flag to the Other Linker Flags setting. In Xcode, select the target, go to the Build Settings tab, and find this setting under the Linking category.

API reference

The Flutter SDK includes four interfaces: init (initializes the SDK), getMetaInfos (gets client metadata), setCustomUI (customizes the UI), and verify (starts authentication).

class AliyunFacePlugin {
  // Initializes the SDK.
  Future<void> init() {
    return AliyunFacePluginPlatform.instance.init();
  }

  // Gets the client metadata. This data is required for the server-side call to obtain the CertifyId.
  Future<String?> getMetaInfos() {
    return AliyunFacePluginPlatform.instance.getMetaInfos();
  }
  
  // Starts the SDK authentication process.
  Future<String?> verify(Map<String, String> params) {
    return AliyunFacePluginPlatform.instance.verify(params);
  }
  
  // Customizes the SDK UI.
  Future<String?> setCustomUI(String configuration) {
    return AliyunFacePluginPlatform.instance.setCustomUI(configuration);
  }
}

Initialize the SDK

  • Description: This interface initializes the face model and face security modules. Call it as early as possible after your app starts and the user accepts the privacy policy.

  • Function prototype:

    Future<void> init() {
        return AliyunFacePluginPlatform.instance.init();
    }
  • Return value: None.

Get MetaInfos

  • Description: This interface returns the client's environment information. You must send this information to your server, which then calls the server-side InitFaceVerify API with this information as the MetaInfo parameter. This call obtains a CertifyId for subsequent authentication.

  • Function prototype:

    Future<String?> getMetaInfos() {
        return AliyunFacePluginPlatform.instance.getMetaInfos();
    }
  • Return value: A string that contains the client's environment information, or null if an error occurs.

Customize the UI

  • Description: Customizes UI elements on the authentication page, such as colors and icons.

  • Function prototype:

    Future<String?> setCustomUI() {
        return AliyunFacePluginPlatform.instance.setCustomUI(configuration);
    }

Start authentication

  • Description: Initiates a real-person authentication request.

  • Function prototype:

    Future<String?> verify(Map<String, String> params) {
        return AliyunFacePluginPlatform.instance.verify(params);
    }
  • Parameter params: A map that contains the CertifyId and key-value pairs for extended parameters. For details, see the extParams description for Android and iOS.

    {"certifyId":"YOUR_CERTIFY_ID","extended_parameter_key":"extended_parameter_value"}
    Important
    • Each CertifyId can be used only once. Otherwise, the SDK returns one of the following errors:

      • iOS: 2002,ZIMNetworkfail

      • Android: 1001,NET_RESPONSE_INVALID

    • We recommend checking the runtime environment to determine whether it is Android or iOS to use the correct extParams. Alternatively, you can pass the extParams for both environments.

  • Return value: Returns the status of the real-person authentication request. The format is code,reson, where the values are separated by a comma (,). code is the error code, and reson is the specific reason.

    Note

    The meanings of code and reason differ between iOS and Android. Refer to the respective documentation for details.

    Error code details

    Android

    Complete result code information (Click to view)

    To view this information offline, you can download the following table.

    Client result code

    Android

    1000

    Z5120 - Facial recognition was successful and the authentication passed. You can call the server-side query API operation to obtain detailed authentication information.

    1001

    Z1000 - Other exceptions occurred.

    Z1001 - Failed to initialize the facial recognition algorithm.

    Z1002 - The camera cannot be started.

    Z1003 - Unsupported CPU architecture.

    Z1004 - The Android system version is too low.

    Z1005 - Facial recognition timed out (single attempt).

    Z1006 - Facial recognition timed out after multiple attempts.

    Z1013 - Liveness detection failed.

    Z1018 - No front-facing camera.

    Z1019 - Camera permission not granted.

    Z1020 - Failed to open the camera.

    Z1023 - Internal authentication error.

    Z1024 - The SDK authentication flow is in progress. Wait for the local authentication flow to complete before you make another call.

    Z1029 - The Android system does not support screen recording.

    Z1030 - Audio recording permission not granted.

    Z1031 - Screen recording permission not granted.

    Z1032 - Failed to open the microphone.

    Z1033 - Failed to start screen recording.

    Z1034 - Insufficient local storage space (available storage is less than 100 MB).

    Z1035 - The context is empty.

    Z1036 - The install() interface was not called to complete the initialization before authentication.

    Z1037 - The CertifyId is null or empty.

    Z1038 - Obfuscation configuration error.

    Z1039 - WebView is used by multiple processes.

    Z1040 - Failed to download the facial recognition model.

    Z1041 - Exited because the number of OCR retries exceeded the limit.

    Z1044 - The state of the foldable device (folded/unfolded) was changed during authentication.

    Z1045 - The context is empty.

    Z1046 - The facial recognition process was interrupted.

    Z1047 - Model data error.

    Z1048 - An error occurred during quality authentication.

    Z5112 - Failed to upload the color meta information.

    Z5113 - Failed to upload the color video.

    Z5114 - Failed to upload the authentication video.

    Z5115_4 - Failed to load the .so file.

    Z5116 - Failed to upload the audio file.

    Z6001 - The number of OCR attempts exceeded the limit.

    Z6002 - Network timed out when uploading the OCR image.

    Z6003 - The OSS token expired.

    Z6004 - Failed to process the face photo.

    Z7001 - Abnormal data was detected during SDK initialization or use.

    Z3001 - The number of NFC retries exceeded the limit.

    Z3002 - Permission to enable the system's NFC feature was denied.

    Z3003 - The device does not support NFC.

    Z3004 - An exception related to the NFC protocol occurred.

    Z3005 - The three elements for pass-through mode are incorrect.

    Z1008 - The user clicked the X button to exit during authentication.

    Z1009 - The user clicked "Do Not Authorize" to exit from the authorization page.

    1003

    Z1011 - A network error occurred during client initialization.

    Z1012- A network access exception occurred on the client.

    2002

    Z1025 - The client initialization API operation returned a network error.

    Z1026 - A network error occurred during information upload.

    Z1027 - A network error occurred in the server-side authentication API operation.

    Z1028 - The number of concurrent requests to the server-side API operation exceeded the limit.

    Z1042 - An error was reported by the OCR authentication service.

    Z1043 - An error was reported by the facial recognition service.

    2003

    The time on the client device is incorrect.

    2006

    Z5128 - Facial recognition failed and the authentication was not passed. You can call the server-side query API operation to find the specific reason for the failure.

    iOS

    response.code contains the following return parameters. These parameters are described in the following table.

    Error code

    Error message

    Error code descriptions

    1000 (ZIMResponseSuccess)

    Facial recognition successful

    The user completed the facial recognition process. The recommended authentication result is Pass.

    This result is for reference only. Call the server-side DescribeFaceVerify API to get the final authentication result.

    1001 (ZIMInternalError)

    System error

    A system error occurred.

    1003 (ZIMInterrupt)

    Verification interrupted

    The verification was interrupted.

    2002 (ZIMNetworkfail)

    Network error

    A network error occurred.

    2003 (ZIMTIMEError)

    Client device time error

    The time on the client device is incorrect.

    2006 (ZIMResponseFail)

    Facial recognition failed

    The user completed the facial recognition process. The recommended authentication result is Fail.

    This result is for reference only. Call the server-side DescribeFaceVerify API to get the final authentication result and the detailed reason for the failure.

    Note

    For more information about error codes, you can download the list of financial-grade iOS client error codes.

Sample code

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:aliyun_face_plugin/aliyun_face_plugin.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _infos = 'Unknown';
  final _aliyunFacePlugin = AliyunFacePlugin();

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

    // Call the init interface early in the app's startup process.
    _aliyunFacePlugin.init();
  }

  Future<void> getMetaInfos() async {
    String metainfos;

    try {
      // Get the client metadata. Send this information to your server to obtain the CertifyId by calling the relevant server-side API.
      metainfos = await _aliyunFacePlugin.getMetaInfos() ?? 'Unknown metainfos';
    } on PlatformException {
      metainfos = 'Failed to get metainfos.';
    }

    setState(() {
      _infos = "metainfos: " + metainfos;
    });
  }

  Future<void> startVerify() async {
    String verifyResult;
    try {
      // Call the authentication interface. The CertifyId must be obtained by calling a server-side API.
      // Each CertifyId can be used only once. Otherwise, the SDK returns an error: code `2002` for iOS or `1001` for Android.
      Map<String, String> params = {"certifyId":"YOUR_CERTIFY_ID","extended_parameter_key":"extended_parameter_value"};
      verifyResult = await _aliyunFacePlugin.verify(
              params) ??
          '-1,error';
    } on PlatformException {
      verifyResult = '-2,exception';
    }

    setState(() {
      _infos = "verifyResult: " + verifyResult;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Aliyun face plugin demo')),
        body: Center(
            child: Column(children: <Widget>[
          Text('$_infos\n'),
          ElevatedButton(
              onPressed: () async {
                getMetaInfos();
              },
              child: Text("getMetaInfos")),
          ElevatedButton(
              onPressed: () async {
                startVerify();
              },
              child: Text("startVerify")),
        ])),
      ),
    );
  }
}
            

To download the complete code sample, click Demo.