RxViewBinder is a simple one-way architecture.
Simple and easy to implement. ☀️
It is implemented as a reactive extension.
- Create a ViewBinder class that implements ViewBindable.
Command, Action, State must be implemented.
Command is enum type.
Action, State is structure type.
important!!
You need to bind the action and state in the constructor of the state structure.
final class SampleViewBinder: ViewBindable {
enum Command {
case fetch
}
struct Action {
let value: PublishRelay<String> = PublishRelay()
}
struct State {
let value: Driver<String>
init(action: Action) {
// Action and state binding
value = action.value.asDriver(onErrorJustReturn: "")
}
}
let action = Action()
lazy var state = State(action: self.action)
}
- implements a binding method that accepts a command stream and sends the stream to action.
When changing the state of ui, only action is used.
state is used only when the view receives the state of ui.
func binding(command: Command) {
switch command {
case .fetch:
Observable<String>.just("test")
.bind(to: action.value)
.disposed(by: self.disposeBag)
}
}
- Or you can simply send the stream without creating an observer.
func binding(command: Command) {
switch command {
case .fetch:
action.value.accept("test")
}
}
- Implement the BindView protocol on the view controller.
It injects the view binder at initialization.
final class ViewController: UIViewController, BindView {
typealias ViewBinder = SampleViewBinder
init(viewBinder: ViewBinder) {
defer { self.viewBinder = viewBinder }
super.init(nibName: nil, bundle: nil)
}
}
- If you are using a storyboard, you have to inject it in a different way.
let vc = ViewController()
vc.viewBinder = SampleViewBinder()
or
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.viewBinder = ViewBinder()
}
- Implements the command and state methods.
func command(viewBinder: ViewBinder) {
self.rx.methodInvoked(#selector(UIViewController.viewDidLoad))
.map { _ in ViewBinder.Command.fetch }
.bind(to: viewBinder.command)
.disposed(by: self.disposeBag)
}
func state(viewBinder: ViewBinder) {
viewBinder.state
.value
.drive(onNext: { print($0) })
.disposed(by: self.disposeBag)
}
- Swift 5.0+
- iOS 9.0+
- For iOS 9+ projects with CocoaPods:
pod 'RxViewBinder', '~> 2.0.0'
- For iOS 9+ projects with Carthage:
github "magi82/RxViewBinder" ~> 2.0.0
magi82, devmagi82@gmail.com
RxViewBinder is available under the MIT license. See the LICENSE file for more info.