mapanguan

导航

iOS TouchID & FaceID

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识别,而且我相信按照苹果的尿性,一定会这么做的。

posted on 2019-04-04 14:34  mapanguan  阅读(354)  评论(0编辑  收藏  举报