[Proposal] Utilizing primary associated types to inject view stores to views #11
[Proposal] Utilizing primary associated types to inject view stores to views #11
Conversation
| init(provider: Provider, scheduler: MainQueueScheduler = .init(type: .default)) { | ||
| self._store = StateObject(wrappedValue: PhotoListViewStore(provider: provider, scheduler: scheduler)) | ||
| /// - store: The `ViewStore` that drives | ||
| init(store: @autoclosure @escaping () -> Store) { |
There was a problem hiding this comment.
@autoclosure to avoid any problems with having stores being incorrectly created multiple times. See the initializer on StateObject as well
| } | ||
| } | ||
|
|
||
| extension PhotoListViewStoreType { |
There was a problem hiding this comment.
Out of curiosity, why did you move these onto the type over the store?
There was a problem hiding this comment.
You have to, since its generic in the view you can't talk to the concrete store type directly - its also an unintended advantage because it is a bit more strict with what you can do and protects the ViewStore concept with extra Published properties and the like
| @@ -13,7 +13,7 @@ import Networking | |||
|
|
|||
| /// A provider meant to be usable by SwiftUI previews and unit tests to provide mocked, successful `Photo`s synchronously. | |||
| final class MockItemProvider: Provider { | |||
There was a problem hiding this comment.
With this change, does this really even need to be a provider? Couldn't you just pass the photos from say Photo+SampleData extension etc?
There was a problem hiding this comment.
This is used for the unit tests, still -- in the future we will probably move this into a test target or a test helper target, to your point, though.
What it Does
Shows example of a proposed new best practice of injecting view stores into views.
Dependent on the PR to add primary associated types to the
ViewStoreprotocol.This injection has several advantages:
MockViewStore, which can be injected by SwiftUI previews and always immediately returns the data. We no longer rely on each individual view store to send an initial value with correct timing for previews and (theoretical) snapshot tests – we can now guarantee it. Control over timing in this manner is a prerequisite for using async/await &AsyncAlgorithmsin view stores in place of Combine.Photos (even though we are, for now, just using the provider to generate those photos).ViewStoreprotocol, we can now conditionally return different view stores, compose them together, or do any number of combinations and pass in the result to a view. This means that if we wanted to add automatic analytics logging, for example, we could write a smallAnalyticsViewStore(see below example) wrapper and inject a view store, passing that to a view.AnalyticsViewStore example
For something like this, you could transparently pass this view store instead of the
PhotoListViewStorein this project!How I Tested
Notes
Plan is to discuss this in the next engineering meeting!