Reputation: 506
I'm trying to create an @EnvironmentObject called "userData" to share data about the user between views. I am trying to create an optional @StateObject "userData" and then initialize the @StateObject "userData" once the user has logged in since I need to know the user's userID to initialize the @StateObject "userData".
This is what my code looks like:
class User: ObservableObject {
var collection: CollectionReference
init(userID: String) {
collection = Firestore.firestore().collection(userID)
}
...
}
struct ContentView: View {
@StateObject var userData: User? = nil
...
NavigationLink(destination: HomePage(), isActive: $action) {
EmptyView().environmentObject(userData)
}
Button(action: {
Auth.auth().signIn(withEmail: self.email ?? "", password: self.password ?? "") { authResult, error in
if let user = authResult?.user {
userData = User(userID: user.uid)
self.action = true
} else {
print("failed :(: \(error)")
}
}
})
...
}
struct HomePage: View {
@EnvironmentObject var userData: User
...
}
However, SwiftUI doesn't seem to be recognizing userData as optional because I keep getting the error:
Generic struct 'StateObject' requires that 'User?' conform to 'ObservableObject'
Is there a way to declare optional @StateObject variables? Or else is there another way to initialize the @StateObject later on in a function?
Upvotes: 5
Views: 3922
Reputation: 52565
As suggested in the comments, you could make collection
optional, since you can't have an optional StateObject
:
class User: ObservableObject {
var collection: CollectionReference?
func loadCollection(userID: String) {
collection = Firestore.firestore().collection(userID)
}
}
//...
@StateObject var userData = User()
//...
Button(action: {
Auth.auth().signIn(withEmail: self.email ?? "", password: self.password ?? "") { authResult, error in
if let user = authResult?.user {
userData.loadCollection(userID: user.uid)
self.action = true
} else {
print("failed :(: \(error)")
}
}
})
Upvotes: 1