@@ -109,9 +109,10 @@ import SwiftUI
109109 extension ViewStore {
110110 /// Sends an action into the store and then suspends while a piece of state is `true`.
111111 ///
112- /// This method can be used to interact with async/await code, allowing you to suspend while work
113- /// is being performed in an effect. One common example of this is using SwiftUI's `.refreshable`
114- /// method, which shows a loading indicator on the screen while work is being performed.
112+ /// This method can be used to interact with async/await code, allowing you to suspend while
113+ /// work is being performed in an effect. One common example of this is using SwiftUI's
114+ /// `.refreshable` method, which shows a loading indicator on the screen while work is being
115+ /// performed.
115116 ///
116117 /// For example, suppose we wanted to load some data from the network when a pull-to-refresh
117118 /// gesture is performed on a list. The domain and logic for this feature can be modeled like so:
@@ -173,17 +174,19 @@ import SwiftUI
173174 ///
174175 /// Here we've used the ``send(_:while:)`` method to suspend while the `isLoading` state is
175176 /// `true`. Once that piece of state flips back to `false` the method will resume, signaling to
176- /// `.refreshable` that the work has finished which will cause the loading indicator to disappear.
177+ /// `.refreshable` that the work has finished which will cause the loading indicator to
178+ /// disappear.
177179 ///
178180 /// **Note:** ``ViewStore`` is not thread safe and you should only send actions to it from the
179- /// main thread. If you are wanting to send actions on background threads due to the fact that the
180- /// reducer is performing computationally expensive work, then a better way to handle this is to
181- /// wrap that work in an ``Effect`` that is performed on a background thread so that the result
182- /// can be fed back into the store.
181+ /// main thread. If you are wanting to send actions on background threads due to the fact that
182+ /// the reducer is performing computationally expensive work, then a better way to handle this
183+ /// is to wrap that work in an ``Effect`` that is performed on a background thread so that the
184+ /// result can be fed back into the store.
183185 ///
184186 /// - Parameters:
185187 /// - action: An action.
186- /// - predicate: A predicate on `State` that determines for how long this method should suspend.
188+ /// - predicate: A predicate on `State` that determines for how long this method should
189+ /// suspend.
187190 public func send(
188191 _ action: Action ,
189192 while predicate: @escaping ( State ) -> Bool
@@ -199,7 +202,8 @@ import SwiftUI
199202 /// - Parameters:
200203 /// - action: An action.
201204 /// - animation: The animation to perform when the action is sent.
202- /// - predicate: A predicate on `State` that determines for how long this method should suspend.
205+ /// - predicate: A predicate on `State` that determines for how long this method should
206+ /// suspend.
203207 public func send(
204208 _ action: Action ,
205209 animation: Animation ? ,
@@ -211,12 +215,12 @@ import SwiftUI
211215
212216 /// Suspends while a predicate on state is `true`.
213217 ///
214- /// - Parameter predicate: A predicate on `State` that determines for how long this method should
215- /// suspend.
218+ /// - Parameter predicate: A predicate on `State` that determines for how long this method
219+ /// should suspend.
216220 public func suspend( while predicate: @escaping ( State ) -> Bool ) async {
217- var cancellable : Cancellable ?
221+ let cancellable = Box < AnyCancellable ? > ( wrappedValue : nil )
218222 try ? await withTaskCancellationHandler (
219- handler: { [ cancellable] in cancellable ? . cancel ( ) } ,
223+ handler: { cancellable. wrappedValue ? . cancel ( ) } ,
220224 operation: {
221225 try Task . checkCancellation ( )
222226 try await withUnsafeThrowingContinuation {
@@ -225,7 +229,7 @@ import SwiftUI
225229 continuation. resume ( throwing: CancellationError ( ) )
226230 return
227231 }
228- cancellable = self . publisher
232+ cancellable. wrappedValue = self . publisher
229233 . filter { !predicate( $0) }
230234 . prefix ( 1 )
231235 . sink { _ in
@@ -237,4 +241,12 @@ import SwiftUI
237241 )
238242 }
239243 }
244+
245+ private class Box < Value> {
246+ var wrappedValue : Value
247+
248+ init ( wrappedValue: Value ) {
249+ self . wrappedValue = wrappedValue
250+ }
251+ }
240252#endif
0 commit comments