背景
使用指纹解锁,苹果有一个小例子,大体的流程是这样的:
//代码块 1
func attemptLoginWithTouchID() {
let context = LAContext();
var authError: NSError? = nil;
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "使用指纹登录", reply: { (success, evaluateError) in
if success {
// case 1: 指纹鉴定成功
}
else {
//case 2:指纹鉴定失败
}
})
}
else {
//case 3: 目前无法进行指纹识别
}
}
进行evaluatePolicy
时,如果连续三次识别不对,在 case 2
处失败一次,如果再连续识别不对两次,Touch ID 功能就会被锁定,需要输入设备密码解锁。
Apple 在 iOS 9 SDK 中,对于失败的情况,加了一条 LAErrorTouchIDLockout
,然而如果在 evaluatePolicy
的时候 Touch ID 被锁,并不会在 case 2
处失败,系统会自动弹出密码框,让用户解锁。这个过程对开发者是透明的。
但是对于 iOS 10,情况就不是这样了。主要有两点区别:
- 如果 Touch ID 已经被锁定,那么执行
canEvaluatePolicy
的时候,会返回false
,但是在 iOS 9 及以前的系统上会返回true
。 - 如果在执行
evaluatePolicy
的过程中,Touch ID 被锁定,系统不会自动调起密码框解除锁定,但是在 iOS 9 及以前的系统上会这么干。
那么现在就很尴尬了:如果在进行指纹解锁的时候,Touch ID 已经被锁定,那么就会直接跳到 case 3
,提示目前无法进行指纹识别。那用户就会说,我的指纹识别明明是好的,这个 App 太 SB !
解决方案
在进入 case 2
和 case 3
的错误状态后,进行判断。如果错误码是 LAErrorTouchIDLockout
,可以主动调起密码框解除 Touch ID 的锁定。以下是解除锁定的代码:
//代码块 2
func unlockTouchID() {
let context = LAContext();
var authError: NSError? = nil;
if #available(iOS 9.0, *) {
if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &authError) {
context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "需要您的密码,才能启用 Touch ID", reply: { (success, evaluateError) in
if success {
// Touch ID 解锁成功,重新尝试指纹登录
}
})
}
} else {
// Fallback on earlier versions, do nothing...
}
}
如有错误请指正。
网友评论