博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS --- Touch ID指纹解锁
阅读量:4522 次
发布时间:2019-06-08

本文共 11397 字,大约阅读时间需要 37 分钟。

https://www.cnblogs.com/ljmaque/p/TouchID.html

最近在项目中刚好用到了TouchId指纹解锁功能,之前也没有接触过,立马百度看看究竟是要如何使用,发现其实也不是很复杂。

文章后面有封装的工具方法,可以直接copy使用。

下面开始跟大家分享一下:

一、使用要点:

(1)需要导入库 LocalAuthentication.framework

(2)引入头文件 #import <LocalAuthentication/LocalAuthentication.h>
(3)指纹解锁只支持iOS 8及以上的版本
(4)如果指纹验证多次错误会被锁定,只能通过输入手机密码来重新启用。iOS 9 提供了一个方法,可以直接调起密码输入界面。
(5)所有操作必须要回到主线程,因为系统的验证是在子线程。
(6)所有的错误处理是通过一个枚举来判断处理的,具体作用看注释

二、代码要点

(1)这是判断系统版本是否大于iOS 8

if (!(MQ_CURRENT_DEVICE_SYSTEM_VERSION >= 8.0)) {        result(NO, MQ_TOUCHID_ERROR_SYSTEM_NOT_SUPPORT);        return; } (2)判断是否可用
// 返回bool值[authenContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]

3)下面的就是重要的点 :

指纹解锁多次失败以后,系统会锁定TouchID硬件必须通过输入手机密码来解锁,如果系统是iOS8的话,TouchID被锁定以后只能通过重启手机来重新开启。

