Skip to content

Commit 626c35c

Browse files
authored
Simplify/fix #1784 (#1785)
* Simplify/fix #1784 This PR works on top of #1784 and: * Reduces the number of moving parts * Restores implicit animations by directly producing the binding from the observable object * Strongly retains the store in the binding to avoid losing writes * Move
1 parent 8f19bf8 commit 626c35c

File tree

1 file changed

+13
-29
lines changed

1 file changed

+13
-29
lines changed

Sources/ComposableArchitecture/ViewStore.swift

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -466,11 +466,14 @@ public final class ViewStore<ViewState, ViewAction>: ObservableObject {
466466
get: @escaping (ViewState) -> Value,
467467
send valueToAction: @escaping (Value) -> ViewAction
468468
) -> Binding<Value> {
469-
@ObservedState var val = get(self.state)
470-
return .init(
471-
get: { [$val] in $val.wrappedValue },
472-
set: { [weak self] in self?.send(valueToAction($0)) }
469+
ObservedObject(
470+
wrappedValue: ObservedState(
471+
initialValue: get(self.state),
472+
send: { self.send(valueToAction($0)) }
473+
)
473474
)
475+
.projectedValue
476+
.wrappedValue
474477
}
475478

476479
/// Derives a binding from the store that prevents direct writes to state and instead sends
@@ -745,31 +748,12 @@ public struct StorePublisher<State>: Publisher {
745748
}
746749
}
747750

748-
final private class ValueWrapper<V>: ObservableObject {
749-
var value: V {
750-
willSet { objectWillChange.send() }
751-
}
752-
753-
init(_ value: V) {
754-
self.value = value
755-
}
756-
}
757-
758-
@propertyWrapper private struct ObservedState<Value>: DynamicProperty {
759-
@ObservedObject private var box: ValueWrapper<Value>
760-
761-
var wrappedValue: Value {
762-
get { box.value }
763-
nonmutating set { box.value = newValue }
764-
}
751+
private final class ObservedState<Value>: ObservableObject {
752+
@Published var wrappedValue: Value
753+
var cancellable: AnyCancellable?
765754

766-
var projectedValue: Binding<Value> {
767-
.init(
768-
get: { wrappedValue },
769-
set: { wrappedValue = $0 }
770-
)
771-
}
772-
init(wrappedValue value: Value) {
773-
self._box = ObservedObject(wrappedValue: .init(value))
755+
init(initialValue: Value, send: @escaping (Value) -> Void) {
756+
self.wrappedValue = initialValue
757+
self.cancellable = self.$wrappedValue.dropFirst().sink(receiveValue: send)
774758
}
775759
}

0 commit comments

Comments
 (0)