flutter - 编写 阿里云-金融级实名认证插件

项目中有实名认证的需求,用户上传身份证反正面,进行人脸核验,后台集成的是阿里云的金融级实名认证SDK,巧合的是阿里云没有packages 需要自己造轮子。
废话不多少,直接上代码:

新建项目 ProjectType = Plugin

创建完成后,会自动为我们搭建好通信结构

编写Dart中间件

在项目下的 lib下的dart文件中定义我们的通信方法。
实名认证 需要两个方法 分别是:
获取本机信息发送给服务器 返回ID
调用实名认证,以及返回结果

import 'dart:async';

import 'package:flutter/services.dart';

class AliAuthPerson {
  static const MethodChannel _channel = MethodChannel('ali_auth_person');

  static Future<String?> get platformVersion async {
    final String? version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }

  static const EventChannel _eventChannel =
      EventChannel("ali_auth_person_plugin_event");

  ///认证结果返回监听
  static addListen(Function(String resData) onEvent) {
    _eventChannel.receiveBroadcastStream().listen((data) {
      onEvent(data);
    });
  }

  ///实名认证
  static Future<void> verify(String certifyId) async {
    await _channel.invokeMethod("verify", certifyId);
  }

  ///获取本机参数
  static Future<String> getMetaInfos() async {
    return await _channel.invokeMethod("getMetaInfos");
  }
}

Andriod 集成

参考:阿里云官方解说:https://help.aliyun.com/document_detail/163105.html

复制粘贴 AAR文件
将SDK的中的 AAR放入项目内
在这里插入图片描述导入声明

dependencies {
    compileOnly files("$flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar")
    //阿里云实人认证SDK
    implementation(name:'android-aliyunbasicstl-sdk-release-1.6.0-20220414192835', ext:'aar')
    implementation(name:'android-aliyuncomm-sdk-release-1.6.0-20220414192835', ext:'aar')
    implementation(name:'Android-AliyunDevice-FG-10022.2', ext:'aar')
    implementation(name:'android-aliyunface-sdk-release-1.6.0-20220414192835', ext:'aar')
    implementation(name:'android-aliyunocr-sdk-release-1.6.0-20220414192835', ext:'aar')
    implementation(name:'APSecuritySDK-DeepSec-7.0.1.20211220', ext:'aar')
    implementation(name:'photinus-1.0.1.220217162928', ext:'aar')
    implementation(name:'tygerservice-1.0.0.220407164130', ext:'aar')

    //三方依赖库
    implementation 'com.squareup.okhttp3:okhttp:3.11.0'
    implementation 'com.squareup.okio:okio:1.14.0'
    implementation 'com.alibaba:fastjson:1.2.62'
    implementation 'com.aliyun.dpa:oss-android-sdk:+'
}

编写Android 适配方法
代码如下

package com.lrs.ali_auth_person.ali_auth_person;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.aliyun.aliyunface.api.ZIMCallback;
import com.aliyun.aliyunface.api.ZIMFacade;
import com.aliyun.aliyunface.api.ZIMFacadeBuilder;
import com.aliyun.aliyunface.api.ZIMResponse;

import org.json.JSONException;
import org.json.JSONObject;

import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;

/**
 * AliAuthPersonPlugin
 */
public class AliAuthPersonPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity
    private MethodChannel channel;
    // 上下文 Context
    private Context context;
    private Activity activity;
    private EventChannel.EventSink eventSink;


    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "ali_auth_person");
        channel.setMethodCallHandler(this);
        context = flutterPluginBinding.getApplicationContext();

        final EventChannel eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "ali_auth_person_plugin_event");
        eventChannel.setStreamHandler(new EventChannel.StreamHandler() {
            @Override
            public void onListen(Object o, EventChannel.EventSink eventSink) {
                AliAuthPersonPlugin.this.eventSink = eventSink;
            }

            @Override
            public void onCancel(Object o) {
                AliAuthPersonPlugin.this.eventSink = null;
            }
        });
    }


    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        if (call.method.equals("getPlatformVersion")) {
            result.success("Android " + android.os.Build.VERSION.RELEASE);
        } else if (call.method.equals("getMetaInfos")) {
            //获取本机参数
            String metaInfo = ZIMFacade.getMetaInfos(context);
            result.success(metaInfo);
        } else if (call.method.equals("verify")) {
            //进行实名认证
            String certifyId = call.arguments();
            if (certifyId == null || certifyId.isEmpty()) {
                Toast.makeText(context, "certifyId 不能为空!", Toast.LENGTH_SHORT).show();
                return;
            }
            Toast.makeText(context, "" + certifyId, Toast.LENGTH_SHORT).show();
            ZIMFacade.install(context);
            ZIMFacade zimFacade = ZIMFacadeBuilder.create(activity);
            zimFacade.verify(certifyId, true, new ZIMCallback() {
                @Override
                public boolean response(ZIMResponse response) {
                    // TODO:根据实人认证回调结果处理自身的业务。
                    JSONObject jsonObject = new JSONObject();
                    try {
                        jsonObject.put("code", response.code);
                        jsonObject.put("msg", response.msg);
                        jsonObject.put("deviceToken", response.deviceToken);
                        jsonObject.put("videoFilePath", response.videoFilePath);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    eventSink.success(jsonObject.toString());
                    return true;
                }
            });
        } else {
            result.notImplemented();
        }
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
    }

    @Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
        activity = binding.getActivity();
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {

    }

    @Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {

    }

    @Override
    public void onDetachedFromActivity() {

    }
}