//系统提供的两个验证的枚举typedef NS_ENUM(NSInteger, LAPolicy){    LAPolicyDeviceOwnerAuthenticationWithBiometrics NS_ENUM_AVAILABLE(NA, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0) = kLAPolicyDeviceOwnerAuthenticationWithBiometrics,    LAPolicyDeviceOwnerAuthentication NS_ENUM_AVAILABLE(10_11, 9_0) = kLAPolicyDeviceOwnerAuthentication} NS_ENUM_AVAILABLE(10_10, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0); kLAPolicyDeviceOwnerAuthentication 这个值只有在iOS9.0及以后才可以使用,利用这个值可以调出输入密码来解锁TouchID的界面。
[authenContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics                  localizedReason:TOUCHID_NOTICE_MESSAGE                            reply:^(BOOL success, NSError * _Nullable error) {                                if (success) {                                  //已经重新解锁Touchid                                }  }];
开始指纹解锁代码
[authenContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics                  localizedReason:TOUCHID_NOTICE_MESSAGE                            reply:^(BOOL success, NSError * _Nullable error) {                                if (success) {                                   // 解锁成功                                }                             }]; (4)看看系统的错误枚举
typedef NS_ENUM(NSInteger, LAError){    /// Authentication was not successful, because user failed to provide valid credentials.    LAErrorAuthenticationFailed = kLAErrorAuthenticationFailed,        /// Authentication was canceled by user (e.g. tapped Cancel button).    LAErrorUserCancel = kLAErrorUserCancel,        /// Authentication was canceled, because the user tapped the fallback button (Enter Password).    LAErrorUserFallback = kLAErrorUserFallback,        /// Authentication was canceled by system (e.g. another application went to foreground).    LAErrorSystemCancel = kLAErrorSystemCancel,        /// Authentication could not start, because passcode is not set on the device.    LAErrorPasscodeNotSet = kLAErrorPasscodeNotSet,    /// Authentication could not start, because Touch ID is not available on the device.    LAErrorTouchIDNotAvailable NS_ENUM_DEPRECATED(10_10, 10_13, 8_0, 11_0, "use LAErrorBiometryNotAvailable") = kLAErrorTouchIDNotAvailable,    /// Authentication could not start, because Touch ID has no enrolled fingers.    LAErrorTouchIDNotEnrolled NS_ENUM_DEPRECATED(10_10, 10_13, 8_0, 11_0, "use LAErrorBiometryNotEnrolled") = kLAErrorTouchIDNotEnrolled,    /// Authentication was not successful, because there were too many failed Touch ID attempts and    /// Touch ID is now locked. Passcode is required to unlock Touch ID, e.g. evaluating    /// LAPolicyDeviceOwnerAuthenticationWithBiometrics will ask for passcode as a prerequisite.    LAErrorTouchIDLockout NS_ENUM_DEPRECATED(10_11, 10_13, 9_0, 11_0, "use LAErrorBiometryLockout")        __WATCHOS_DEPRECATED(3.0, 4.0, "use LAErrorBiometryLockout") __TVOS_DEPRECATED(10.0, 11.0, "use LAErrorBiometryLockout") = kLAErrorTouchIDLockout,    /// Authentication was canceled by application (e.g. invalidate was called while    /// authentication was in progress).    LAErrorAppCancel NS_ENUM_AVAILABLE(10_11, 9_0) = kLAErrorAppCancel,    /// LAContext passed to this call has been previously invalidated.    LAErrorInvalidContext NS_ENUM_AVAILABLE(10_11, 9_0) = kLAErrorInvalidContext,    /// Authentication could not start, because biometry is not available on the device.    LAErrorBiometryNotAvailable NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryNotAvailable,    /// Authentication could not start, because biometry has no enrolled identities.    LAErrorBiometryNotEnrolled NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryNotEnrolled,    /// Authentication was not successful, because there were too many failed biometry attempts and    /// biometry is now locked. Passcode is required to unlock biometry, e.g. evaluating    /// LAPolicyDeviceOwnerAuthenticationWithBiometrics will ask for passcode as a prerequisite.    LAErrorBiometryLockout NS_ENUM_AVAILABLE(10_13, 11_0) __WATCHOS_AVAILABLE(4.0) __TVOS_AVAILABLE(11.0) = kLAErrorBiometryLockout,        /// Authentication failed, because it would require showing UI which has been forbidden    /// by using interactionNotAllowed property.    LAErrorNotInteractive API_AVAILABLE(macos(10.10), ios(8.0), watchos(3.0), tvos(10.0)) = kLAErrorNotInteractive,} NS_ENUM_AVAILABLE(10_10, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0);

三、这是我封装的工具类

(1)MQTouchID.h文件

////  MQTouchID.h//  Test////  Created by PasserMontanus on 2018/3/21.//  Copyright © 2018年 lgl. All rights reserved.//#import 
typedef NS_ENUM(NSInteger, MQ_TOUCHID_ERROR) { // 系统不支持 要大于 8.0 MQ_TOUCHID_ERROR_SYSTEM_NOT_SUPPORT = 0, // 验证成功 MQ_TOUCHID_ERROR_SUCCESS = 1, // 系统取消授权,如其他APP切入 MQ_TOUCHID_ERROR_SYSTEM_CANCEL = -4, // 用户取消验证Touch ID MQ_TOUCHID_ERROR_USER_CANCEL = -2, // 用户选择输入密码 MQ_TOUCHID_ERROR_USER_FALLBACK = -3, //授权失败 MQ_TOUCHID_ERROR_FAILED = -1, //系统未设置密码 这个密码在用户指纹多次验证失败的时候要用他来重新激活 MQ_TOUCHID_ERROR_PASSCODE_NOT_SET = -5, //设备Touch ID不可用,例如未打开 MQ_TOUCHID_ERROR_NOT_AVAILABLE = -6, //设备Touch ID不可用,用户没有录入指纹 MQ_TOUCHID_ERROR_NOT_ENROLLED = -7, //身份验证失败,因为它需要显示已被禁止的UI MQ_TOUCHID_ERROR_NOT_INTERACTIVE = -1004, // 设备Touch ID被锁定,输入错误的次数过多 这个时候需要密码来重新激活 MQ_TOUCHID_ERROR_LOCKOUT = -8 , //应用程序已取消身份验证 MQ_TOUCHID_ERROR_APP_CANCEL = -9, // 传递给此调用的LAContext先前已失效。 MQ_TOUCHID_ERROR_INVALID_CONTEXT = -10};typedef void(^MQTouchIDResult)(BOOL isSuccess, MQ_TOUCHID_ERROR error_code);@interface MQTouchID : NSObject/** 开始验证 TouchID 指纹解锁 (需要导入 LocalAuthentication.framework) 注意: 结果回调以后的操作都需要回到主线程 这个验证是在子线程里面执行的 */+ (void)validateTouchID:(MQTouchIDResult)result;@end (2)MQTouchID.m文件
////  MQTouchID.m//  Test////  Created by PasserMontanus on 2018/3/21.//  Copyright © 2018年 lgl. All rights reserved.//#import "MQTouchID.h"#import 
#define MQ_CURRENT_DEVICE_SYSTEM_VERSION ([[UIDevice currentDevice]systemVersion].doubleValue)static NSString * TOUCHID_NOTICE_MESSAGE = @"通过Home键验证已有的手机指纹";static NSString * TOUCHID_NOTICE_RESTART_MESSAGE = @"重新开启TouchID功能";@implementation MQTouchID+ (void)validateTouchID:(MQTouchIDResult)result { if (!(MQ_CURRENT_DEVICE_SYSTEM_VERSION >= 8.0)) { result(NO, MQ_TOUCHID_ERROR_SYSTEM_NOT_SUPPORT); return; } LAContext *authenContext = [[LAContext alloc]init]; NSError* error = nil; if ([authenContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) { // 可用 [self startValidateTouchID:authenContext result:result]; } else { // 不可用 MQ_TOUCHID_ERROR erroCode = [self errorCode:error.code]; [self processingTouchIdError:authenContext erroCode:erroCode result:result]; }}+ (void)startValidateTouchID:(LAContext *)authenContext result:(MQTouchIDResult)result { [authenContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:TOUCHID_NOTICE_MESSAGE reply:^(BOOL success, NSError * _Nullable error) { if (success) { result(YES,MQ_TOUCHID_ERROR_SUCCESS); } else { MQ_TOUCHID_ERROR erroCode = [self errorCode:error.code]; [self processingTouchIdError:authenContext erroCode:erroCode result:result]; } }];}+ (void)processingTouchIdError:(LAContext *)authenContext erroCode:(MQ_TOUCHID_ERROR)erroCode result:(MQTouchIDResult)result { if (@available(iOS 9.0, *)) { if (erroCode == MQ_TOUCHID_ERROR_LOCKOUT) { [authenContext evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:TOUCHID_NOTICE_RESTART_MESSAGE reply:^(BOOL success, NSError * _Nullable error) { if (success) { [self validateTouchID:result]; } else { result(NO, MQ_TOUCHID_ERROR_USER_CANCEL); } }]; } else { result(NO, erroCode); } } else { result(NO, erroCode); }}+ (MQ_TOUCHID_ERROR)errorCode:(NSInteger )errorCode { switch (errorCode) { case LAErrorSystemCancel:{ // 系统取消授权,如其他APP切入 return MQ_TOUCHID_ERROR_SYSTEM_CANCEL; break; } case LAErrorUserCancel:{ // 用户取消验证Touch ID return MQ_TOUCHID_ERROR_USER_CANCEL; break; } case LAErrorUserFallback:{ // 用户选择输入密码 return MQ_TOUCHID_ERROR_USER_FALLBACK; break; } case LAErrorAuthenticationFailed:{ // //授权失败 return MQ_TOUCHID_ERROR_FAILED; break; } case LAErrorPasscodeNotSet: { //系统未设置密码 这个密码在用户指纹多次验证失败的时候要用他来重新激活 return MQ_TOUCHID_ERROR_PASSCODE_NOT_SET; break; } case LAErrorTouchIDNotAvailable: { //设备Touch ID不可用,例如未打开 return MQ_TOUCHID_ERROR_NOT_AVAILABLE; break; } case LAErrorTouchIDNotEnrolled: { //设备Touch ID不可用,用户没有录入指纹 return MQ_TOUCHID_ERROR_NOT_ENROLLED; break; } case LAErrorNotInteractive: { // 身份验证失败,因为它需要显示已被禁止的UI return MQ_TOUCHID_ERROR_NOT_INTERACTIVE; break; } default:{ if (@available(iOS 9.0, *)) { if (errorCode == LAErrorTouchIDLockout) { // 设备Touch ID被锁定,输入错误的次数过多 这个时候需要密码来重新激活 return MQ_TOUCHID_ERROR_LOCKOUT; break; } else { if (errorCode == LAErrorInvalidContext) { return MQ_TOUCHID_ERROR_INVALID_CONTEXT; break; } else if (errorCode == LAErrorAppCancel) { return MQ_TOUCHID_ERROR_APP_CANCEL; break; } else { return MQ_TOUCHID_ERROR_FAILED; break; } } } else { return MQ_TOUCHID_ERROR_FAILED; break; } } }}@end

四、最后结语

(1)最后的结果回调以后的操作一定要在主线程,系统验证在子线程进行

(2)以上就是我的一点小总结,欢迎大家指正。

转载于:https://www.cnblogs.com/sundaysgarden/p/10307580.html

你可能感兴趣的文章
mybatis(二)执行CRUD操作的两种方式配置和注解
查看>>
java课程课后作业190606之计算最长英语单词链
查看>>
how to use ubus over http in openwrt 12.09
查看>>
poj 1753【枚举+dfs(位向量法)】
查看>>
【原】Eclipse中快速重写(Override)基类方法的技巧
查看>>
【Java,JNI】学习汇总
查看>>
smarty直接在模板中格式化时间的方法
查看>>
dockerd启动配置_修改IP和systemd管理
查看>>
UVA 10815 -- Andy's First Dictionary
查看>>
Spring课程 Spring入门篇 5-1 aop基本概念及特点
查看>>
mysql之一
查看>>
kindeditor 在JSP 中上传文件的配置
查看>>
[转]NuGet学习笔记(1) 初识NuGet及快速安装使用
查看>>
DRF的Filter:字段过滤,查找,排序
查看>>
一些程序在线学习网站
查看>>
SQL Server 连接字符串和身份验证 学习
查看>>
jquery ajax中的datatype属性选项值
查看>>
Centos7 安装mysql教程
查看>>
Linux下查看文件和文件夹大小
查看>>
javascript 基础知识点
查看>>