简体   繁体   English

使用 swiftUI 进行生物特征认证评估

[英]Biometric Authentication evaluation with swiftUI

I've been able to get a rudimentary version of Face / Touch ID working inside my app.我已经能够在我的应用程序中使用基本版本的 Face / Touch ID。 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 Face ID 评估过程无法正常工作

However, I can't find anything that works inside a SwiftUI view.但是,我在 SwiftUI 视图中找不到任何可用的东西。 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这是我在 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)
}

Explanation:解释:

'unowned' may only be applied to class and class-bound protocol types, not 'AuthenticateView' 'unowned' 可能只适用于类和类绑定的协议类型,而不是 'AuthenticateView'

First of all, you have AuthenticateView which is a struct .首先,你有AuthenticateView这是一个struct You can't do it class because whole Apple's SwiftUI idea is about structures.你不能在class做,因为整个 Apple 的 SwiftUI 想法都是关于结构的。 And because Struct is value type and not a Reference type, so no pointer as such.并且因为Struct是值类型而不是引用类型,所以没有指针。 So you may not include code parts containing unowned self and weak self modifiers into struct AuthenticateView: View {}因此,您可能不会将包含unowned selfweak self修饰符的代码部分包含到struct AuthenticateView: View {}

Value of type 'AuthenticateView' has no member 'present' 'AuthenticateView' 类型的值没有成员 'present'

present is a UIViewController 's method. present是一个UIViewController的方法。 Here in SwiftUI you have no access to it.在 SwiftUI 中,您无法访问它。 The alerts are being presented using the next style:警报使用下一个样式显示:

struct ContentView: View {
    @State private var show = false
    var body: some View {
        Button(action: { self.show = true }) { Text("Click") }
        .alert(isPresented: $showingAlert) {
            Alert(title: Text("Title"), 
                message: Text("Message"), 
          dismissButton: .default(Text("Close")))
        }
    }
}

Solution: For your case, I would create a class Handler subclass of ObservableObject for your logic and use the power of @ObservedObject , @Published and @State .解决方案:对于您的情况,我将为您的逻辑创建ObservableObjectclass Handler 子类,并使用@ObservedObject@Published@State

Rough example for understanding the concept:理解概念的粗略示例:

import SwiftUI

struct ContentView: View {
    @ObservedObject var handler = Handler()
    var body: some View {
        Button(action: { self.handler.toggleShowAlert() }) { Text("Click") }
            .alert(isPresented: $handler.shouldShowAlert) {
                Alert(title: Text(handler.someTitle),
                    message: Text(handler.someMessage),
              dismissButton: .default(Text("Close")))
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

class Handler: ObservableObject {
    @Published var shouldShowAlert: Bool = false
    @Published var someTitle = ""
    @Published var someMessage = ""

    func toggleShowAlert() {
        shouldShowAlert.toggle()
        someTitle = "ErrorTitle"
        someMessage = "ErrorMessage"
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM