Я бы изменил ваш класс 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 аутентификация недоступна, но это должно помочь вам начать.