iOS TouchID (FaceID)集成方案

  • TouchID指纹技术是苹果2013年在iPhone5siOS7)上开始应用的。iOS7是不允许开发人员来使用TouchAPI来验证自己的应用程序。
  • iOS8开始,苹果陆续开放了Touch ID公共APITouchID的使用时“本地”的一个验证,框架给我们提供了提示用户进行身份验证的方法。我们可以使用它来认证登录,或授权访问安全敏感信息的应用程序。
TouchID常用的方法(Face ID同TouchID相同)

1. canEvaluatePolicy:error:来判断运行的设备是否支持Touch ID

2. evaluatePolicy:localizedReason:reply:来验证识别的情况,成功或失败(失败的原因以枚举值显示)

  Context.biometryType == .faceID  //是否人脸识别
1. 判断设置是否支持TouchID

通过canEvaluatePolicy:error:判断设置是否支持TouchID,返回Bool类型,true代表支持TouchID。

open func canEvaluatePolicy(_ policy: LAPolicy, error: NSErrorPointer) -> Bool

LAPolicy: 它是一个枚举,提供两个枚举值,根据需求进行选择

public enum LAPolicy : Int {
    //支持iOS8以上系统,使用该设备的TouchID进行验证,当输入TouchID验证5次失败后,TouchID被锁定,只能通过锁屏后解锁设备时输入正确的解锁密码来解锁TouchID。
    case deviceOwnerAuthenticationWithBiometrics
  //支持iOS9以上系统,使用该设备的TouchID或设备密码进行验证,当输入TouchID验证5次失败后,TouchID被锁定,会触发设备密码页面进行验证。
        case deviceOwnerAuthentication
}

Error(LAError结构体): 以下这几个错误要注意以下

/// 该设备支持TouchID,但从来没有注册过指纹,所以指纹登录不能用
    public static var touchIDNotEnrolled: LAError.Code { get }
/// 由于未在设备上设置密码,因此无法启动身份验证
    public static var passcodeNotSet: LAError.Code { get }
/// 身份验证无法开始,因为设备上没有Touch ID(可能Touch ID坏掉了)
    public static var touchIDNotAvailable: LAError.Code { get }

e.g.(示例代码中的枚举值附在文章最后)

// 如果不需要知道错误原因的话可以直接调用canEvaluatePolicy返回Bool值就可以了
static func getTouchIDStatus() -> TouchUseStatus {
        let myContext = LAContext()
        var authError: NSError?
        var status = TouchUseStatus.canNotUse
        let isCanEvaluatePolicy = myContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
                                                              error: &authError)

        if isCanEvaluatePolicy {
            status = .canUse
        } else {
            switch authError?.code {
            case LAError.touchIDNotEnrolled.rawValue:
                status = .canNotUseFingerNotEnrolled
            case LAError.passcodeNotSet.rawValue:
                status = .canNotUsePasscodeNotSet
            case LAError.touchIDNotAvailable.rawValue:
                status = .canNotAvailable
            default:
                status = .canNotUse
            }
        }
        return status
    }
2. 获取识别结果
static func authenticateWithTouchID(_ localizedReason: String,
                                 callback: @escaping (Bool, TouchAuthenticationCode) -> Void) {
        let touchStatus = getTouchIDStatus()
        if touchStatus == .canNotAvailable {
            callback(false, TouchAuthenticationCode.invalidContext)
            return
        }

        let myContext = LAContext()
        var policyType = LAPolicy.deviceOwnerAuthenticationWithBiometrics
        if #available(iOS 9.0, *) {
            policyType = LAPolicy.deviceOwnerAuthentication
        }

        myContext.evaluatePolicy(policyType,
                                 localizedReason: localizedReason) { (isSuccess, error) in
            DispatchQueue.main.async {
                if isSuccess {
                    callback(true, TouchAuthenticationCode.sucessed)
                } else {
                    guard let errorOC = error as NSError? else {
                        callback(false, TouchAuthenticationCode.defalutFailed)
                        return
                    }
                    switch errorOC.code {
                    case LAError.appCancel.rawValue:
                        callback(false, TouchAuthenticationCode.appCancel)
                    case LAError.authenticationFailed.rawValue:
                        callback(false, TouchAuthenticationCode.failedThree)
                    case LAError.invalidContext.rawValue:
                        callback(false, TouchAuthenticationCode.invalidContext)
                    case LAError.passcodeNotSet.rawValue:
                        callback(false, TouchAuthenticationCode.passCodeNotSet)
                    case LAError.systemCancel.rawValue:
                        callback(false, TouchAuthenticationCode.systemCanceled)
                    case LAError.touchIDLockout.rawValue:
                        callback(false, TouchAuthenticationCode.IDLockedOut)
                    case LAError.touchIDNotAvailable.rawValue:
                        callback(false, TouchAuthenticationCode.notAvailable)
                    case LAError.userCancel.rawValue:
                        callback(false, TouchAuthenticationCode.canceled)
                    case LAError.userFallback.rawValue:
                        callback(false, TouchAuthenticationCode.fallBack)
                    default:
                        callback(false, TouchAuthenticationCode.defalutFailed)
                    }
                }
            }
        }
    }

附加代码

 enum TouchUseStatus {
        case canUse                         //该机器可以使用
        case canNotUseFingerNotEnrolled     //该机器没有设置指纹
        case canNotUsePasscodeNotSet        // 密码未设定
        case canNotAvailable                //机器不支持touchID
        case canNotUse                      //其他情况,应都不能用指纹
    }

    enum TouchAuthenticationCode {
        case sucessed               //指纹验证成功
        case failedThree            //指纹验证失败三次
        case failedFive             // 指纹验证失败五次,需要调用密码了
        case canceled               //用户主动取消指纹,点击取消按钮
        case fallBack               //按了密码按钮,普惠应该不会用到,这个要调回主线程
        case systemCanceled         //调到了后台,取消授权,如其他应用切入,用户自主
        case passCodeNotSet         //设备系统未设置密码
        case notAvailable           //用户未录入指纹
        case IDLockedOut            //用户连续多次进行Touch ID验证失败,Touch ID被锁,需要用户输入密码解锁,先Touch ID验证密码
        case appCancel              //用户来了电话之类的,应用被挂起
        case invalidContext         //之前就已经失效
        case defalutFailed          //其他失效情况
    }

弹出的指纹验证框的两个按钮的标题,可以通过下面的方法修改:

//为空默认显示"Cancel"
context.localizedCancelTitle = "取消"
//为空默认不显示
context.localizedFallbackTitle = "输入密码"

你可能感兴趣的:(iOS TouchID (FaceID)集成方案)