OK, this is all looking absolutely incredible. We have now seemingly fixed all of the problems we encountered with sharing state, and so we can now full heartedly and strongly recommend representing simple shared state in your applications as a reference type. Historically it would have been quite problematic to put a reference in a Composable Architecture feature, for two main reasons:
Reference types used to not play nicely with view invalidation, and so you could make changes to the data in the reference and that would not cause the view to re-render. That is no longer a concern thanks to Swift’s new observation tools.
And second, reference types are not easy to test and debug since you can’t capture the before and after values to compare. But we have now fixed that thanks to the Shared
type and some new internal logic inside the TestStore
.
Now everything we have accomplished so far is fantastic, and we could stop here and have a very compelling story for how to share state amongst features in the Composable Architecture. But we can make things even better.
Sometimes we want shared state to be very explicit and localized. This is how our case study is structured right now, and how we approached the complex sign up flow a few episodes back. If a feature wants a piece of shared state, it must use the @Shared
property wrapper, and whoever creates that feature must pass along a piece of shared state.
But sometimes we want shared state to be ubiquitous throughout the application. Any feature should be able to reach out and grab the shared state immediately without it being passed around explicitly, and should be able to make changes to that shared state.
The prototypical example of this is settings. Settings is usually state that the entire app needs to be able to access, and that perhaps a few features also need to be able to write to. If we stopped with shared state as it is right now we would have to explicitly pass around Shared
values to every feature that needs settings. And this is a viral situation. If some deep leaf feature needs access to settings, then every parent feature needs to also hold onto a Shared
settings object just to pass it along, even if it doesn’t care about settings.
Let’s see what it takes share state across the entire application, instantly.