title: Why Should SwiftUI View Models be Annotated with @MainActor?
body: <p>I've been watching Apple's concurrency talks from WWDC21 as well as reading a ton of articles on Apple's concurrency updates; however, I cannot wrap my head around one thing: Why do people provide guidance that you should annotate view models with <code>@MainActor</code>? From what I have read, by making a view model property a <code>@StateObject</code> or <code>@ObservedObject</code> within a view, it automatically becomes <code>@MainActor</code>. So if that's the case, why do people still recommend annotating view models as <code>@MainActor</code>?</p>
  <p>For context, here are a few of the articles I've read that reference this:</p>
  <ol>
  <li><a href="https://www.hackingwithswift.com/quick-start/concurrency/understanding-how-global-actor-inference-works" rel="nofollow noreferrer">https://www.hackingwithswift.com/quick-start/concurrency/understanding-how-global-actor-inference-works</a></li>
  <li><a href="https://www.hackingwithswift.com/books/concurrency/how-to-use-mainactor-to-run-code-on-the-main-queue" rel="nofollow noreferrer">https://www.hackingwithswift.com/books/concurrency/how-to-use-mainactor-to-run-code-on-the-main-queue</a></li>
  <li><a href="https://peterfriese.dev/swiftui-concurrency-essentials-part1/" rel="nofollow noreferrer">https://peterfriese.dev/swiftui-concurrency-essentials-part1/</a></li>
  </ol>
  <p>Excerpt from the first link:</p>
  <blockquote>
  <p>[A]ny struct or class using a property wrapper with @MainActor for its wrapped value will automatically be @MainActor. This is what makes @StateObject and @ObservedObject convey main-actor-ness on SwiftUI views that use them – if you use either of those two property wrappers in a SwiftUI view, the whole view becomes @MainActor too.</p>
  </blockquote>
  <p>Excerpt from the second link:</p>
  <blockquote>
  <p>[W]henever you use @StateObject or @ObservedObject inside a view, Swift will ensure that the whole view runs on the main actor so that you can’t accidentally try to publish UI updates in a dangerous way. Even better, no matter what property wrappers you use, the body property of your SwiftUI views is always run on the main actor.</p>
  </blockquote>
  <blockquote>
  <p>Does that mean you don’t need to explicitly add @MainActor to observable objects? Well, no – there are still benefits to using @MainActor with these classes, not least if they are using async/await to do their own asynchronous work such as downloading data from a server.</p>
  </blockquote>
  <p>All in all, I'm a bit confused by the guidance if it would be handled for us automatically. Especially since I don't know of a scenario where you'd have a view model in SwiftUI that is not an <code>@ObservableObject</code>.</p>
  <p>My last question, related to the first question, is: If <code>@StateObject</code> and <code>@ObservedObject</code> automatically make the view <code>@MainActor</code>, then does <code>@EnvironmentObject</code> also make a view <code>@MainActor</code>?</p>
  <p>To put some code behind this, I intend to have the following class injected into the environment using <code>.environmentObject(...)</code></p>
  <pre><code>@MainActor
  class UserSettings: ObservableObject {
      @Published var flowUser: FlowUser?
      
      init(flowUser: FlowUser? = nil) {
          self.flowUser = flowUser
      }
  }
  </code></pre>
  <p>And the following is a view model for one of my views:</p>
  <pre><code>@MainActor
  class CatalogViewModel: ObservableObject {
      @Published var flowUser: FlowUser?
      
      init(flowUser: FlowUser?) {
          self.flowUser = flowUser
      }
  }
  </code></pre>
  <p>As you can see, I have made both classes <code>@ObservableObjects</code> so I feel like I should be able to remove the <code>@MainActor</code> annotation.</p>
  <p>Any help would be greatly appreciated! Thanks for your time!</p>