skip to Main Content

Is it possible to use EnvironmentObject in the app file for a new SwiftUI 2.0 project?
I’m using the following code and I get the error:

Fatal error: No ObservableObject of type Authentication found. A
View.environmentObject(_:) for Authentication may be missing as an
ancestor of this view.: file SwiftUI, line 0

I’m assuming this error is because I haven’t used the .environmentObject modifier in any view yet and so the UserAuth has not yet been placed in the environment.

But I want this loginStatus to be available anywhere in my app and to be able to use the function getLoginStatus also anywhere in my app on one common instance of the UserAuth Class.

I was hoping to put this in my rootView and have it apply to all views but not sure how to do this with the structure I have below in my app file.

enum LoginStatus {
    case signedIn
    case signedOut
}

import SwiftUI

@main
struct ExampleApp: App {

    @EnvironmentObject var userAuth: UserAuth

    init() {
        userAuth.getLoginStatus()
    }
    
    var body: some Scene {
        WindowGroup {
            switch userAuth.loginStatus {
            case .signedIn:
                Text("Signed In")
            case .signedOut:
                Text("Signed Out")
            }
        }
    }
}

import SwiftUI

class UserAuth: ObservableObject {
    
    @Published var loginStatus: LoginStatus = .undetermined
    
    func getLoginStatus() {
        // asynchrounously set loginStatus
    }
}

2

Answers


  1. You can use it as regular property at that level and pass as environment down into view hierarchy if/when needed, like

    struct ExampleApp: App {
    
        let userAuth = UserAuth()     // << here !!
        
        var body: some Scene {
            WindowGroup {
                switch userAuth.loginStatus {
                case .signedIn:
                    ContentView()
                       .environmentObject(userAuth)    // << here !!
                case .signedOut:
                    Text("Signed Out")
                }
            }
        }
    }
    
    Login or Signup to reply.
  2. You need to inject UserAuth from root view, and access your object in View with @EnvironmentObject property.

    import SwiftUI
    
    @main
    struct ExampleApp: App {
    
        var body: some Scene {
            WindowGroup {
                MainView().environmentObject(UserAuth())
            }
        }
    }
    
    
    class UserAuth: ObservableObject {
        
        @Published var loginStatus: LoginStatus = .undetermined
        
        func getLoginStatus() {
            // asynchrounously set loginStatus
        }
        
        enum LoginStatus {
            case undetermined
        }
    }
    
    struct MainView:View{
        var body: some View{
            Text("")
        }
    }
    
    struct MainView1:View{
        
        @EnvironmentObject var userAuth: UserAuth
        
        var body: some View{
            Text("")
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search