我是 iOS 开发初学者,我的第一个应用程序有问题。我正在使用 Firebase 作为我的应用程序的后端,并且我已经登录并启用了已实现的方法。我的问题是在 Auth.auth().signIn 方法完成后关闭 LoginView。当我通过在 isActive 中设置 ObservableObject 使用 NavigationLink 时,我设法做到了这一点:
NavigationLink(destination: DashboardView(), isActive: $isUserLogin) { EmptyView() }
它按预期工作:当应用程序结束登录过程屏幕将进入下一个视图时 - 仪表板。
但我不想使用 NavigationLink 并创建额外的步骤,我只想使用以下方法返回仪表板:
self.presentationMode.wrappedValue.dismiss()
在这种情况下,我不知道如何强制应用程序等待方法 loginUser() 结束。这是我的代码现在的样子:
if loginVM.loginUser() {
appSession.isUserLogin = true
self.presentationMode.wrappedValue.dismiss()
}
我尝试使用闭包,但它不起作用或者我做错了什么。
非常感谢!
答案 0 :(得分:1)
您想使用 AuthStateDidChangeListenerHandle
和 @EnvrionmentObject
,如下所示:
class SessionStore: ObservableObject {
var handle: AuthStateDidChangeListenerHandle?
@Published var isLoggedIn = false
@Published var userSession: UserModel? { didSet { self.willChange.send(self) }}
var willChange = PassthroughSubject<SessionStore, Never>()
func listenAuthenticationState() {
handle = Auth.auth().addStateDidChangeListener({ [weak self] (auth, user) in
if let user = user {
let firestoreUserID = API.FIRESTORE_DOCUMENT_USER_ID(userID: user.uid)
firestoreUserID.getDocument { (document, error) in
if let dict = document?.data() {
//Decoding the user, you can do this however you see fit
guard let decoderUser = try? UserModel.init(fromDictionary: dict) else {return}
self!.userSession = decoderUser
}
}
self!.isLoggedIn = true
} else {
self!.isLoggedIn = false
self!.userSession = nil
}
})
}
func logOut() {
do {
try Auth.auth().signOut()
print("Logged out")
} catch let error {
debugPrint(error.localizedDescription)
}
}
func unbind() {
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
deinit {
print("deinit - seession store")
}
}
然后简单地按照以下方式做一些事情:
struct InitialView: View {
@EnvironmentObject var session: SessionStore
func listen() {
session.listenAuthenticationState()
}
var body: some View {
ZStack {
Color(SYSTEM_BACKGROUND_COLOUR)
.edgesIgnoringSafeArea(.all)
Group {
if session.isLoggedIn {
DashboardView()
} else if !session.isLoggedIn {
SignInView()
}
}
}.onAppear(perform: listen)
}
}
然后在您的应用程序文件中,您将拥有:
InitialView()
.environmentObject(SessionStore())
通过使用@EnvironmentObject,您现在可以从任何视图访问用户,此外,这还允许跟踪用户的身份验证状态,这意味着如果他们已登录,则应用程序将记住。