Learn techniques for sharing state throughout your application and persisting data
Sharing state is the process of letting many features have access to the same data so that when any feature makes a change, it is instantly visible to every other feature. The Composable Architecture provides tools for sharing state with many parts of your application.
Because the Composable Architecture prefers modeling domains with value types rather than reference types, sharing state can be tricky. The library comes with tools from the Sharing library to handle this.
There are two main kinds of shared state: explicitly passed state and persisted state. And there are 3 persistence strategies: in-memory, user defaults, and file storage.
This is the simplest kind of shared state. It allows you to share state amongst many features without any persistence. The data is only held in memory.
1
Define shared state in parent
@Reducerstruct ParentFeature { @ObservableState struct State { @Shared var count: Int // Other properties } // ...}
2
Accept shared reference in child
@Reducerstruct ChildFeature { @ObservableState struct State { @Shared var count: Int // Other properties } // ...}
3
Pass shared reference
case .presentButtonTapped: state.child = ChildFeature.State(count: state.$count) // ...
Now any mutation the child makes to count will be instantly reflected in the parent’s count too.
extension SharedReaderKey where Self == FileStorageKey<IdentifiedArrayOf<User>> { static var users: Self { fileStorage(.users) }}
Now you can use it with compile-time type checking:
@Shared(.users) var users: IdentifiedArrayOf<User> = []
You can even bake in the default:
extension SharedReaderKey where Self == FileStorageKey<IdentifiedArrayOf<User>>.Default { static var users: Self { Self[.fileStorage(.users), default: []] }}// Now even simpler:@Shared(.users) var users