Help understanding `SwiftUI.App` identity lifecycle and need for `SwiftUI.State`?

Hi! I have a stateful object that should be created in my app entry point and delivered through my component graph:

@main
@MainActor struct MyApp : App {
  @State private var myAppState = MyAppState()
  
  var body: some Scene {
    ...
  }
}

The MyApp is a struct value type… in a SwiftUI world that seems to imply it could "go away" and be recreated as the system sees appropriate. We see this with view components all the time (hence the State wrapper to help preserve our instance across the lifecycle of our identity)… but I'm wondering if this State wrapper is even necessary with an App entry point. Could this struct ever go away? Would there be any legit reasons that this struct should go away and recreate over one SwiftUI app lifecycle (other than terminating the app and starting a whole new process of course)?

And what lifecycle is the SwiftUI.State tied to in this example? In a view component our SwiftUI.State is tied to our component identity. In this example… we are tied to app component identity? Is there ever going to be multiple legit app component identities live in the same process?

I'm thinking I could just go ahead and keep using State as a best practice… but is this just overkill or is there a real best practice lurking under here? Any more ideas about that? Thanks!

Answered by DTS Engineer in 805183022

State property wrapper manages transient properties. If the view doesn’t modify the data then you should declare it as a standard Swift property.

If you value is transient and changes, you would want to use the state propriety because when the value changes, SwiftUI updates the parts of the view hierarchy that depend on the value.

Don’t use state properties for persistent storage because the life cycle of state variables mirrors the view life cycle.

If you want to learn more about how to model your data and manage your interface state does please see these resources:

Managing user interface state

Data Essentials in SwiftUI Discover Observation in SwiftUI

State property wrapper manages transient properties. If the view doesn’t modify the data then you should declare it as a standard Swift property.

If you value is transient and changes, you would want to use the state propriety because when the value changes, SwiftUI updates the parts of the view hierarchy that depend on the value.

Don’t use state properties for persistent storage because the life cycle of state variables mirrors the view life cycle.

If you want to learn more about how to model your data and manage your interface state does please see these resources:

Managing user interface state

Data Essentials in SwiftUI Discover Observation in SwiftUI

Hmm… I believe I do now have an understanding how a State variable would tie the lifecycle of its value to the lifecycle of a View component… but I am still unclear how this helps me to understand how a State variable defined on an App component can be expected to behave:

https://developer.apple.com/documentation/swiftui/managing-user-interface-state

  • This article has many examples of using State in a View component… but I do not see examples of using State in our App component.

https://developer.apple.com/videos/play/wwdc2020/10040/?time=1852

  • This video does have an example of a StateObject being used as a global "source of truth" (which is going to be most similar to my use case)… but this video predates the release of State and Observable.

https://developer.apple.com/videos/play/wwdc2023/10149

  • I believe this video has a close example from FoodTruckModel to achieve a similar feature to my use case. What this video seems to be missing is where this FoodTruckModel should first be created. Similar to the previous talk… this "global source of truth" looks like it should belong in my root App component… but then would that imply that FoodTruckModel be better initialized as a State var or as a regular Swift let?

A side-question I would have here is how it would be possible for an engineer to stress-test their app in a way to cause the App component instance to be disposed by SwiftUI (and then rebuilt while the process is running). Is such a use case ever possible in an edge case? Is this something (recreating App component) that engineers should ever have to prepare for to defend against?

Help understanding `SwiftUI.App` identity lifecycle and need for `SwiftUI.State`?
 
 
Q