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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
| #import <UIKit/UIKit.h>
#define iPhoneX (UIScreen.mainScreen.bounds.size.width == 375.f && UIScreen.mainScreen.bounds.size.height == 812.f)
@implementation XyAuthID
+ (instancetype)sharedInstance { static XyAuthID *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[XyAuthID alloc] init]; }); return instance; }
- (void)xy_showAuthIDWithDescribe:(NSString *)describe block:(XyAuthIDStateBlock)block { if(!describe) { if(iPhoneX){ describe = @"验证已有面容"; }else{ describe = @"通过Home键验证已有指纹"; } }
if (NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0) {
dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"系统版本不支持TouchID/FaceID (必须高于iOS 8.0才能使用)"); block(XyAuthIDStateVersionNotSupport, nil); });
return; }
LAContext *context = [[LAContext alloc] init];
// 认证失败提示信息,为 @"" 则不提示 context.localizedFallbackTitle = @"输入密码";
NSError *error = nil;
// LAPolicyDeviceOwnerAuthenticationWithBiometrics: 用TouchID/FaceID验证 // LAPolicyDeviceOwnerAuthentication: 用TouchID/FaceID或密码验证, 默认是错误两次或锁定后, 弹出输入密码界面(本案例使用) if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error]) { [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:describe reply:^(BOOL success, NSError * _Nullable error) {
if (success) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 验证成功"); block(XyAuthIDStateSuccess, error); }); }else if(error){
if (@available(iOS 11.0, *)) { switch (error.code) { case LAErrorAuthenticationFailed:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 验证失败"); block(XyAuthIDStateFail, error); }); } break; case LAErrorUserCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 被用户手动取消"); block(XyAuthIDStateUserCancel, error); }); } break; case LAErrorUserFallback:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"用户不使用TouchID/FaceID,选择手动输入密码"); block(XyAuthIDStateInputPassword, error); }); } break; case LAErrorSystemCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 被系统取消 (如遇到来电,锁屏,按了Home键等)"); block(XyAuthIDStateSystemCancel, error); }); } break; case LAErrorPasscodeNotSet:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 无法启动,因为用户没有设置密码"); block(XyAuthIDStatePasswordNotSet, error); }); } break; //case LAErrorTouchIDNotEnrolled:{ case LAErrorBiometryNotEnrolled:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 无法启动,因为用户没有设置TouchID/FaceID"); block(XyAuthIDStateTouchIDNotSet, error); }); } break; //case LAErrorTouchIDNotAvailable:{ case LAErrorBiometryNotAvailable:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 无效"); block(XyAuthIDStateTouchIDNotAvailable, error); }); } break; //case LAErrorTouchIDLockout:{ case LAErrorBiometryLockout:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID/FaceID 被锁定(连续多次验证TouchID/FaceID失败,系统需要用户手动输入密码)"); block(XyAuthIDStateTouchIDLockout, error); }); } break; case LAErrorAppCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (如App进入了后台等)"); block(XyAuthIDStateAppCancel, error); }); } break; case LAErrorInvalidContext:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (LAContext对象无效)"); block(XyAuthIDStateInvalidContext, error); }); } break; default: break; } } else { // iOS 11.0以下的版本只有 TouchID 认证 switch (error.code) { case LAErrorAuthenticationFailed:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 验证失败"); block(XyAuthIDStateFail, error); }); } break; case LAErrorUserCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 被用户手动取消"); block(XyAuthIDStateUserCancel, error); }); } break; case LAErrorUserFallback:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"用户不使用TouchID,选择手动输入密码"); block(XyAuthIDStateInputPassword, error); }); } break; case LAErrorSystemCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 被系统取消 (如遇到来电,锁屏,按了Home键等)"); block(XyAuthIDStateSystemCancel, error); }); } break; case LAErrorPasscodeNotSet:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 无法启动,因为用户没有设置密码"); block(XyAuthIDStatePasswordNotSet, error); }); } break; case LAErrorTouchIDNotEnrolled:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 无法启动,因为用户没有设置TouchID"); block(XyAuthIDStateTouchIDNotSet, error); }); } break; case LAErrorTouchIDNotAvailable:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 无效"); block(XyAuthIDStateTouchIDNotAvailable, error); }); } break; case LAErrorTouchIDLockout:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"TouchID 被锁定(连续多次验证TouchID失败,系统需要用户手动输入密码)"); block(XyAuthIDStateTouchIDLockout, error); }); } break; case LAErrorAppCancel:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (如App进入了后台等)"); block(XyAuthIDStateAppCancel, error); }); } break; case LAErrorInvalidContext:{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前软件被挂起并取消了授权 (LAContext对象无效)"); block(XyAuthIDStateInvalidContext, error); }); } break; default: break; } } } }]; }else{ dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"当前设备不支持TouchID/FaceID"); block(XyAuthIDStateNotSupport, error); }); } }
@end
|