我正在尝试观察Firebase身份验证并相应地更新我的视图。
I have an SessionStore object:
class SessionStore: ObservableObject {
@Published var session: Account?
var handle: AuthStateDidChangeListenerHandle?
deinit {
stopListen()
}
func listen() {
if handle == nil {
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
if let user = user {
print("User logged in: \(user)")
self.session = Account.preData
} else {
self.session = nil
}
}
}
}
func stopListen() {
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
}
我在这样的视图中使用它:
struct TabBarView: View {
@EnvironmentObject var sessionStore: SessionStore
@State var selectedTab = Tab.swiping
enum Tab: Int {
case swiping, matches, profil
}
func getUser() {
sessionStore.listen()
}
var body: some View {
Group {
if (sessionStore.session != nil) {
TabView(selection: $selectedTab) {
SwipingView().tabItem {
TabBarItem(text: "Text", image: "pause.circle")
}.tag(Tab.swiping)
}
} else {
LoginView()
}
}.onAppear(perform: getUser).onDisappear(perform: sessionStore.stopListen)
}
}
并这样称呼它:
sessionStore = SessionStore()
TabBarView().environmentObject(sessionStore!)
但是,即使会话不为零,它也仅显示LoginView。我进行了一些代码更改,这实际上是解决方案。
答案 0 :(得分:1)
我认为这是做到这一点的方式
class SessionStore: ObservableObject {
@Published var session: Account?
此外,您在状态闭包内引用了self
,这意味着您的对象将永远不会取消初始化。像这样添加无主或弱项:
handle = Auth.auth().addStateDidChangeListener { [unowned self] (auth, user) in
答案 1 :(得分:0)
正确的实现是:
class SessionStore: ObservableObject {
let objectWillChange = ObservableObjectPublisher()
var session: Account? {
didSet {
objectWillChange.send()
}
}
var handle: AuthStateDidChangeListenerHandle?
deinit {
stopListen()
}
func listen() {
handle = Auth.auth().addStateDidChangeListener { (auth, user) in
if let user = user {
print("User logged in: \(user)")
self.session = Account.preData
} else {
self.session = nil
}
}
}
func stopListen() {
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
}
有关它的更多信息: https://www.pointfree.co/blog/posts/30-swiftui-and-state-management-corrections