基于swiftUI的生物特征认证评估

基于swiftUI的生物特征认证评估,swift,swiftui,localauthentication,Swift,Swiftui,Localauthentication,我已经能够在我的应用程序中获得人脸/触摸ID的基本版本。但是,我想添加更好的回退和错误处理 所以我一直在研究怎么做。有这样的奇妙资源: 但是,我在SwiftUI视图中找不到任何可以工作的东西。目前,我的项目将不会运行: 'unowned' may only be applied to class and class-bound protocol types, not 'AuthenticateView' 及 任何帮助都将不胜感激。谢谢大家! 这是我在AuthenticateView.swif

我已经能够在我的应用程序中获得人脸/触摸ID的基本版本。但是,我想添加更好的回退和错误处理

所以我一直在研究怎么做。有这样的奇妙资源:

但是,我在SwiftUI视图中找不到任何可以工作的东西。目前,我的项目将不会运行:

'unowned' may only be applied to class and class-bound protocol types, not 'AuthenticateView'

任何帮助都将不胜感激。谢谢大家!

这是我在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)
        }
    }
}
说明:

“unowned”只能应用于类和类绑定协议类型,而不能应用于“AuthenticateView”

首先,您有一个
AuthenticateView
,它是一个
struct
。你不能这样做,因为整个苹果公司的SwiftUI理念,因为结构是值类型而不是引用类型,所以没有指针。因此,您可能不会将包含
无主self
弱self
修饰符的代码部分包含到
struct AuthenticateView:View{}

“AuthenticateView”类型的值没有成员“存在”

present
是一种
UIViewController
的方法。在SwiftUI中,您无法访问它。警报将使用下一种样式显示:

struct ContentView:View{
@状态私有变量显示=false
var body:一些观点{
按钮(操作:{self.show=true}{Text(“单击”)}
.警报(显示:$showingAlert){
警报(标题:文本(“标题”),
信息:文本(“信息”),
dismissButton:。默认值(文本(“关闭”))
}
}
}
解决方案: 对于您的情况,我将为您的逻辑创建
observeObject
处理程序子类,并使用
@ObservedObject
@Published
@State
的功能

理解该概念的粗略示例:

导入快捷界面
结构ContentView:View{
@ObservedObject var handler=handler()
var body:一些观点{
按钮(操作:{self.handler.toggleshowart()}{Text(“Click”)}
.alert(显示:$handler.shouldshowart){
警报(标题:文本(handler.someTitle),
消息:文本(handler.someMessage),
dismissButton:。默认值(文本(“关闭”))
}
}
}
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView()
}
}
类处理程序:observeObject{
@已发布的变量shouldShowAlert:Bool=false
@已发布var someTitle=“”
@已发布var someMessage=“”
func toggleShowAlert(){
shouldShowAlert.toggle()
someTitle=“ErrorTitle”
someMessage=“ErrorMessage”
}
}
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)
}