Ios集成

参考:阿里云官方解说:https://help.aliyun.com/document_detail/163106.html

复制粘贴 frameworks
在这里插入图片描述导入声明

编写 .podspec文件 如下

#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint ali_auth_person.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
  s.name             = 'ali_auth_person'
  s.version          = '0.0.1'
  s.summary          = 'A new Flutter project.'
  s.description      = <<-DESC
A new Flutter project.
                       DESC
  s.homepage         = 'http://example.com'
  s.license          = { :file => '../LICENSE' }
  s.author           = { 'Your Company' => 'email@example.com' }
  s.source           = { :path => '.' }
  s.source_files = 'Classes/**/*'
  s.public_header_files = 'Classes/**/*.h'
  s.dependency 'Flutter'
  s.platform = :ios, '9.0'

  s.vendored_frameworks = 'frameworks/AliyunIdentityManager.framework','frameworks/AliyunOSSiOS.framework','frameworks/APBToygerFacade.framework','frameworks/APPSecuritySDK.framework','frameworks/BioAuthAPI.framework','frameworks/BioAuthEngine.framework','frameworks/deviceiOS.framework','frameworks/MPRemoteLogging.framework','frameworks/OCRDetectSDKForTech.framework','frameworks/ToygerNative.framework','frameworks/ToygerService.framework','frameworks/ZolozIdentityManager.framework','frameworks/ZolozMobileRPC.framework','frameworks/ZolozOpenPlatformBuild.framework','frameworks/ZolozSensorServices.framework','frameworks/ZolozUtility.framework'

  s.frameworks = 'CoreGraphics','Accelerate','SystemConfiguration','AssetsLibrary','CoreTelephony','QuartzCore','CoreFoundation','CoreLocation','ImageIO','CoreMedia','CoreMotion','AVFoundation','WebKit','AudioToolbox','CFNetwork','MobileCoreServices','AdSupport'

  s.libraries = 'resolv','z','c++.1','c++abi','z.1.2.8'

  s.resource_bundles = { 'Resources' => 'frameworks/*.framework/*.bundle' }


  # Flutter.framework does not contain a i386 slice.
  # s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
  s.swift_version = '5.0'

  # s.ios.deployment_target = '9.0'
  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
  s.pod_target_xcconfig = {'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64'   }
  s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
end

编写IOS适配方法

import Flutter
import UIKit
import AliyunIdentityManager

//当前视图 ViewController;
var controller : UIViewController?;
//method管道
var channel : FlutterMethodChannel?;
//event管道
var eventChannel : FlutterEventChannel?;
//回调flutter
let eventStreamHandler = EventStreamHandler()
public class SwiftAliAuthPersonPlugin: NSObject, FlutterPlugin{

