magi82/rxviewbinder
RxViewBinder is a simple one-way architecture.<br>
Flow
<img src="https://github.com/magi82/RxViewBinder/blob/master/Resources/flow.png?raw=true">
Usage (ViewBindable)
- Create a ViewBinder class that implements ViewBindable.
<br>Command, Action, State must be implemented. <br>Command is enum type. <br>Action, State is structure type.
important!! <br>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.
<br>When changing the state of ui, only action is used. <br>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")
}
}Usage (BindView)
- Implement the BindView protocol on the view controller.
<br>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)
}Requirements
- Swift 5.0+
- iOS 9.0+
Installation
- For iOS 9+ projects with CocoaPods:
pod 'RxViewBinder', '~> 2.0.0'- For iOS 9+ projects with Carthage:
github "magi82/RxViewBinder" ~> 2.0.0License
RxViewBinder is available under the MIT license. See the LICENSE file for more info.
Package Metadata
Repository: magi82/rxviewbinder
Default branch: master
README: README.md