Is there a more natural way (now that it's 2022) of initializing some internal variables that depend on an @EnvironmentObject (or other @ObservedObject) within a view's init() function?
For example, the following shows what I'm trying to do (commented out) versus what works. Unfortunately the "what works" code is considerably more unwieldly (bulky, repetitive). Instead of just using a diary var I have to sprinkle my code with try? log.readDiary(for: state.now) or wrap it all in a subviews. Wondering what the best practice is.
struct NutritionView: View {
let log: LogProvider
@ObservedObject private var state: StateService
// @StateObject private var diary: DiaryReader? // init depends on using state (above)
init(log: LogProvider) {
// self.diary = try? log.readDiary(for: state.now) // would like to init here
// unfortunately `self.state` not available inside init()
}
var body: some View {
// let remaining = remainingCalories(diary: diary, goals: goals) // and use `diary` here
let remaining = remainingCalories(diary: try? log.readDiary(for: state.now), goals: goals)
VStack {
...
}
}
}
There's a related post here: Swiftui - How do I initialize an observedObject using an environmentobject as a parameter?, but I'd rather not create internal subviews to accomplish what seems to be a simple initialization. That just seems... wasteful, repetitive, unwieldly. Hoping the API has evolved a bit since then.
@ObservedObjectwhich can't be put into a computed property as far as I know. I'll update the code to reflect this. Second option... well yes – but that's a different flavor of complexity. This is a data-driven view right now, so there's no view model. I can add one but... wish it wasn't necessary.@EnvironmentObject(or other similar type) in aninit()is not possible. Which is what I was driving at – before going in another direction, wanted to confirm that..onAppearor pass the@EnvironmentObjectin from the parent view