Face ID evaluation process not working properly

巧了我就是萌 提交于 2019-11-30 05:11:30

问题


I'm trying to get if Face ID or Touch ID succeeded in the function below

func authenticate() -> Bool{

    let context = LAContext()
    var error: NSError?

    guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
        return false
    }
    var returnValue = false
    let reason = "Face ID authentication"
    context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) 
    {
        isAuthorized, error in
        guard isAuthorized == true else {
            return print(error)
        }
        returnValue = true
        print("success")
    }
    return returnValue        
}

but even when it succeeds with this code it skips the returnValue = true is passed later which results a false return. why does this happen? and how can I fix this code to make it work like it is suppose to?

the code above is from this link just in case this person was watching, thank you.


回答1:


Working code of Touch ID & Face ID LocalAuthentication (swift 4 Code)

Note : Privacy - Face ID Usage Description key add in Info.plist

Use

self.Authenticate { (success) in
     print(success)
}

Local Authentication Function

func Authenticate(completion: @escaping ((Bool) -> ())){

    //Create a context
    let authenticationContext = LAContext()
    var error:NSError?

    //Check if device have Biometric sensor
    let isValidSensor : Bool = authenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)

    if isValidSensor {
        //Device have BiometricSensor
        //It Supports TouchID

        authenticationContext.evaluatePolicy(
            .deviceOwnerAuthenticationWithBiometrics,
            localizedReason: "Touch / Face ID authentication",
            reply: { [unowned self] (success, error) -> Void in

                if(success) {
                    // Touch / Face ID recognized success here
                    completion(true)
                } else {
                    //If not recognized then
                    if let error = error {
                        let strMessage = self.errorMessage(errorCode: error._code)
                        if strMessage != ""{
                            self.showAlertWithTitle(title: "Error", message: strMessage)
                        }
                    }
                    completion(false)
                }
        })
    } else {

        let strMessage = self.errorMessage(errorCode: (error?._code)!)
        if strMessage != ""{
            self.showAlertWithTitle(title: "Error", message: strMessage)
        }
    }

}

Handle Error Codes with Messages

//MARK: TouchID error
func errorMessage(errorCode:Int) -> String{

    var strMessage = ""

    switch errorCode {

    case LAError.Code.authenticationFailed.rawValue:
        strMessage = "Authentication Failed"

    case LAError.Code.userCancel.rawValue:
        strMessage = "User Cancel"

    case LAError.Code.systemCancel.rawValue:
        strMessage = "System Cancel"

    case LAError.Code.passcodeNotSet.rawValue:
        strMessage = "Please goto the Settings & Turn On Passcode"

    case LAError.Code.touchIDNotAvailable.rawValue:
        strMessage = "TouchI or FaceID DNot Available"

    case LAError.Code.touchIDNotEnrolled.rawValue:
        strMessage = "TouchID or FaceID Not Enrolled"

    case LAError.Code.touchIDLockout.rawValue:
        strMessage = "TouchID or FaceID Lockout Please goto the Settings & Turn On Passcode"

    case LAError.Code.appCancel.rawValue:
        strMessage = "App Cancel"

    case LAError.Code.invalidContext.rawValue:
        strMessage = "Invalid Context"

    default:
        strMessage = ""

    }
    return strMessage
}

Show alert message

//MARK: Show Alert
func showAlertWithTitle( title:String, message:String ) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)

    let actionOk = UIAlertAction(title: "OK", style: .default, handler: nil)
    alert.addAction(actionOk)
    self.present(alert, animated: true, completion: nil)
}



回答2:


You should use a closure to obtain results of evaluation. Note that the return value for canEvaluatePolicy is a Bool but there is no return value for evaluatePolicy as it accepts a closure.

You can modify your method to include a closure instead of return.

func authenticate(completion: ((Bool) -> ())) {
    ...
    completion(true) // false if it failed.
    ...
}

In other parts of your app, where you earlier used a return value you would now have to use a closure like:

class Foo {
   func test() {
       let isEvaluated = self.authenticate() // Old way
       self.authenticate { success in
           // bool will now indicate whether evaluation was done successfully or not.
       }
   }
}


来源:https://stackoverflow.com/questions/52092990/face-id-evaluation-process-not-working-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!