How to handle the authentication in SwiftUI + CoreData for IOS APP

Viewed 20

Hi I am super new to swift and I want to handle the login and registration for my app, below is what I have tried so far,

however, I keep getting the error 'SwiftUI/EnvironmentObject.swift:70: Fatal error: No ObservableObject of type UserAuth found. A View.environmentObject(_:) for UserAuth may be missing as an ancestor of this view.' Does this error means I have to place the UserAuth somewhere else and pass down to ContentView?

May I know why and how to solve it? Thanks

   struct ContentView: View {
        @Environment(\.managedObjectContext) private var viewContext
        @EnvironmentObject var userAuth: UserAuth
        
        @FetchRequest(
            sortDescriptors: [NSSortDescriptor(keyPath: \User.created_at, ascending: true)],
            animation: .default)
        
        private var users: FetchedResults<User>
        
        
        @ViewBuilder
        var body: some View {
            if !userAuth.isLoggedin {
                    LogInView()
                
            } else {
                    AddRoomView()
                
            }
        }
    }

And in my UserAuth.swift:

class UserAuth: ObservableObject {

  let didChange = PassthroughSubject<UserAuth,Never>()

  // required to conform to protocol 'ObservableObject'
  let willChange = PassthroughSubject<UserAuth,Never>()

  func login() {
    // login request... on success:
    self.isLoggedin = true
  }

  var isLoggedin = false {
    didSet {
      didChange.send(self)
    }
  }
}

I have also try instantiate the Auth class on the entrance view and pass to contentView by using environmentObject but still no use, it shows 'circular reference'.

struct MyApp: App {
    let persistenceController = PersistenceController.shared
    let userAuth = userAuth()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
                .environmentObject(userAuth)
        }
    }
}

After Edit: ContentView():

@State var userAuth = UserAuth()
var body: some View {
        if !userAuth.isLoggedin {
            NavigationView{
                LogInView().environmentObject(userAuth)
            }
        } else {
            NavigationView{
                AddRoomView()
            }
        }
    }

LoginView():

struct LogInView: View {
    
    @State  private var emailAddress: String = ""
    @State  private var password: String = ""
    @EnvironmentObject var userAuth: UserAuth

    var body: some View {
    Button(action: {
                        userAuth.login()
                    }) 
....}
}
0 Answers
Related