I understand that EnvironmentObject
property wrapper can be used to pass around objects to views. I have a session object which I am passing around to my views. Now I have a requirement to pass this into one of my model classes (i.e., non-view). Ideally, this model (receiving the session object) is instantiated as a StateObject
.
struct CreditDetailsView: View {
@EnvironmentObject var session: Session
@StateObject var transactionsModel = TransactionsModel(token: session.token)
The code above will not work (understandably) because:
cannot use instance member 'session' within property initializer; property initializers run before 'self' is available
Any suggestions on how I can pass in the session into TransactionsModel
?
The best way that I've found to do this (because you cannot have an optional StateObject) is:
struct CreditDetailsView: View {
@EnvironmentObject var session: Session
@StateObject var localModel = LocalModel()
var body: some View {
SomeChildView()
.onAppear {
localModel.transactionModel = TransactionModel(token: session.token)
}
}
class LocalModel: ObservableObject {
@Published transactionModel: TransactionModel?
}
}
Try initializing the StateObject in an .onAppear()
prop to a child view, like this:
struct CreditDetailsView: View {
@EnvironmentObject var session: Session
@StateObject var transactionsModel: TransactionModel?
var body: some View {
SomeChildView()
.onAppear(perform: {
transactionModel = TransactionModel(token: session.token)
})
}
}
This way, the variable is initialized when the view renders on the screen. It doesn't matter much which child view you add the onAppear
prop to, as long as it is rendered as soon as the parent does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With