【问题标题】:Biometric Authentication evaluation with swiftUI使用 swiftUI 进行生物特征认证评估
【发布时间】:2020-02-19 10:01:24
【问题描述】:

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

所以我一直在研究如何做到这一点。有很多很棒的资源:

Face ID evaluation process not working properly

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

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

Value of type 'AuthenticateView' has no member 'present'

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

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

【问题讨论】:

    标签: swift swiftui localauthentication


    【解决方案1】:

    解释:

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

    首先,您有AuthenticateView,即struct。你不能这样做 class 因为整个 Apple 的 SwiftUI 理念 is about structures. 并且因为 Struct 是值类型而不是引用类型,所以没有指针本身。因此,您可能不会将包含 unowned selfweak self 修饰符的代码部分包含在 struct AuthenticateView: View {}

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

    presentUIViewController 的方法。在 SwiftUI 中,您无法访问它。正在使用下一种样式呈现警报:

    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")))
            }
        }
    }
    

    解决方案: 对于您的情况,我将为您的逻辑创建ObservableObjectclass Handler 子类,并使用@ObservedObject@Published@State 的强大功能。

    理解概念的粗略示例:

    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"
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-19
      • 2021-11-16
      • 2016-02-18
      • 1970-01-01
      • 1970-01-01
      • 2015-12-21
      • 2011-08-22
      • 2021-03-23
      • 1970-01-01
      相关资源
      最近更新 更多