Biometri c Оценка аутентификации с помощью swiftUI - PullRequest
0 голосов
/ 19 февраля 2020

Мне удалось получить элементарную версию Face / Touch ID, работающую внутри моего приложения. Тем не менее, я хочу добавить лучшие запасные варианты и обработку ошибок.

Итак, я изучал, как это сделать. Существуют такие фантастические c ресурсы, как:

Процесс оценки лица не работает должным образом

Однако я не могу найти ничего, что работает в представлении 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)
}

1 Ответ

1 голос
/ 19 февраля 2020

Объяснение:

«unowned» может применяться только к классам и типам протоколов, связанных с классами, но не «AuthenticateView»

Прежде всего, у вас есть AuthenticateView, что является struct. Вы не можете сделать это class, потому что вся идея Apple SwiftUI касается структур. И потому что Struct является типом значения, а не ссылочным типом, поэтому указатель как таковой отсутствует. Поэтому вы не можете включать части кода, содержащие модификаторы unowned self и weak self, в struct AuthenticateView: View {}

Значение типа 'AuthenticateView' не имеет члена 'присутствует'

present - это метод UIViewController. Здесь, в 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")))
        }
    }
}

Решение: Для вашего случая я бы создал подкласс class Handler ObservableObject для вашей логики c и использовал бы мощность @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"
    }
}
...