I've been able to get a rudimentary version of Face / Touch ID working inside my app. However, I want to add better fallbacks and error handling.
So I've been researching how to do it. There are fantastic resources like this:
Face ID evaluation process not working properly
However, I can't find anything that works inside a SwiftUI view. At the moment my project won't run with:
'unowned' may only be applied to class and class-bound protocol types, not 'AuthenticateView'
and
Value of type 'AuthenticateView' has no member 'present'
any help would be much appreciated. Thank you!
Here's my code inside AuthenticateView.swift
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) } }}
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}
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)}