Chapter 9: State & Data Flow – Part II

After going through Chapter 9 and looking at final code I have a question regarding the KuchiApp.swift file.

The final project has KuchiApp.swift as:

@main
struct KuchiApp: App {
  let userManager = UserManager()
  let challengesViewModel = ChallengesViewModel()
  
  init() {
    userManager.load()
  }
  
  var body: some Scene {
    WindowGroup {
      StarterView()
        .environmentObject(userManager)
        .environmentObject(challengesViewModel)
    }
  }
}

But based on my experience with SwiftUI shouldn’t userManager and challengesViewModel be marked as a StateObject since the KuchiApp owns those objects and we are injecting them into the environment.

Note here is an excerpt from the book which seems to be backing my thought of these properties being marked with StateObject.

  • When you want a view to own an observable object, because it conceptually belongs to it, your tool is @StateObject.
  • When an observable object is owned elsewhere, either @ObservedObject or @EnvironmentObject are your tools — choosing one or the other depends from each specific case.

Here is the updated code for what I think it should be.

@main
struct KuchiApp: App {
  @StateObject var userManager = UserManager()
   @StateObject var challengesViewModel = ChallengesViewModel()
  
  init() {
    userManager.load()
  }
  
  var body: some Scene {
    WindowGroup {
      StarterView()
        .environmentObject(userManager)
        .environmentObject(challengesViewModel)
    }
  }
}

Am I right in my thoughts that these two properties should be marked with @StateObject or am I missing something?