iOS TouchID and FaceID

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
/**
* .h 继承自 LAContext
* TouchID/FaceID 状态
*/
typedef NS_ENUM(NSUInteger, XyAuthIDState){

/**
* 当前设备不支持TouchID/FaceID
*/
XyAuthIDStateNotSupport = 0,
/**
* TouchID/FaceID 验证成功
*/
XyAuthIDStateSuccess = 1,

/**
* TouchID/FaceID 验证失败
*/
XyAuthIDStateFail = 2,
/**
* TouchID/FaceID 被用户手动取消
*/
XyAuthIDStateUserCancel = 3,
/**
* 用户不使用TouchID/FaceID,选择手动输入密码
*/
XyAuthIDStateInputPassword = 4,
/**
* TouchID/FaceID 被系统取消 (如遇到来电,锁屏,按了Home键等)
*/
XyAuthIDStateSystemCancel = 5,
/**
* TouchID/FaceID 无法启动,因为用户没有设置密码
*/
XyAuthIDStatePasswordNotSet = 6,
/**
* TouchID/FaceID 无法启动,因为用户没有设置TouchID/FaceID
*/
XyAuthIDStateTouchIDNotSet = 7,
/**
* TouchID/FaceID 无效
*/
XyAuthIDStateTouchIDNotAvailable = 8,
/**
* TouchID/FaceID 被锁定(连续多次验证TouchID/FaceID失败,系统需要用户手动输入密码)
*/
XyAuthIDStateTouchIDLockout = 9,
/**
* 当前软件被挂起并取消了授权 (如App进入了后台等)
*/
XyAuthIDStateAppCancel = 10,
/**
* 当前软件被挂起并取消了授权 (LAContext对象无效)
*/
XyAuthIDStateInvalidContext = 11,
/**
* 系统版本不支持TouchID/FaceID (必须高于iOS 8.0才能使用)
*/
XyAuthIDStateVersionNotSupport = 12
};

@interface XyAuthID : LAContext

typedef void (^XyAuthIDStateBlock)(XyAuthIDState state, NSError *error);

/**
* 启动TouchID/FaceID进行验证
* @param describe TouchID/FaceID显示的描述
* @param block 回调状态的block
*/
- (void)xy_showAuthIDWithDescribe:(NSString *)describe block:(XyAuthIDStateBlock)block;

@end
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
-------------本文结束感谢您的阅读-------------
最近的文章

iOS 证书转换相关命令

证书有效期:1openssl x509 -in xxx.pem -noout -dates生成pem格式的证书:1openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes …

继续阅读
更早的文章

iOS 悬浮按钮

新建继承于UIWindow的类.h文件如下123456789101112131415typedef void(^ClickBlock)(NSInteger i);@interface GSLFloatingView : UIWindow@property (nonatomic, copy) Clic …

继续阅读