The universal system operator and architecture for RxSwift
The simplest architecture for RxSwift
typealias Feedback<State, Event> = (Observable<State>) -> Observable<Event>
public static func system<State, Event>(
initialState: State,
reduce: @escaping (State, Event) -> State,
feedback: Feedback<State, Event>...
) -> Observable<State>
Straightforward
Declarative
Debugging is easier
Can be applied on any level
system
operator)system
operator inside feedback loop)Works awesome with dependency injection
Testing
Can model circular dependencies
Completely separates business logic from effects (Rx).
Observable.system(
initialState: 0,
reduce: { (state, event) -> State in
switch event {
case .increment:
return state + 1
case .decrement:
return state - 1
}
},
scheduler: MainScheduler.instance,
feedback:
// UI is user feedback
bind(self) { me, state -> Bindings<Event> in
let subscriptions = [
state.map(String.init).bind(to: me.label.rx.text)
]
let events = [
me.plus.rx.tap.map { Event.increment },
me.minus.rx.tap.map { Event.decrement }
]
return Bindings(
subscriptions: subscriptions,
events: events
)
}
)
Simple automatic feedback loop.
Observable.system(
initialState: State.humanHasIt,
reduce: { (state: State, event: Event) -> State in
switch event {
case .throwToMachine:
return .machineHasIt
case .throwToHuman:
return .humanHasIt
}
},
scheduler: MainScheduler.instance,
feedback:
// UI is human feedback
bindUI,
// NoUI, machine feedback
react(request: { $0.machinePitching }, effects: { (_) -> Observable<Event> in
return Observable<Int>
.timer(1.0, scheduler: MainScheduler.instance)
.map { _ in Event.throwToHuman }
})
)
Driver.system(
initialState: State.empty,
reduce: State.reduce,
feedback:
// UI, user feedback
bindUI,
// NoUI, automatic feedback
react(request: { $0.loadNextPage }, effects: { resource in
return URLSession.shared.loadRepositories(resource: resource)
.asSignal(onErrorJustReturn: .failure(.offline))
.map(Event.response)
})
)
Run RxFeedback.xcodeproj
> Example
to find out more.
CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:
$ gem install cocoapods
To integrate RxFeedback into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'RxFeedback', '~> 3.0'
Then, run the following command:
$ pod install
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.
You can install Carthage with Homebrew using the following command:
$ brew update
$ brew install carthage
To integrate RxFeedback into your Xcode project using Carthage, specify it in your Cartfile
:
github "NoTests/RxFeedback" ~> 3.0
Run carthage update
to build the framework and drag the built RxFeedback.framework
into your Xcode project. As RxFeedback
depends on RxSwift
and RxCocoa
you need to drag the RxSwift.framework
and RxCocoa.framework
into your Xcode project as well.
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift
compiler.
Once you have your Swift package set up, adding RxFeedback as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/NoTests/RxFeedback.swift.git", majorVersion: 1)
]
Cmd
, which effects to perform are encoded into state and queried by feedback loops