I'm facing an issue with swiftUI where my view doesn't update when an isSignedIn property changes in a sessionManager.
Setup Overview:
I have an 'AppState' object which encapsulates several managers, including a 'SessionManager'. The 'SessionManager' handles user auth and has a published property 'isSignedIn' to track user sign in status. Despite correctly updating 'isSignedIn' after a successful sign-in, my 'MainView' does not reflect these changes until I manually trigger a state change (pressing a test button). Even after the changes are manually reflected, the 'MainView' does not update as expected.
Code Snippets:
// SessionManager
import Foundation
import SwiftUI
class SessionManager: ObservableObject {
@Published private(set) var session: Session? = nil
@Published private(set) var user: User? = nil
@Published private(set) var isSignedIn: Bool = false
// These signIn and signOut functions are working as expected
func signIn(email: String, password: String) async throws {
try await performSignIn(email: email, password: password)
}
func signOut() {
Task {
await performSignOut()
}
}
// AppState
class AppState: ObservableObject {
@Published var sessionManager: SessionManager
@Published var eventManager: EventManager
@Published var locationManager: LocationManager
init() {
let session = SessionManager()
self._sessionManager = Published(wrappedValue: session)
self._eventManager = Published(wrappedValue: EventManager(sessionManager: session)).
self._locationManager = Published(wrappedValue: LocationManager(sessionManager: session)).
}
}
// App
import SwiftUI
@main
struct myApp: App {
@StateObject var appState = AppState()
var body: some Scene {
WindowGroup {
MainView()
.environmentObject(appState)
}
}
}
}
// MainView
import SwiftUI
@_spi(Experimental) import MapboxMaps
struct MainView: View {
@EnvironmentObject var appState: AppState
@State var selectedTab = "MapView"
var body: some View {
Group {
// display based on sign in status
if appState.sessionManager.isSignedIn {
NormalView()
// if not signed in, display login form
} else {
ZStack {
LoginView(LoginViewModel(appState))
VStack {
Spacer()
// after a successful sign in, pressing this button prints true to the console as expected
Button("test") {
print("Test!!! \(appState.sessionManager.isSignedIn)")
}
// but after a successful sign in, this text doesn't update, and neither does the main view...
Text("\(appState.sessionManager.isSignedIn ? "Signed In" : "Not Signed In")")
}
}
}
}
}
}
Debugging Steps Taken
Print Statements: Confirmed that isSignedIn changes to true upon successful sign-in.
Environment Object: Verified that AppState is correctly passed as an environment object to MainView.
Memory Addresses: Confirmed that the same instances of AppState and its properties are being used throughout the app.
Request for help
I'd greatly appreciate any insights or suggestions on what might be causing the view not to update automatically when 'isSignedIn' changes, and how to resolve this issue. If more information is needed, please let me know.
Thank you!
Topic:
UI Frameworks
SubTopic:
SwiftUI