ios swift版touchID&faceID

2019-06-06  本文已影响0人  Henry________

FaceID和TouchID本身代码很简单,使用起来也很容易,主要是逻辑的嵌套相对复杂。
状态很多但不是所有状态都需要处理和提示,故没有列出所有枚举

enum LocalAuthStatus : Int {
    case success             //成功
    case failed              //失败
    case passwordNotSet      //未设置手机密码
    case touchidNotSet       //未设置指纹
    case touchidNotAvailable //不支持指纹
    case cancleSys           //系统取消
    case canclePer           //用户取消
    case inputNUm            //输入密码
}

从iOS11开始系统提供了当前设备支持哪种检测。
biometryType该参数返回对应类型,但是必须在canEvaluatePolicy方法之后该参数才有值。
注:支持FaceID的设备出厂最低系统版本就是iOS11.0所以,在iOS11以下只要硬件支持,则只有TouchID一种。

enum BiometryType : Int {
    case none
    case touchID
    case faceID
}
public static func getBiometryType() -> BiometryType{
        //该参数必须在canEvaluatePolicy方法后才有值
        let authContent = LAContext()
        var error: NSError?
        if authContent.canEvaluatePolicy(
        .deviceOwnerAuthenticationWithBiometrics,
        error: &error) {
            //iPhoneX出厂最低系统版本号:iOS11.0.0
            if #available(iOS 11.0, *) {
                if authContent.biometryType == .faceID {
                    return .faceID
                }else if authContent.biometryType == .touchID {
                    return .touchID
                }
            } else {
                guard let laError = error as? LAError else{
                    return .none
                }
                if laError.code != .touchIDNotAvailable {
                    return .touchID
                }
            }
        }
         return .none
    }

官方API已经把UI和交互都封装好了可以直接使用,除了一个字符串剩下的我们都只能看看。我们只需要做好验证成功、异常的处理就可以了。

let authContent = LAContext()
        //如果为空不展示输入密码的按钮
        authContent.localizedFallbackTitle = strTips
        var error: NSError?
        /*
         LAPolicy有2个参数:
         用TouchID/FaceID验证,如果连续出错则需要锁屏验证手机密码,
         但是很多app都是用这个参数,等需要输入密码解锁touchId&faceId再弃用该参数。
         优点:用户在单次使用后就可以取消验证。
         1,deviceOwnerAuthenticationWithBiometrics
         
         用TouchID/FaceID或密码验证, 默认是错误两次或锁定后, 弹出输入密码界面
         等错误次数过多验证被锁时启用该参数
         2,deviceOwnerAuthentication
         
         */
        if authContent.canEvaluatePolicy
        (.deviceOwnerAuthenticationWithBiometrics,
        error: &error) 
        {
       authContent.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
            localizedReason: strTips) {(success,error) in
                if success {
                    //evaluatedPolicyDomainState 只有生物验证成功才会有值
                    if let _ = authContent.evaluatedPolicyDomainState {
                        //如果不放在主线程回调可能会有5-6s的延迟
                        DispatchQueue.main.async {
                            print("验证成功")
                            block(.success, error)
                        }
                    }else{
                        DispatchQueue.main.async {
                            print("设备密码输入正确")
                        }
                    }
                }else{
                    guard let laError = error as? LAError else{
                        DispatchQueue.main.async {
                            print("touchID不可用")
                            block(.touchidNotAvailable,error)
                        }
                        return
                    }
                    switch laError.code {
                    case .authenticationFailed:
                        DispatchQueue.main.async {
                            print("连续三次输入错误,身份验证失败")
                            block(.failed, error)
                        }
                    case .userCancel:
                        DispatchQueue.main.async {
                            print("用户点击取消按钮。")
                            block(.canclePer, error)
                        }
                    case .userFallback:
                        DispatchQueue.main.async {
                            print("用户点击输入密码")
                            block(.inputNUm, error)
                        }
                    case .systemCancel:
                        DispatchQueue.main.async {
                            print("系统取消")
                            block(.cancleSys,error)
                        }
                    case .passcodeNotSet:
                        DispatchQueue.main.async {
                            print("用户未设置密码")
                            block(.passwordNotSet,error)
                        }
                    case .touchIDNotAvailable:
                        DispatchQueue.main.async {
                            print("touchID不可用")
                            block(.touchidNotAvailable,error)
                        }
                    case .touchIDNotEnrolled:
                        DispatchQueue.main.async {
                            print("touchID未设置指纹")
                            block(.touchidNotSet,error)
                        }
                    case .touchIDLockout:
                        DispatchQueue.main.async {
                            print("touchID输入次数过多验证被锁")
                            unlockLocalAuth()
                        }
                    default:break
                    }
                }
            }
        }else{
            print("设备不支持或验证多次后被锁定")
            unlockLocalAuth()
        }
    }
private static func unlockLocalAuth() {
        let passwordContent = LAContext()
        var error: NSError?
        if passwordContent.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error){
            passwordContent.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "需要您的密码,才能启用 Touch ID") { (success, err) in
                if success {
                    print("密码解锁成功")
                }else{
                    print(err!)
                    print(error!) } }
        }else{ }}

这就是全部的代码了,可是真正在项目中使用还需要很多逻辑,才是它真正复杂的地方。
至于生物识别在项目中该如何应用,可以去这里看看

iOS-Swift 完整登录方案(touchID&faceID&keychina)一

上一篇 下一篇

猜你喜欢

热点阅读