1. 手势
手势的代码有很多,可以参考支付宝或者其他人写的。
手势/指纹登陆是为了省去输入密码的麻烦。参考了中国银行信用卡App --"缤纷生活",截图如下
1. 在登陆成功的情况下才能进入 “设置-账号与安全” 设置手势/指纹,未登陆时 见图10
2. 登陆成功时会提示你是否设置辅助登陆密码,也就是手势/指纹 ,见图1
3. 在“设置-账号与安全” 中点击开关,会进入到密码验证,如果已有手势,则弹出手势验证,见图2,3,4,5
4. 手势绘制需要重复绘制2次,录入成功之后回到开关界面,开关打开,见图6
5. 图8,是杀掉App,再次打开App,可见用户数据都清空了
6. 图9,有注册,切换登录方式这两个,目的就是为了给不同账号登陆
再看这个,我关闭了所有网络,此时用手势快捷登陆,会提示网络故障,由此可以看看出,手势验证成功之后,他立即发送了一个登陆的请求。
包括图9中这个用户名,可能还有密码,都会存入沙盒。
2. 指纹
而指纹验证,验证成功了在沙盒存一个标志就可以了。
一般指纹验证的时候3次失败了,会有有一个失败的回调,指纹弹窗消失,需要重新使用evaluatePolicy...方法唤起弹窗。5次失败则需要输入手机密码,然后再次唤起弹窗。
注意使用evaluatePolicy...方法的回调里面如果要操作UI,一定要切换回主线程。
这里参考https://github.com/ITHanYong/TouchID.git把指纹验证的代码封装到一个管理类中,然后回调用通知发出去。在使用的地方,就是要弹出的地方调用就可以了。少走很多弯路。
TouchIDManager.h
// // WLFTouchIDManager.h // WLFApp // // Created by udc on 2020/1/10. // Copyright © 2020 xxx. All rights reserved. // #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface WLFTouchIDManager : NSObject // 当识别出现每一种情况是会发出通知 + (void)validateTouchID; @end /* * 授权成功 */ UIKIT_EXTERN NSString *const ValidateTouchIDSuccess; /* * 取消按钮 */ UIKIT_EXTERN NSString *const ValidateTouchIDCancel; /* * 输入密码 */ UIKIT_EXTERN NSString *const ValidateTouchIDInputPassword; /* * 授权失败 */ UIKIT_EXTERN NSString *const ValidateTouchIDAuthenticationFailed; /* * 设备不可用 */ UIKIT_EXTERN NSString *const ValidateTouchIDNotAvailable; /* * 设备未设置指纹 */ UIKIT_EXTERN NSString *const ValidateTouchIDNotEnrolled; /* * 设备未设置密码 */ UIKIT_EXTERN NSString *const ValidateTouchIDErrorPasscodeNotSet; /* * 指纹设备被锁定 */ UIKIT_EXTERN NSString *const ValidateTouchIDLockout; NS_ASSUME_NONNULL_END
TouchIDManager.m
// // WLFTouchIDManager.m // WLFApp // // Created by udc on 2020/1/10. // Copyright © 2020 xxx. All rights reserved. // #import "WLFTouchIDManager.h" #import <LocalAuthentication/LocalAuthentication.h> #define DeviceVersion [[UIDevice currentDevice]systemVersion].doubleValue /* * 授权成功 */ NSString *const ValidateTouchIDSuccess = @"ValidateTouchIDSuccess"; /* * 取消按钮 */ NSString *const ValidateTouchIDCancel = @"ValidateTouchIDCancel"; /* * 输入密码 */ NSString *const ValidateTouchIDInputPassword = @"ValidateTouchIDInputPassword"; /* * 授权失败 */ NSString *const ValidateTouchIDAuthenticationFailed = @"ValidateTouchIDAuthenticationFailed"; /* * 设备指纹不可用 */ NSString *const ValidateTouchIDNotAvailable = @"ValidateTouchIDNotAvailable"; /* * 设备未设置指纹 */ NSString *const ValidateTouchIDNotEnrolled = @"ValidateTouchIDNotEnrolled"; /* * 设备未设置密码 */ NSString *const ValidateTouchIDErrorPasscodeNotSet = @"ValidateTouchIDErrorPasscodeNotSet"; /* * 指纹设备被锁定 */ NSString *const ValidateTouchIDLockout = @"ValidateTouchIDLockout"; @implementation WLFTouchIDManager + (void)validateTouchID { // 判断系统是否是iOS8.0以上 8.0以上可用 if (!([[UIDevice currentDevice]systemVersion].doubleValue >= 8.0)) { NSLog(@"系统不支持"); return; } // 创建LAContext对象 LAContext *authenticationContext = [[LAContext alloc]init]; NSError *error = nil; authenticationContext.localizedFallbackTitle = @""; [authenticationContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]; if (error.code == LAErrorTouchIDLockout && DeviceVersion >= 9.0) { [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDLockout object:nil]; [authenticationContext evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:@"重新开启TouchID功能" reply:^(BOOL success, NSError * _Nullable error) { if (success) { [self validateTouchID]; } }]; return; } [authenticationContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"通过Home键验证已有手机指纹" reply:^(BOOL success, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ // 指纹识别错误调用分为以下情况, // 点击取消按钮 : domain = com.apple.LocalAuthentication code = -2 // 点击输入密码按钮 : domain = com.apple.LocalAuthentication code = -3 // 输入密码重新进入指纹系统 : domain = com.apple.LocalAuthentication code = -8 // 指纹三次错误 : domain = com.apple.LocalAuthentication code = -1 // 指纹验证成功 : error = nil if (error) { switch (error.code) { case LAErrorAuthenticationFailed: NSLog(@"LAErrorAuthenticationFailed");//-1 [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDAuthenticationFailed object:nil]; break; case LAErrorUserCancel: // 点击取消按钮 [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDCancel object:nil]; break; case LAErrorUserFallback: // 用户点击输入密码按钮 [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDInputPassword object:nil]; break; case LAErrorPasscodeNotSet: //没有在设备上设置密码 [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDErrorPasscodeNotSet object:nil]; break; case LAErrorTouchIDNotAvailable: [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDNotAvailable object:nil]; //设备不支持TouchID break; case LAErrorTouchIDNotEnrolled: [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDNotEnrolled object:nil]; break; //设备没有注册TouchID case LAErrorTouchIDLockout: [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDLockout object:nil]; if (DeviceVersion >= 9.0) { [self validateTouchID]; } break; default: break; } return ; } // 说明验证成功,如果要刷新UI必须在这里回到主线程 [[NSNotificationCenter defaultCenter]postNotificationName:ValidateTouchIDSuccess object:nil]; }); }]; } @end