  public static func register(with registrar: FlutterPluginRegistrar) {
    channel = FlutterMethodChannel(name: "ali_auth_person", binaryMessenger: registrar.messenger())
    let instance = SwiftAliAuthPersonPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel!)
    eventChannel = FlutterEventChannel(name: "ali_auth_person_plugin_event", binaryMessenger: registrar.messenger())
    eventChannel?.setStreamHandler((eventStreamHandler as! FlutterStreamHandler & NSObjectProtocol))
    //初始化阿里SDK
    AliyunSdk.`init`();
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
      //获取本机参数
      if(call.method == "getMetaInfos"){
          let info  = AliyunIdentityManager.getMetaInfo();
          var jsonData: Data? = nil
          do {
              if info != nil {
                  jsonData = try JSONSerialization.data(withJSONObject: info!, options: .prettyPrinted)
              }
          } catch  _ {
              print("(parseError.localizedDescription)");
          }
          var infoData : String? = "";
          if let jsonData = jsonData {
              infoData = String(data: jsonData, encoding: .utf8)
          };
         result(infoData);
      }else if(call.method == "verify"){
          controller = UIApplication.shared.delegate?.window??.rootViewController;
          //进行实名认证
          let  certifyId : String = String(describing: call.arguments!);
          print(certifyId);
          let extParams: [String : Any] = ["currentCtr": controller!];
          AliyunIdentityManager.sharedInstance()?.verify(with: certifyId, extParams: extParams, onCompletion: { (response) in
              DispatchQueue.main.async {
                  var resString = ""
                  switch response?.code {
                  case .ZIMResponseSuccess:
                    resString = "认证成功"
                      break;
                  case .ZIMInterrupt:
                      resString = "初始化失败"
                   break
                  case .ZIMTIMEError:
                   resString = "设备时间错误"
                   break
                  case .ZIMNetworkfail:
                   resString = "网络错误"
                   break
                  case .ZIMInternalError:
                   resString = "用户退出"
                   break
                  case .ZIMResponseFail:
                   resString = "刷脸失败"
                  default:
                      resString = "未知异常"
                      break
                  }
                  eventStreamHandler.sendEvent(event: "{'code':\(response?.code)},'msg':\(resString),'deviceToken':\(response?.deviceToken),'videoFilePath':\(response?.videoFilePath)");
              }
          })
      }else{
          result("")
      }
  }
}

class EventStreamHandler: FlutterStreamHandler {
    private var eventSink:FlutterEventSink? = nil
    func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
        eventSink = events
        return nil
    }
    
    func onCancel(withArguments arguments: Any?) -> FlutterError? {
        eventSink = nil
        return nil
    }
    
    public func sendEvent(event:Any) {
        eventSink?(event)
    }
}

就此完成啦

https://github.com/lurongshuang/ali_auth_person

IOS集成的时候遇见几个问题,我截图列一下,有其他问题,联系我,我们共同成长。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/33010.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

wsl下面的子系统启用systemctl

下载地址 https://github.com/gdraheim/docker-systemctl-replacement 操作 mv /usr/bin/systemctl /usr/bin/systemctl.old #对原文件进行备份sudo scp /mnt/c/Users/Administrator/Desktop/systemctl.py /usr/bin/systemctl #把项目中的systemctl.py文件拷贝到/use/bin/ 目…

Diffusion扩散模型学习2——Stable Diffusion结构解析-以文本生成图像为例

Diffusion扩散模型学习2——Stable Diffusion结构解析 学习前言源码下载地址网络构建一、什么是Stable Diffusion&#xff08;SD&#xff09;二、Stable Diffusion的组成三、生成流程1、文本编码2、采样流程a、生成初始噪声b、对噪声进行N次采样c、单次采样解析I、预测噪声II、…

安装mmdetection2.22(windows下)

安装mmdetection2.22 确定版本安装mmcv1.4安装mmdetection测试方案1方案2 确定版本 安装mmcv1.4 首先.cuda,pytorch得安装好&#xff0c;这里我拷贝pt1.8虚拟环境 安装mmcv1.4 安装mmdetection 参考文章 下载 cd E:\Code\mmdetection\mmdetection-2.22.0 pip install -r…

MATLAB 之 低层绘图操作和光照及材质处理

这里写目录标题 一、低层绘图操作1. 曲线对象2. 曲面对象3. 文本对象4. 其他核心对象4.1 区域块对象4.2 方框对象 二、光照和材质处理1. 光照处理2. 材质处理2.1 图形对象的反射特性2.2 material 函数 一、低层绘图操作 MATLAB 将曲线、曲面、文本等图形均视为对象&#xff0c…

【MySQL数据库 | 第十九篇】SQL性能分析工具

目录 前言&#xff1a; SQL执行频率&#xff1a; 慢查询日志&#xff1a; profile&#xff1a; profile各个指令&#xff1a; 总结&#xff1a; 前言&#xff1a; 本篇我们将为大家讲解SQL性能的分析工具&#xff0c;而只有熟练的掌握了性能分析的工具&#xff0c;才可以更…

【Spring Cloud Sleuth 分布式链路跟踪】 —— 每天一点小知识

&#x1f4a7; S p r i n g C l o u d S l e u t h 分布式链路跟踪 \color{#FF1493}{Spring Cloud Sleuth 分布式链路跟踪} SpringCloudSleuth分布式链路跟踪&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云…

力扣 257. 二叉树的所有路径

题目来源&#xff1a;https://leetcode.cn/problems/binary-tree-paths/description/ C题解1&#xff1a;使用递归&#xff0c;声明了全局变量result&#xff0c;遇到叶子节点就将字符串添加到result中。 递归三步法&#xff1a; 1. 确认传入参数&#xff1a;当前节点已有路径…

