У меня есть приложение, в котором пользователи могут зарегистрироваться и войти в систему с помощью Firebase. Однако я не могу предупредить пользователя о каких-либо ошибках в представлении.
Сначала у нас есть UserStore, который является ObservableObject
и инициализируется как EnvironmentObject
при настройке представления в SceneDelegate
.
let appView = AppView().environmentObject(userStore)
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: appView)
self.window = window
window.makeKeyAndVisible()
}
Затем мы регистрируемся или авторизуемся в View вот так.
В поле зрения
self.userStore.logIn(email: self.email, password: self.password)
self.isLoggingIn = true
if self.userStore.failedToLogin {
self.isLoggingIn = false
self.alertTitle = "There seems to be a problem"
self.alertBody = self.userStore.errorMessage
self.showingAlert = true
}
Затем фактический метод должен обновить значения свойств UserStore, которые затем обновят представление и отобразят предупреждение, однако это не так.
Войти
// Session Properties
@Published var isLoggedIn = false {didSet{didChange.send() }}
@Published var isNewUser = false {didSet{didChange.send() }}
@Published var failedToCreateAccount = false {didSet{didChange.send() }}
@Published var failedToLogin = false {didSet{didChange.send() }}
@Published var errorMessage = "" {didSet{didChange.send() }}
init () {
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
if let user = user {
self.session = user
self.isLoggedIn = true
//Change isNewUser is user document exists?
} else {
self.session = nil
self.isLoggedIn = false
}
}
}
func logIn(email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { [weak self] user, error in
print("Signed In")
if(error != nil) {
print("Failed to login")
self!.failedToLogin = true
self!.errorMessage = ("\(String(describing: error))")
print(error!)
return
} else if error == nil {
print("Success Logging In")
}
}
}
AppView определяет, какое представление загружается, в зависимости от того, вошел ли пользователь в систему.
Просмотр приложений
if !userStore.isLoggedIn {
LoginView().transition(.opacity)
}
if userStore.isLoggedIn {
ContentView().transition(.opacity)
}
Сообщения об ошибках банкомата не отображаются; представление входа в систему также отображается незадолго до основного представления.
Как правильно отображать сообщения об ошибках в представлении?
userStore.login
- это асинхронный процесс. Т.е. вызовif self.userStore.failedToLogin
выполняется до возвратаuserStore.login
. Таким образом,userStore.failedToLogin
по-прежнемуfalse
, и код в условном операторе никогда не будет выполнен. Есть два способа обойти это: 1. Реализовать завершающее замыкание наuserStore.logIn
и переместить код, отображающий ошибку, в закрытие. 2. СделатьuserStore.failedToLogin
издателем и подписать на него видимость вашего предупреждения. - person Peter Friese   schedule 13.02.2020self.isLoggingIn = true
и следующий за ней код будут выполняться до входа пользователя в систему - код быстрее, чем в Интернете, и вам нужно выполнить следующий «шаг» из закрытия входа Firebase. См. Мой ответ на этот вопрос для дополнительного чтения. - person Jay   schedule 13.02.2020