@ObservedObject not triggering redraw if in conditional

Viewed 57

I have the following code:

import SwiftUI

struct RootView: View {
    @ObservedObject var authentication: AuthenticationModel
    
    var body: some View {
        ZStack {
            if self.authentication.loading {
                Text("Loading")
            } else if self.authentication.userId == nil {
                SignInView()
            } else {
                ContentView()
            }
        }
    }
}

However, the @ObservedObject's changes doesn't seem to trigger the switch to the other views. I can "fix" this by rendering

    var body: some View {
        VStack {
            Text("\(self.authentication.loading ? "true" : "false") \(self.authentication.userId ?? "0")")
        }.font(.largeTitle)
        ZStack {
            if self.authentication.loading {
                Text("Loading")
            } else if self.authentication.userId == nil {
                SignInView()
            } else {
                ContentView()
            }
        }
    }

and suddenly it starts working. Why does @ObservedObject not seem to trigger a rerender if the watched properties are only used in conditionals?

The code for AuthenticationModel is:

import SwiftUI
import Combine
import Firebase
import FirebaseAuth

class AuthenticationModel: ObservableObject {
    @Published var userId: String?
    @Published var loading = true
    
    init() {
        // TODO: Properly clean up this handle.
        Auth.auth().addStateDidChangeListener { [unowned self] (auth, user) in
            self.userId = user?.uid
            self.loading = false
        }
    }
}
1 Answers

I think the problem could be that you aren't creating an instance of AuthenticationModel. Can you try the following in RootView?:

@ObservedObject var authentication = AuthenticationModel()
Related