My goal is to
- show a
LoginViewwhen the user first launches the app - after the user logs in, we should store the token and go to the
HomeView - any time the user opens the app in the future, we taken user to the
HomeViewsince we have a stored token - finally, we should log the user out and return them to the login screen if the token has expired
I tried approaches outlined in this youtube video and this medium article
At a high level, they both talk about injecting some sort of an Authentication object into the environment, something like:
First we have the authentication class which is an observable object
class Authentication: ObservableObject {
@Published var isValidated = false
func updateValidation(success: Bool) {
withAnimation {
isValidated = success
}
}
}
We then create the authentication object in the main and pass it to the environment
@main
struct MySecureApp_App: App {
@StateObject var authentication = Authentication()
var body: some Scene {
WindowGroup {
if authentication.isValidated {
ContentView()
.environmentObject(authentication)
} else {
HomeView()
.environmentObject(authentication)
}
}
}
}
Then in the login view
struct LoginView: View {
@StateObject private var loginVM = LoginViewModel()
@EnvironmentObject var authentication: Authentication
var body: some View {
VStack {
// some login views
Button("Log in") {
loginVM.login { success in
authentication.updateValidation(success: success)
}
}
}
}
}
and then finally in the home view
struct HomeView: View {
@StateObject private var homeVM = HomeViewModel()
@EnvironmentObject var authentication: Authentication
var body: some View {
NavigationView {
VStack {
}.onReceive($homeVM.isUnauthorized) // ignore for SwiftUI syntax {
authentication.updateValidation(success: false)
}
}
}
}
Now while this could work, it seems rather cumbersome to keep passing the authentication object to each and every view.
Is there a way possible that we could inject these StateObjects or environment objects into view models or services ?
In my opinion a good solution might be to set the logout status of the user from the HTTPClient when an API returns an unauthorized response rather than having to check this in every view.




