Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save finestructure/a9dcda2b5c05ce287925428f13a857d6 to your computer and use it in GitHub Desktop.
Save finestructure/a9dcda2b5c05ce287925428f13a857d6 to your computer and use it in GitHub Desktop.
ViewStore.binding example
// Playground generated with 🏟 Arena (https://github.com/finestructure/arena)
// ℹ️ If running the playground fails with an error "no such module ..."
// go to Product -> Build to re-trigger building the SPM package.
// ℹ️ Please restart Xcode if autocomplete is not working.
// Created by running
// arena git@github.com:stephencelis/swift-composable-architecture.git@revision:63b04f284a557d36d5c09d60dafb6e016b3432b8 -n text-field
import ComposableArchitecture
import ComposableArchitectureTestSupport
import PlaygroundSupport
import SwiftUI
PlaygroundPage.current.needsIndefiniteExecution = true
// --------------------
// Guidance protocols
// --------------------
protocol CAView: View {
associatedtype State
associatedtype Action
var store: Store<State, Action> { get }
var viewStore: ViewStore<State, Action> { get }
static var reducer: PureReducer<State, Action> { get }
}
protocol CAScopedView: CAView {
associatedtype ViewState
associatedtype ViewAction
var viewStore: ViewStore<ViewState, ViewAction> { get }
}
protocol CAInitialStore {
associatedtype State
associatedtype Action
static func initialStore() -> Store<State, Action>
}
// --------------------
struct ContentView: CAView {
let store: Store<State, Action>
@ObservedObject var viewStore: ViewStore<State, Action>
var body: some View {
TextField("Text", text: viewStore.binding(get: \.text, send: Action.textFieldChanged))
}
// boilerplate - move to framework somehow?
init(store: Store<State, Action>) {
self.store = store
self.viewStore = store.view()
}
}
extension ContentView {
struct State: Equatable {
var text: String = ""
}
enum Action {
case textFieldChanged(String)
}
static let reducer = PureReducer<State, Action> { state, action in
switch action {
case .textFieldChanged(let str):
state.text = str
}
}.print()
}
extension ContentView: CAInitialStore {
static func initialStore() -> Store<State, Action> {
let initial = State(text: "foo")
return Store(initialState: initial, reducer: reducer, environment: ())
}
}
PlaygroundPage.current.setLiveView(ContentView(store: ContentView.initialStore()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment