После повторной попытки FaceID я сразу вижу содержимое разблокированных приложений - PullRequest
0 голосов
/ 17 апреля 2020

Я вижу текст «Unlocked», когда я снова пытаюсь идентифицировать лицо. Как отобразить пустой экран или экран Spla sh вместо него?

Мой код следующий:

import Foundation
import LocalAuthentication

class UserAuthentification{

    func authenticate(){

        let context = LAContext()
        var error: NSError?

        guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else {
            print("No Biometric Sensor Has Been Detected. This device does not support FaceID/TouchID.")
            return
        }

        context.evaluatePolicy(LAPolicy.deviceOwnerAuthentication, localizedReason: "Only device owner is allowed", reply: { (success, error) -> Void in

            if( success ) {
                print("FaceID/TouchID. You are a device owner!")
            } else {

                // Check if there is an error
                if let errorObj = error {
                    print("Error took place. \(errorObj.localizedDescription)")
                }
                if LAError.Code.userCancel.rawValue == -2{
                self.authenticate()
            }

            }
        })
    }
}

struct ContentView: View {


    var variable : UserAuthentification

    var body: some View {

// Этот текст отображается после повторной попытки FaceID

                Text("Unlocked")
        .onAppear(perform: variable.authenticate)

    }

}

Спасибо, что ответили заранее!)

1 Ответ

0 голосов
/ 17 апреля 2020

Я бы изменил ваш класс UserAuthentication так, чтобы он выставлял объект @Observable для обозначения аутентифицированного состояния.

У вас также есть ошибка в проверке для отмененного пользователем результата - вы просто проверяете собственное значение константы. Вам нужно проверить code в LAError

import Foundation
import LocalAuthentication

class UserAuthenticator: ObservableObject {

    @Published private(set) var isAuthenticated = false
    @Published private(set) var error: Error?

    func authenticate(){

        let context = LAContext()
        var error: NSError?

        guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
            print("No Biometric Sensor Has Been Detected. This device does not support FaceID/TouchID.")
            return
        }

        context.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: "Only device owner is allowed", reply: { (success, error) -> Void in

            DispatchQueue.main.async {

                self.error = error

                if( success ) {
                    print("FaceID/TouchID. You are a device owner!")
                    self.isAuthenticated = true
                } else {

                    // Check if there is an error
                    if let errorObj = error as? LAError {
                        print("Error took place. \(errorObj.localizedDescription)")
                        if errorObj.code == .userCancel {
                            self.authenticate()
                        }
                    }
                }
            }
        })
    }

    func deauthenticate() {
        self.isAuthenticated = false
    }
}

. Затем вы можете внедрить экземпляр этого класса в качестве объекта модели в ваше представление и использовать свойство isAuthenticated для управления состоянием представления. :

import SwiftUI

struct ContentView: View {

    @ObservedObject var authenticator: UserAuthenticator

    var body: some View {
        HStack {
            if authenticator.isAuthenticated {
                VStack {
                    Text("Welcome")
                    Button(action: {self.authenticator.deauthenticate()}) {
                        Text("Logout")
                    }
                }
            } else {
                VStack {
                    Text("Please authenticate").onAppear {
                        self.authenticator.authenticate()
                    }
                    if self.authenticator.error != nil {
                        Text(self.authenticator.error!.localizedDescription)
                    }
                }
            }
        }
    }
}

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

Вам нужно будет внедрить экземпляр UserAuthenticator из вашего делегата сцены, как я это делал в коде провайдера предварительного просмотра.

Это простой пример; вам нужно учитывать ограничения и повторные попытки, если биометрия c аутентификация недоступна, но это должно помочь вам начать.

...