import UIKit import LocalAuthentication //指纹识别必须用真机测试,并且在iOS8以上系统,如果是FaceID至少IOS11以上. class AuthenticationTool: NSObject { let lc = LAContext() func hasTouchID() -> Bool{ if NSFoundationVersionNumber < NSFoundationVersionNumber_iOS_8_0 { return false } /* 在这里简单介绍一下LAPolicy,它是一个枚举.我们根据自己的需要选择LAPolicy,它提供两个值: LAPolicyDeviceOwnerAuthenticationWithBiometrics和LAPolicyDeviceOwnerAuthentication. LAPolicyDeviceOwnerAuthenticationWithBiometrics是支持iOS8以上系统,使用该设备的TouchID进行验证,当输入TouchID验证5次失败后,TouchID被锁定,只能通过锁屏后解锁设备时输入正确的解锁密码来解锁TouchID。 LAPolicyDeviceOwnerAuthentication是支持iOS9以上系统,使用该设备的TouchID或设备密码进行验证,当输入TouchID验证5次失败后,TouchID被锁定,会触发设备密码页面进行验证。 */ lc.localizedFallbackTitle = "请输入密码" var error:NSError! if lc.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) { return false } return true } typealias TouchIDBlock = (_ result:Dictionary<String, String>) -> Void var tblock:TouchIDBlock? func authenticationTouchID(block:@escaping TouchIDBlock){ tblock = block if hasTouchID() { /*context.evaluatedPolicyDomainState用于判断设备上的指纹是否被更改, 在LAContext被创建的时候,evaluatedPolicyDomainState才生效, 可在TouchID验证成功时,将它记录下来,用于下次使用TouchID时校验,提高安全性。 */ //IOS11之后如果支持faceId也是走同样的逻辑,faceId和TouchId只能选一个 if #available(iOS 9.0, *) { lc.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "通过验证支持touchID") { (sucess, error) in if sucess{ if let block = self.tblock { block(["reason":"sucess"]) } }else{ if let erro = error as NSError?{ var reason = "" if #available(iOS 11.0, *){ switch erro.code { case LAError.biometryNotEnrolled.rawValue: reason = "TouchID 无法启动,因为用户没有设置TouchID" default: reason = "未知原因" } }else{ switch erro.code { case LAError.appCancel.rawValue: reason = "当前软件被挂起并取消了授权 (如App进入了后台等)" case LAError.invalidContext.rawValue: reason = "当前软件被挂起并取消了授权 (LAContext对象无效)" case LAError.touchIDLockout.rawValue: reason = "TouchID 被锁定(连续多次验证TouchID失败,系统需要用户手动输入密码" default: reason = "未知原因" } } block(["reason":reason]) } } } } else { lc.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "通过验证支持touchID") { (sucess, erro) in if sucess{ if let block = self.tblock { block(["reason":"sucess"]) } }else{ if let erro = erro as NSError?{ var reason = "" // Fallback on earlier versions switch erro.code { case LAError.authenticationFailed.rawValue: reason = "TouchID 验证失败" case LAError.passcodeNotSet.rawValue: reason = "TouchID 无法启动,因为用户没有设置密码" case LAError.systemCancel.rawValue: reason = "TouchID 被系统取消 (如遇到来电,锁屏,按了Home键等)" case LAError.touchIDNotAvailable.rawValue: reason = "TouchID 无效" case LAError.userCancel.rawValue: reason = "TouchID 被用户手动取消" case LAError.userFallback.rawValue: reason = "用户不使用TouchID,选择手动输入密码" default: reason = "未知原因" } block(["reason":reason]) } } } } if let block = tblock { block(["reason":"nonsupport"]) } } } }
如果想要支持FaceID识别的话,最好加上一个key:NSFaceIDUsageDescription,不加的话,确实也不会崩溃,但我觉得为了保险最好加上,防止以后iOS升级后必须要求该key才能进行FaceID识别,而且我相信按照苹果的尿性,一定会这么做的。