1
1
import ReactiveSwift
2
2
3
3
#if canImport(Combine)
4
- import Combine
4
+ import Combine
5
5
#endif
6
6
#if canImport(SwiftUI)
7
- import SwiftUI
7
+ import SwiftUI
8
8
#endif
9
9
10
10
/// A ``ViewStore`` is an object that can observe state changes and send actions. They are most
@@ -52,22 +52,22 @@ import ReactiveSwift
52
52
///
53
53
/// ### Thread safety
54
54
///
55
- /// The ``ViewStore`` class is not thread-safe, and all interactions with it must happen on the main
56
- /// thread. See the documentation of the ``Store`` class for more information why this decision was
57
- /// made.
55
+ /// The ``ViewStore`` class is not thread-safe, and all interactions with it (and the store it was
56
+ /// derived from) must happen on the same thread. Further, for SwiftUI applications, all
57
+ /// interactions must happen on the _main_ thread. See the documentation of the ``Store`` class for
58
+ /// more information as to why this decision was made.
58
59
///
59
60
/// ### ViewStore object lifetime
60
61
///
61
62
/// You must always keep a strong reference to any ``ViewStore`` that you create to prevent it from
62
63
/// being immediately deallocated, and thereby preventing its ``produced`` ``StoreProducer`` from
63
64
/// emiting any more state updates. This is primarly an issue when using UIKit, as the SwiftUI
64
65
/// ``WithViewStore`` helper ensures that the ``ViewStore`` is retained.
65
- ///
66
66
@dynamicMemberLookup
67
67
public final class ViewStore < State, Action> {
68
68
#if canImport(Combine)
69
69
@available ( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * )
70
- public private( set) lazy var objectWillChange = ObservableObjectPublisher ( )
70
+ public private( set) lazy var objectWillChange = ObservableObjectPublisher ( )
71
71
#endif
72
72
73
73
private let _send : ( Action ) -> Void
@@ -94,12 +94,12 @@ public final class ViewStore<State, Action> {
94
94
guard let self = self else { return }
95
95
#if canImport(Combine)
96
96
if #available( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * ) {
97
- self . objectWillChange. send ( )
98
- }
97
+ self . objectWillChange. send ( )
98
+ }
99
99
#endif
100
100
self . _state = $0
101
101
self . statePipe. input. send ( value: $0)
102
- }
102
+ }
103
103
}
104
104
105
105
/// A producer of state.
@@ -131,145 +131,145 @@ public final class ViewStore<State, Action> {
131
131
}
132
132
133
133
#if canImport(SwiftUI)
134
- /// Derives a binding from the store that prevents direct writes to state and instead sends
135
- /// actions to the store.
136
- ///
137
- /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
138
- /// since the ``Store`` does not allow directly writing its state; it only allows reading state
139
- /// and sending actions.
140
- ///
141
- /// For example, a text field binding can be created like this:
142
- ///
143
- /// ```swift
144
- /// struct State { var name = "" }
145
- /// enum Action { case nameChanged(String) }
146
- ///
147
- /// TextField(
148
- /// "Enter name",
149
- /// text: viewStore.binding(
150
- /// get: { $0.name },
151
- /// send: { Action.nameChanged($0) }
152
- /// )
153
- /// )
154
- /// ```
155
- ///
156
- /// - Parameters:
157
- /// - get: A function to get the state for the binding from the view
158
- /// store's full state.
159
- /// - localStateToViewAction: A function that transforms the binding's value
160
- /// into an action that can be sent to the store.
161
- /// - Returns: A binding.
134
+ /// Derives a binding from the store that prevents direct writes to state and instead sends
135
+ /// actions to the store.
136
+ ///
137
+ /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
138
+ /// since the ``Store`` does not allow directly writing its state; it only allows reading state
139
+ /// and sending actions.
140
+ ///
141
+ /// For example, a text field binding can be created like this:
142
+ ///
143
+ /// ```swift
144
+ /// struct State { var name = "" }
145
+ /// enum Action { case nameChanged(String) }
146
+ ///
147
+ /// TextField(
148
+ /// "Enter name",
149
+ /// text: viewStore.binding(
150
+ /// get: { $0.name },
151
+ /// send: { Action.nameChanged($0) }
152
+ /// )
153
+ /// )
154
+ /// ```
155
+ ///
156
+ /// - Parameters:
157
+ /// - get: A function to get the state for the binding from the view
158
+ /// store's full state.
159
+ /// - localStateToViewAction: A function that transforms the binding's value
160
+ /// into an action that can be sent to the store.
161
+ /// - Returns: A binding.
162
162
@available ( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * )
163
- public func binding< LocalState> (
164
- get: @escaping ( State ) -> LocalState ,
165
- send localStateToViewAction: @escaping ( LocalState ) -> Action
166
- ) -> Binding < LocalState > {
167
- Binding (
163
+ public func binding< LocalState> (
164
+ get: @escaping ( State ) -> LocalState ,
165
+ send localStateToViewAction: @escaping ( LocalState ) -> Action
166
+ ) -> Binding < LocalState > {
167
+ Binding (
168
168
get: { get ( self . _state) } ,
169
- set: { newLocalState, transaction in
170
- if transaction. animation != nil {
171
- withTransaction ( transaction) {
172
- self . send ( localStateToViewAction ( newLocalState) )
173
- }
174
- } else {
169
+ set: { newLocalState, transaction in
170
+ if transaction. animation != nil {
171
+ withTransaction ( transaction) {
175
172
self . send ( localStateToViewAction ( newLocalState) )
176
173
}
174
+ } else {
175
+ self . send ( localStateToViewAction ( newLocalState) )
177
176
}
178
- )
179
- }
177
+ }
178
+ )
179
+ }
180
180
181
- /// Derives a binding from the store that prevents direct writes to state and instead sends
182
- /// actions to the store.
183
- ///
184
- /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
185
- /// since the ``Store`` does not allow directly writing its state; it only allows reading state
186
- /// and sending actions.
187
- ///
188
- /// For example, an alert binding can be dealt with like this:
189
- ///
190
- /// ```swift
191
- /// struct State { var alert: String? }
192
- /// enum Action { case alertDismissed }
193
- ///
194
- /// .alert(
195
- /// item: self.store.binding(
196
- /// get: { $0.alert },
197
- /// send: .alertDismissed
198
- /// )
199
- /// ) { alert in Alert(title: Text(alert.message)) }
200
- /// ```
201
- ///
202
- /// - Parameters:
203
- /// - get: A function to get the state for the binding from the view store's full state.
204
- /// - action: The action to send when the binding is written to.
205
- /// - Returns: A binding.
181
+ /// Derives a binding from the store that prevents direct writes to state and instead sends
182
+ /// actions to the store.
183
+ ///
184
+ /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
185
+ /// since the ``Store`` does not allow directly writing its state; it only allows reading state
186
+ /// and sending actions.
187
+ ///
188
+ /// For example, an alert binding can be dealt with like this:
189
+ ///
190
+ /// ```swift
191
+ /// struct State { var alert: String? }
192
+ /// enum Action { case alertDismissed }
193
+ ///
194
+ /// .alert(
195
+ /// item: self.store.binding(
196
+ /// get: { $0.alert },
197
+ /// send: .alertDismissed
198
+ /// )
199
+ /// ) { alert in Alert(title: Text(alert.message)) }
200
+ /// ```
201
+ ///
202
+ /// - Parameters:
203
+ /// - get: A function to get the state for the binding from the view store's full state.
204
+ /// - action: The action to send when the binding is written to.
205
+ /// - Returns: A binding.
206
206
@available ( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * )
207
- public func binding< LocalState> (
208
- get: @escaping ( State ) -> LocalState ,
209
- send action: Action
210
- ) -> Binding < LocalState > {
211
- self . binding ( get: get, send: { _ in action } )
212
- }
207
+ public func binding< LocalState> (
208
+ get: @escaping ( State ) -> LocalState ,
209
+ send action: Action
210
+ ) -> Binding < LocalState > {
211
+ self . binding ( get: get, send: { _ in action } )
212
+ }
213
213
214
- /// Derives a binding from the store that prevents direct writes to state and instead sends
215
- /// actions to the store.
216
- ///
217
- /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
218
- /// since the ``Store`` does not allow directly writing its state; it only allows reading state
219
- /// and sending actions.
220
- ///
221
- /// For example, a text field binding can be created like this:
222
- ///
223
- /// ```swift
224
- /// typealias State = String
225
- /// enum Action { case nameChanged(String) }
226
- ///
227
- /// TextField(
228
- /// "Enter name",
229
- /// text: viewStore.binding(
230
- /// send: { Action.nameChanged($0) }
231
- /// )
232
- /// )
233
- /// ```
234
- ///
235
- /// - Parameters:
236
- /// - localStateToViewAction: A function that transforms the binding's value
237
- /// into an action that can be sent to the store.
238
- /// - Returns: A binding.
214
+ /// Derives a binding from the store that prevents direct writes to state and instead sends
215
+ /// actions to the store.
216
+ ///
217
+ /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
218
+ /// since the ``Store`` does not allow directly writing its state; it only allows reading state
219
+ /// and sending actions.
220
+ ///
221
+ /// For example, a text field binding can be created like this:
222
+ ///
223
+ /// ```swift
224
+ /// typealias State = String
225
+ /// enum Action { case nameChanged(String) }
226
+ ///
227
+ /// TextField(
228
+ /// "Enter name",
229
+ /// text: viewStore.binding(
230
+ /// send: { Action.nameChanged($0) }
231
+ /// )
232
+ /// )
233
+ /// ```
234
+ ///
235
+ /// - Parameters:
236
+ /// - localStateToViewAction: A function that transforms the binding's value
237
+ /// into an action that can be sent to the store.
238
+ /// - Returns: A binding.
239
239
@available ( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * )
240
- public func binding(
241
- send localStateToViewAction: @escaping ( State ) -> Action
242
- ) -> Binding < State > {
243
- self . binding ( get: { $0 } , send: localStateToViewAction)
244
- }
240
+ public func binding(
241
+ send localStateToViewAction: @escaping ( State ) -> Action
242
+ ) -> Binding < State > {
243
+ self . binding ( get: { $0 } , send: localStateToViewAction)
244
+ }
245
245
246
- /// Derives a binding from the store that prevents direct writes to state and instead sends
247
- /// actions to the store.
248
- ///
249
- /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
250
- /// since the ``Store`` does not allow directly writing its state; it only allows reading state
251
- /// and sending actions.
252
- ///
253
- /// For example, an alert binding can be dealt with like this:
254
- ///
255
- /// ```swift
256
- /// typealias State = String
257
- /// enum Action { case alertDismissed }
258
- ///
259
- /// .alert(
246
+ /// Derives a binding from the store that prevents direct writes to state and instead sends
247
+ /// actions to the store.
248
+ ///
249
+ /// The method is useful for dealing with SwiftUI components that work with two-way `Binding`s
250
+ /// since the ``Store`` does not allow directly writing its state; it only allows reading state
251
+ /// and sending actions.
252
+ ///
253
+ /// For example, an alert binding can be dealt with like this:
254
+ ///
255
+ /// ```swift
256
+ /// typealias State = String
257
+ /// enum Action { case alertDismissed }
258
+ ///
259
+ /// .alert(
260
260
/// item: self.store.binding(
261
- /// send: .alertDismissed
262
- /// )
263
- /// ) { title in Alert(title: Text(title)) }
264
- /// ```
265
- ///
266
- /// - Parameters:
267
- /// - action: The action to send when the binding is written to.
268
- /// - Returns: A binding.
261
+ /// send: .alertDismissed
262
+ /// )
263
+ /// ) { title in Alert(title: Text(title)) }
264
+ /// ```
265
+ ///
266
+ /// - Parameters:
267
+ /// - action: The action to send when the binding is written to.
268
+ /// - Returns: A binding.
269
269
@available ( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * )
270
- public func binding( send action: Action ) -> Binding < State > {
271
- self . binding ( send: { _ in action } )
272
- }
270
+ public func binding( send action: Action ) -> Binding < State > {
271
+ self . binding ( send: { _ in action } )
272
+ }
273
273
#endif
274
274
275
275
deinit {
0 commit comments