由于接下来的项目需要接触到触控ID以及面容ID支付,发现API调用简单但是支付宝微信等还做了新旧录用信息对比evaluatedPolicyDomainState的逻辑(或许不是这么简单),so简单封装一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| ////////// .h file #import <Foundation/Foundation.h> @interface LocalAuthManager : NSObject + (instancetype)sharedInstance; - (BOOL)isSupportTouchID; - (BOOL)isSupportFaceID; - (void)showAuthIDWithDescribe:(NSString *)describe block:(void (BOOL success, NSError * _Nullable error))block; - (void)setCurrentUserAuthDataWithIdentity:(NSString *)identity; - (NSData *)currentUserAuthData:(NSString *)identity; @end ////////.m file #import "LocalAuthManager.h" #import <LocalAuthentication/LocalAuthentication.h> #import "SAMKeychain.h" #import <UIKit/UIKit.h>
#define iPhoneX (UIScreen.mainScreen.bounds.size.width >= 375.f && UIScreen.mainScreen.bounds.size.height >= 812.f) #define Auth_ID_DATA_SERVICE @"Auth_ID_DATA_SERVICE"
@implementation LocalAuthManager
static LocalAuthManager *_instance;
#pragma mark - 单例 + (instancetype)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (_instance == nil) { _instance = [[super allocWithZone:NULL] init]; } }); return _instance; } +(instancetype)allocWithZone:(struct _NSZone *)zone { return [self sharedInstance]; } -(id)copyWithZone:(NSZone *)zone { return _instance; } -(id)mutableCopyWithZone:(NSZone *)zone { return _instance; }
#pragma mark - 判断是否支持触控ID - (BOOL)isSupportTouchID{ LAContext *laContext = [[LAContext alloc] init]; NSError *error = nil; //LAPolicyDeviceOwnerAuthenticationWithBiometrics判断TouchID和FaceID [laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]; if (error.code == LAErrorTouchIDNotAvailable) return NO; return YES; } #pragma mark - 判断是否支持面容ID - (BOOL)isSupportFaceID{ if (iPhoneX && [UIDevice currentDevice].systemVersion.doubleValue >= 11.0) return YES; return NO; } #pragma mark - 显示验证 - (void)showAuthIDWithDescribe:(NSString *)describe block:(void (BOOL success, NSError * _Nullable error))block{ if (!describe) { if (iPhoneX) { describe = @"验证已有面容"; }else{ describe = @"通过Home键验证已有指纹"; } } if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"系统版本低于8.0"); }); return; } LAContext *context = [[LAContext alloc] init]; NSError *error; context.localizedFallbackTitle = @"输入密码"; if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) { [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:describe reply:^(BOOL success, NSError * _Nullable error) { block(success,error); }]; } else { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前设备不支持TouchID/FaceID"); }); } } #pragma mark - 根据当前用户标识的保存TouchID/FaceID信息 - (void)setCurrentUserAuthDataWithIdentity:(NSString *)identity { LAContext *context = [[LAContext alloc] init]; NSError *error; if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) { NSLog(@"save authe error:%@",error); return; } if (identity && context.evaluatedPolicyDomainState) { [SAMKeychain setPasswordData:context.evaluatedPolicyDomainState forService:Auth_ID_DATA_SERVICE account:identity error:&error]; } } #pragma mark - 根据当前用户标识的获取TouchID/FaceID信息 - (NSData *)currentUserAuthData:(NSString *)identity { return [SAMKeychain passwordDataForService:Auth_ID_DATA_SERVICE account:identity]; }
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| typedef NS_ENUM(NSInteger, LAError) { LAErrorAuthenticationFailed, // 验证信息出错 LAErrorUserCancel // 用户取消了验证 LAErrorUserFallback // 用户点击了手动输入密码的按钮 LAErrorSystemCancel // 被系统取消,就是说你现在进入别的应用了,不在刚刚那个页面,所以没法验证 LAErrorPasscodeNotSet // 用户没有设置文本密码 LAErrorTouchIDNotAvailable // 用户设备不支持TouchID LAErrorTouchIDNotEnrolled // 用户没有设置手指指纹 LAErrorTouchIDLockout // 用户错误次数被锁了 LAErrorAppCancel // 在验证中被其他app中断 LAErrorInvalidContext // 请求验证出错 LAErrorBiometryNotAvailable // 多次验证(T&F二者)失败被锁定 LAErrorBiometryNotEnrolled // 用户没有设置触控ID、面容ID LAErrorBiometryLockout // 触控ID、面容ID被锁了 LAErrorNotInteractive // 验证失败,使用了禁止UI } NS_ENUM_AVAILABLE(10_10, 8_0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0);
|
thanks for your reading~