如何保证API接口的安全性

API接口的安全性是非常重要的&#xff0c;以下是一些保证API接口安全性的措施&#xff1a; 用户认证、授权&#xff1a;接口的调用者必须提供有效的身份认证信息&#xff0c;包括用户名、密码、密钥等&#xff0c;以保证接口的调用者的身份有效性。同时&#xff0c;需要在接口的…

echarts的基础知识和配置项

异步数据加载和更新 ECharts 中在异步更新数据的时候需要通过series的name属性对应到相应的系列&#xff0c;如果没有name&#xff0c;series就会根据数组的顺序索引&#xff0c;把数据跟前面的配置对应上 loading动画 如果数据加载时间较长&#xff0c;一个空的坐标轴放在画…

基于深度学习的高精度人脸口罩检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度人脸口罩检测识别系统可用于日常生活中或野外来检测与定位人脸口罩目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的人脸口罩目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5…

《面试1v1》Redis持久化

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

<Oracle>《Linux 下安装Oracle数据库 - Oracle 19C By CentOS 8 》(第一部分)

《Linux 下安装Oracle数据库 - Oracle 19C By CentOS 8 》&#xff08;第一部分&#xff09; 1 说明1.1 前言1.2 资源下载 2 安装步骤2.1 上传安装包2.2 下载数据库预安装包2.3 安装数据库预安装包 1 说明 1.1 前言 本文是Linux系统命令行模式安装Oracle数据库的学习实验记录…

【C++实现二叉树的遍历】

目录 一、二叉树的结构二、二叉树的遍历方式三、源码 一、二叉树的结构 二、二叉树的遍历方式 先序遍历&#xff1a; 根–>左–>右中序遍历&#xff1a; 左–>根–>右后序遍历&#xff1a;左–>右–>根层次遍历&#xff1a;顶层–>底层 三、源码 注&am…

云原生监控平台 Prometheus 从部署到监控

1.监控系统架构设计 角色 节点 IP地址 监控端 Prometheus &#xff0c;Grafana&#xff0c;node_exporter &#xff0c;Nginx 47.120.35.251 被监控端1 node_exporter 47.113.177.189 被监控端2 mysqld_exporter&#xff0c;node_exporter&#xff0c;Nginx&#xff…

ivx低代码开发平台

前言 低代码开发平台&#xff08;Low-Code Development Platform, LCDS&#xff09;为企业和开发者提供了高效的应用开发方式。在2023年&#xff0c;中国的低代码开发平台正在快速发展&#xff0c;以下是其中最受关注的十大平台&#xff1a; iVX&#xff1a;iVX是一款新型的低代…

react总结

一、React 入门 1.1 特点 高性能、声明式、组件化、单向响应的数据流、JSX扩展、灵活 1.2 React初体验 <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport&quo…

跨越时空限制,酷暑天气用VR看房是一种什么体验?

近年来&#xff0c;全球厄尔尼诺现象越来越频繁&#xff0c;夏季温度不断创下新高&#xff0c;持续大范围的高温天气让人们对出门“望而生畏”。很多购房者也不愿意在如此酷暑期间&#xff0c;四处奔波看房&#xff0c;酷暑天气让带看房效率大大降低&#xff0c;更有新闻报道&a…

VSCode+GDB+Qemu调试ARM64 linux内核

俗话说&#xff0c;工欲善其事 必先利其器。linux kernel是一个非常复杂的系统&#xff0c;初学者会很难入门。 如果有一个方便的调试环境&#xff0c;学习效率至少能有5-10倍的提升。 为了学习linux内核&#xff0c;通常有这两个需要 可以摆脱硬件&#xff0c;方便的编译和…

基于open62541库的OPC UA协议节点信息查询及多节点数值读写案例实践

目录 一、OPC UA协议简介 二、open62541库简介 三、 opcua协议的多点查询、多点读写案例服务端opcua_server 3.1 opcua_server工程目录 3.2 程序源码 3.3 工程组织文件 3.4 编译及启动 四、opcua协议的多点查询、多点读写案例客户端opcua_client 4.1 opcua_client工程目录 4…

使用 Jetpack Compose 构建 Spacer

欢迎阅读本篇关于如何使用 Jetpack Compose 构建 Spacer 的博客。Jetpack Compose 是 Google 的现代 UI 工具包&#xff0c;主要用于构建 Android 界面。其声明式的设计使得 UI 开发更加简洁、直观。 一、什么是 Spacer&#xff1f; 在 UI 设计中&#xff0c;我们通常需要在不…