iOS 10 的那些坑之指纹解锁

背景

使用指纹解锁,苹果有一个小例子,大体的流程是这样的:

//代码块 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 2case 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...
        }
    }

如有错误请指正。

你可能感兴趣的:(iOS 10 的那些坑之指纹解锁)