@@ -17,11 +17,23 @@ import SwiftUI
1717/// inside a `WithViewStore` it will behave erratically. To work around you should use the
1818/// initializer that takes a binding (see
1919/// [here](https://gist.github.com/mbrandonw/dee2ceac2c316a1619cfdf1dc7945f66)).
20- public struct WithViewStore < State, Action, Content> : View where Content : View {
20+ public struct WithViewStore < State, Action, Content> {
2121 private let content : ( ViewStore < State , Action > ) -> Content
2222 private var prefix : String ?
2323 @ObservedObject private var viewStore : ViewStore < State , Action >
2424
25+ /// Prints debug information to the console whenever the view is computed.
26+ ///
27+ /// - Parameter prefix: A string with which to prefix all debug messages.
28+ /// - Returns: A structure that prints debug messages for all computations.
29+ public func debug( _ prefix: String = " " ) -> Self {
30+ var view = self
31+ view. prefix = prefix
32+ return view
33+ }
34+ }
35+
36+ extension WithViewStore : View where Content: View {
2537 /// Initializes a structure that transforms a store into an observable view store in order to
2638 /// compute views from store state.
2739
@@ -39,7 +51,7 @@ public struct WithViewStore<State, Action, Content>: View where Content: View {
3951 self . viewStore = ViewStore ( store, removeDuplicates: isDuplicate)
4052 }
4153
42- public var body : some View {
54+ public var body : Content {
4355 #if DEBUG
4456 if let prefix = self . prefix {
4557 print (
@@ -52,19 +64,9 @@ public struct WithViewStore<State, Action, Content>: View where Content: View {
5264 #endif
5365 return self . content ( self . viewStore)
5466 }
55-
56- /// Prints debug information to the console whenever the view is computed.
57- ///
58- /// - Parameter prefix: A string with which to prefix all debug messages.
59- /// - Returns: A structure that prints debug messages for all computations.
60- public func debug( _ prefix: String = " " ) -> Self {
61- var view = self
62- view. prefix = prefix
63- return view
64- }
6567}
6668
67- extension WithViewStore where State: Equatable {
69+ extension WithViewStore where Content : View , State: Equatable {
6870 /// Initializes a structure that transforms a store into an observable view store in order to
6971 /// compute views from equatable store state.
7072 ///
@@ -79,7 +81,7 @@ extension WithViewStore where State: Equatable {
7981 }
8082}
8183
82- extension WithViewStore where State == Void {
84+ extension WithViewStore where Content : View , State == Void {
8385 /// Initializes a structure that transforms a store into an observable view store in order to
8486 /// compute views from equatable store state.
8587 ///
@@ -101,3 +103,79 @@ extension WithViewStore: DynamicViewContent where State: Collection, Content: Dy
101103 self . viewStore. state
102104 }
103105}
106+
107+ #if compiler(>=5.3)
108+
109+ import SwiftUI
110+
111+ /// A structure that transforms a store into an observable view store in order to compute scenes from
112+ /// store state.
113+ @available ( iOS 14 . 0 , macOS 11 . 0 , tvOS 14 . 0 , watchOS 7 . 0 , * )
114+ extension WithViewStore : Scene where Content: Scene {
115+ public typealias Body = Content
116+
117+ /// Initializes a structure that transforms a store into an observable view store in order to
118+ /// compute scenes from store state.
119+
120+ /// - Parameters:
121+ /// - store: A store.
122+ /// - isDuplicate: A function to determine when two `State` values are equal. When values are
123+ /// equal, repeat view computations are removed,
124+ /// - content: A function that can generate content from a view store.
125+ public init (
126+ _ store: Store < State , Action > ,
127+ removeDuplicates isDuplicate: @escaping ( State , State ) -> Bool ,
128+ @SceneBuilder content: @escaping ( ViewStore < State , Action > ) -> Content
129+ ) {
130+ self . content = content
131+ self . viewStore = ViewStore ( store, removeDuplicates: isDuplicate)
132+ }
133+
134+ public var body : Content {
135+ #if DEBUG
136+ if let prefix = self . prefix {
137+ print (
138+ """
139+ \( prefix. isEmpty ? " " : " \( prefix) : " ) \
140+ Evaluating WithViewStore< \( State . self) , \( Action . self) , ...>.body
141+ """
142+ )
143+ }
144+ #endif
145+ return self . content ( self . viewStore)
146+ }
147+ }
148+
149+ @available ( iOS 14 . 0 , macOS 11 . 0 , tvOS 14 . 0 , watchOS 7 . 0 , * )
150+ extension WithViewStore where Content: Scene , State: Equatable {
151+ /// Initializes a structure that transforms a store into an observable view store in order to
152+ /// compute views from equatable store state.
153+ ///
154+ /// - Parameters:
155+ /// - store: A store of equatable state.
156+ /// - content: A function that can generate content from a view store.
157+ public init (
158+ _ store: Store < State , Action > ,
159+ @SceneBuilder content: @escaping ( ViewStore < State , Action > ) -> Content
160+ ) {
161+ self . init ( store, removeDuplicates: == , content: content)
162+ }
163+ }
164+
165+ @available ( iOS 14 . 0 , macOS 11 . 0 , tvOS 14 . 0 , watchOS 7 . 0 , * )
166+ extension WithViewStore where Content: Scene , State == Void {
167+ /// Initializes a structure that transforms a store into an observable view store in order to
168+ /// compute views from equatable store state.
169+ ///
170+ /// - Parameters:
171+ /// - store: A store of equatable state.
172+ /// - content: A function that can generate content from a view store.
173+ public init (
174+ _ store: Store < State , Action > ,
175+ @SceneBuilder content: @escaping ( ViewStore < State , Action > ) -> Content
176+ ) {
177+ self . init ( store, removeDuplicates: == , content: content)
178+ }
179+ }
180+
181+ #endif
0 commit comments