Flutter身份验证插件jumio_mobile_sdk_flutter的使用
Flutter身份验证插件jumio_mobile_sdk_flutter的使用
插件概述
jumio_mobile_sdk_flutter
是Jumio官方为Flutter提供的移动SDK插件,用于实现身份验证功能。此插件与Jumio SDK iOS 4.12.0和Jumio SDK Android 4.12.1兼容。如果您有任何问题,请联系您的客户经理或Jumio支持。
目录
兼容性
该插件已在Flutter版本3.27.1和Dart 3.6.0上进行了测试。
设置
创建Flutter项目并添加Jumio Mobile SDK模块
flutter create MyProject
添加依赖项
在pubspec.yaml
文件中添加Jumio Mobile SDK依赖项:
dependencies:
flutter:
sdk: flutter
jumio_mobile_sdk_flutter: ^4.12.0
安装依赖项:
cd MyProject
flutter pub get
cd ios && pod install
集成
iOS
Info.plist配置
- 在
Info.plist
文件中添加NSCameraUsageDescription
键。 - 确保应用的部署目标至少为iOS 11.0。
NFC、Digital Identity 和 Device Risk
- 参考NFC setup guide。
- 参考Digital Identity setup guide。
- 若要包含Device Risk功能,在Podfile中添加
pod Jumio/DeviceRisk
。
Android
AndroidManifest.xml配置
打开AndroidManifest.xml
文件并将allowBackup
设置为false
:
<application>
...
android:allowBackup="false">
</application>
...
确保compileSdkVersion
、minSdkVersion
和buildToolsVersion
足够高:
android {
minSdkVersion 21
compileSdkVersion 33
buildToolsVersion "32.0.0"
...
}
启用MultiDex
参考Android开发者指南启用MultiDex:
android {
...
defaultConfig {
...
multiDexEnabled true
}
}
升级Gradle构建工具
插件要求至少使用8.0.0版本的Android构建工具,这需要升级Gradle包装器到版本8并更新到Java 11。
在android/build.gradle
中升级构建工具版本:
buildscript {
...
dependencies {
...
classpath 'com.android.tools.build:gradle:8.2.2'
}
}
在android/gradle.wrapper/gradle-wrapper.properties
中修改Gradle Wrapper版本:
...
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
Proguard规则
参考Android guides了解有关Jumio SDK的Android Proguard规则信息。
为了启用分析反馈和内部诊断,请确保在Proguard规则中包含以下行:
-keep class io.flutter.embedding.android.FlutterActivity
使用
导入库
import 'package:jumio_mobile_sdk_flutter/jumio_mobile_sdk_flutter.dart';
初始化SDK
Jumio.init("AUTHORIZATION_TOKEN", "DATACENTER");
DATACENTER
可以是US
、EU
或SG
。有关如何获取AUTHORIZATION_TOKEN
的信息,请参考API Guide。
启动SDK
Jumio.start();
获取信息
扫描结果将异步返回。可以通过await
获取结果。如果发生问题(如无效凭据、缺少API密钥、权限错误等),会抛出异常。
自定义
Android
通过覆盖自定义主题AppThemeCustomJumio
来自定义JumioSDK Android外观。可以在styles.xml中找到所有可自定义值的例子。
iOS
可以基于设备的外观设置(深色模式或浅色模式)自定义每个颜色,也可以为两种外观设置一个单一颜色。可以在启动时传递自定义选项。
例如,设置基于深色或浅色模式的颜色:
Jumio.start({
"primaryColor": { light:"ffffff", dark:"000000" },
"primaryButtonBackground": { light:"ffffff", dark:"000000" }
});
设置相同颜色用于深色和浅色模式:
Jumio.start({
"primaryColor": "ffffff",
"primaryButtonBackground": "ffffff"
});
所有颜色都以HEX字符串提供,格式为#ff00ff
或#66ff00ff
(如果要设置透明度级别)。
配置
有关如何设置特定的SDK参数(如callbackUrl
、userReference
、country
等),请参考API Guide。
回调
有关结果字段、检索API、删除API、全局设置等信息,请阅读服务器相关信息页面。
结果对象
JumioSDK将在工作流成功完成后返回EventResult
,在出现错误时返回EventError
。EventError
包括错误代码和错误消息。
EventResult
参数 | 类型 | 最大长度 | 描述 |
---|---|---|---|
selectedCountry | String | 3 | ISO 3166-1 alpha-3国家代码 |
selectedDocumentType | String | 16 | PASSPORT, DRIVER_LICENSE, IDENTITY_CARD 或 VISA |
selectedDocumentSubType | String | 扫描ID的子类型 | |
idNumber | String | 100 | 文档识别号 |
personalNumber | String | 文档个人编号 | |
issuingDate | Date | 发行日期 | |
expiryDate | Date | 到期日期 | |
issuingCountry | String | 3 | 发行国ISO 3166-1 alpha-3国家代码 |
lastName | String | 100 | 客户姓氏 |
firstName | String | 100 | 客户名字 |
dob | Date | 出生日期 | |
gender | String | 1 | m, f 或 x |
originatingCountry | String | 3 | 原籍国ISO 3166-1 alpha-3国家代码 |
addressLine | String | 64 | 街道名称 |
city | String | 64 | 城市 |
subdivision | String | 3 | ISO 3166-2:US州代码后三位 |
postCode | String | 15 | 邮政编码 |
mrzData | MRZ-DATA | MRZ数据 | |
optionalData1 | String | 50 | MRZ第一行的可选字段 |
optionalData2 | String | 50 | MRZ第二行的可选字段 |
placeOfBirth | String | 255 | 出生地 |
MRZ-Data
参数 | 类型 | 最大长度 | 描述 |
---|---|---|---|
format | String | 8 | MRP, TD1, TD2, CNIS, MRVA, MRVB 或 UNKNOWN |
line1 | String | 50 | MRZ第一行 |
line2 | String | 50 | MRZ第二行 |
line3 | String | 50 | MRZ第三行 |
idNumberValid | BOOL | 如果ID号码校验位有效则为true,否则为false | |
dobValid | BOOL | 如果出生日期校验位有效则为true,否则为false | |
expiryDateValid | BOOL | 如果到期日校验位有效或不可用则为true,否则为false | |
personalNumberValid | BOOL | 如果个人编号校验位有效或不可用则为true,否则为false | |
compositeValid | BOOL | 如果复合校验位有效则为true,否则为false |
本地模型
我们的SDK需要几个机器学习模型来最佳工作。我们建议下载这些文件并将其添加到项目中而不更改其名称(类似于添加本地化文件)。这将在运行时节省两个网络请求以下载这些文件。
预加载模型
可以在初始化Jumio SDK之前预加载ML模型。为此,设置完成块JumioMobileSDK.setPreloaderFinishedBlock
并使用JumioMobileSDK.preloadIfNeeded
开始预加载。
iOS
可以在Bundling models in the app部分找到模型,并将其复制到ios/Assets
文件夹中。
Android
可以在Bundling models in the app部分找到模型,并将其复制到app/src/main/assets/
文件夹中。
常见问题
Android面帮助动画在发布版本中损坏
如果面帮助动画在调试版本中看起来正常但在发布版本中损坏,请确保在Proguard文件中包含以下规则:
-keep class androidx.constraintlayout.motion.widget.** { *; }
iOS模拟器显示白屏
Jumio SDK不支持iOS模拟器。请仅在物理设备上运行Jumio SDK。
iOS调试版本运行正常但发布版本崩溃
这是由于Xcode 13引入了新的选项“管理版本和构建号”。请确保禁用此选项。或者,可以在exportOptions.plist
中设置manageAppVersionAndBuildNumber
为false
。
iOS应用启动时崩溃
如果iOS应用程序在启动时立即崩溃且没有其他信息,但Android正常工作,请确保在Podfile
中添加以下行:
post_install do |installer|
installer.pods_project.targets.each do |target|
if ['iProov', 'DatadogRUM', 'DatadogCore', 'DatadogInternal'].include? target.name
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
end
对于Xcode 15及以上版本,请确保在Podfile
中添加以下行:
post_install do |installer|
installer.pods_project.targets.each do |target|
if ['iProov', 'DatadogRUM', 'DatadogCore', 'DatadogInternal'].include? target.name
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
end
end
end
end
Android发布版本国家列表为空
如果Android发布版本中的国家列表为空,请确保应用程序具有适当的互联网权限。如果没有有效的网络连接,国家不会加载,列表将保持为空。如果需要,请在AndroidManifest.xml
文件中添加android.permission.INTERNET
权限。
支持
如果您有任何问题,请联系Jumio客户服务:support@jumio.com或访问支持页面。
示例代码
以下是一个完整的示例demo,展示了如何在Flutter应用中使用jumio_mobile_sdk_flutter
插件进行身份验证。
import 'package:flutter/material.dart';
import 'package:jumio_mobile_sdk_flutter/jumio_mobile_sdk_flutter.dart';
void main() {
runApp(DemoApp());
}
class DemoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(title: "Mobile SDK Demo App"),
);
}
}
class HomePage extends StatefulWidget {
final String? title;
HomePage({Key? key, this.title}) : super(key: key);
@override
State<StatefulWidget> createState() => _HomePageState(title);
}
class _HomePageState extends State<HomePage> {
final String? title;
final tokenInputController = TextEditingController();
bool pressedUS = false;
bool pressedEU = false;
bool pressedSGP = false;
_HomePageState(this.title);
@override
void initState() {
super.initState();
initModelPreloading();
}
void initModelPreloading() {
Jumio.setPreloaderFinishedBlock(() {
print('All models are preloaded. You may start the SDK now!');
});
Jumio.preloadIfNeeded();
}
@override
void dispose() {
tokenInputController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title!),
),
body: Center(
child: IntrinsicWidth(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 250.0,
child: TextFormField(
controller: tokenInputController,
decoration: InputDecoration(
border: UnderlineInputBorder(),
labelText: 'Authorization token',
),
),
),
ElevatedButton(
child: Text("Start"),
onPressed: () {
_start(tokenInputController.text);
},
),
ElevatedButton(
child: Text("US"),
style: ElevatedButton.styleFrom(
backgroundColor: pressedUS ? Colors.yellow : Colors.blue,
foregroundColor: Colors.white,
),
onPressed: () => {
setState(() {
pressedUS = !pressedUS;
pressedEU = false;
pressedSGP = false;
}),
DATACENTER = 'US',
},
),
ElevatedButton(
child: Text("EU"),
style: ElevatedButton.styleFrom(
backgroundColor: pressedEU ? Colors.yellow : Colors.blue,
foregroundColor: Colors.white,
),
onPressed: () => {
setState(() {
pressedEU = !pressedEU;
pressedUS = false;
pressedSGP = false;
}),
DATACENTER = 'EU',
},
),
ElevatedButton(
child: Text("SG"),
style: ElevatedButton.styleFrom(
backgroundColor: pressedSGP ? Colors.yellow : Colors.blue,
foregroundColor: Colors.white,
),
onPressed: () => {
setState(() {
pressedSGP = !pressedSGP;
pressedUS = false;
pressedEU = false;
}),
DATACENTER = 'SG',
},
),
],
),
),
),
);
}
Future<void> _start(String authorizationToken) async {
await _logErrors(() async {
await Jumio.init(authorizationToken, DATACENTER);
final result = await Jumio.start(
{
// "background": "#AC3D9A",
// "primaryColor": "#FF5722",
// "loadingCircleIcon": "#F2F233",
// "loadingCirclePlain": "#57ffc7",
// "loadingCircleGradientStart": "#EC407A",
// "loadingCircleGradientEnd": "#bc2e41",
// "loadingErrorCircleGradientStart": "#AC3D9A",
// "loadingErrorCircleGradientEnd": "#C31322",
// "primaryButtonBackground": {"light": "#D900ff00", "dark": "#9Edd9E"}
}
);
await _showDialogWithMessage("Jumio has completed. Result: $result");
});
}
Future<void> _logErrors(Future<void> Function() block) async {
try {
await block();
} catch (error) {
await _showDialogWithMessage(error.toString(), "Error");
}
}
Future<void> _showDialogWithMessage(String message, [String title = "Result"]) async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text(title),
content: SingleChildScrollView(child: Text(message)),
actions: <Widget>[
TextButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
希望这个详细的指南能帮助您顺利集成和使用jumio_mobile_sdk_flutter
插件。如果有任何问题,请随时联系Jumio支持团队。
更多关于Flutter身份验证插件jumio_mobile_sdk_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter身份验证插件jumio_mobile_sdk_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用jumio_mobile_sdk_flutter
插件进行身份验证的示例代码。这个示例假设你已经安装并配置好了jumio_mobile_sdk_flutter
插件。
首先,确保你的pubspec.yaml
文件中已经添加了jumio_mobile_sdk_flutter
依赖:
dependencies:
flutter:
sdk: flutter
jumio_mobile_sdk_flutter: ^latest_version # 请替换为最新的版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你可以按照以下步骤使用Jumio SDK进行身份验证:
- 初始化SDK(通常在你的应用的主入口文件中,比如
main.dart
):
import 'package:flutter/material.dart';
import 'package:jumio_mobile_sdk_flutter/jumio_mobile_sdk_flutter.dart';
void main() {
// 初始化Jumio SDK(这里假设你已经有了Jumio提供的必要配置信息)
Jumio.initialize(
apiKey: 'YOUR_API_KEY',
apiSecret: 'YOUR_API_SECRET',
environment: JumioEnvironment.sandbox, // 或者 JumioEnvironment.production
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Jumio Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: JumioDemoScreen(),
);
}
}
- 创建一个屏幕来触发身份验证流程(比如
JumioDemoScreen.dart
):
import 'package:flutter/material.dart';
import 'package:jumio_mobile_sdk_flutter/jumio_mobile_sdk_flutter.dart';
class JumioDemoScreen extends StatefulWidget {
@override
_JumioDemoScreenState createState() => _JumioDemoScreenState();
}
class _JumioDemoScreenState extends State<JumioDemoScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Jumio Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
try {
// 触发Jumio身份验证流程
final result = await Jumio.startDocumentVerification(
configuration: DocumentVerificationConfiguration(
// 根据你的需求配置相关参数
allowedDocumentTypes: [
DocumentType.driversLicense,
DocumentType.passport,
// 其他支持的文档类型
],
countryCodes: ['US'], // 支持的国家代码列表
// 其他可选配置参数
),
listener: (event) {
// 处理身份验证过程中的事件,比如扫描进度、错误信息等
print('Jumio event: $event');
},
);
// 处理身份验证结果
if (result.isVerified) {
print('Document is verified!');
// 可以在这里处理验证成功后的逻辑
} else {
print('Document verification failed.');
// 可以在这里处理验证失败后的逻辑
}
} catch (e) {
// 处理错误
print('Error during Jumio verification: $e');
}
},
child: Text('Start Jumio Verification'),
),
),
);
}
}
请注意,上述代码是一个简化的示例,实际使用中你可能需要根据Jumio SDK的文档来调整配置参数,并处理更多的身份验证流程和结果。
另外,确保你已经在Jumio开发者门户中注册并获取了必要的API密钥和秘密,以及配置了你的应用信息。
最后,不要忘记在发布应用前将环境从JumioEnvironment.sandbox
切换到JumioEnvironment.production
。