RxController is a library for the development with MVVM-C based on RxFlow and RxSwift. If you are not familiar with them, please learn these frameworks at first:
- RxSwift (https://github.com/ReactiveX/RxSwift)
- RxCocoa (https://github.com/ReactiveX/RxSwift)
- RxFlow (https://github.com/RxSwiftCommunity/RxFlow)
RxController provides the the following basic view controller and view model classes.
- RxViewController
- RxViewModel
- RxChildViewController
- RxChildViewModel
These classes make it easy to transfer data among the flows, the parent view models and the child view models.
RxController is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'RxController'
The example app helps you to understand how to use RxController.
To run the example project, clone the repo, and run pod install
from the Example directory first.
RxController provides generic classes RxViewController
and RxChildViewController
.
With the genric classes, RxController avoids using an Optional
or an Implicit Unwrapping Option
type for the view model property in the view controller class.
In the demo app, we define the view model class by extending the RxViewModel class, and the view controller class by extending the RxViewController generic class.
// View model class
class InfoViewModel: RxViewModel {
}
// View controller class
class InfoViewController: RxViewController<InfoViewModel> {
}
Then, we can initialize the InfoViewController
with a safe way as the following.
func navigate(to step: Step) -> FlowContributors {
guard let appStep = step as? AppStep else {
return .none
}
switch appStep {
case .start:
let infoViewController = InfoViewController(viewModel: InfoViewModel())
navigationController.pushViewController(infoViewController, animated: false)
return .viewController(infoViewController)
}
}
In a standard MVVM-C architecture using RxFlow, view models exchange data via the a flow class using the steps.accept()
method.
With RxChildViewModel
and RxChildViewController
, we can exchange data among parent and child view models without the flow class.
We define a event struct in the parent view model.
struct InfoEvent {
static let name = RxControllerEventType(type: String.self)
static let number = RxControllerEventType(type: String.self)
}
Send a event from the parent view model.
events.accept(InfoEvent.name.event("Alice"))
Send a event from the child view model.
accept(event: accept(event: InfoEvent.name.event("Alice")
Receive a event in the parent view model.
var name: Observable<String?> {
return events.value(of: InfoEvent.name)
}
Receive a event in the child view model.
var name: Observable<String?> {
return parentEvents.value(of: InfoEvent.name)
}
lm2343635, [email protected]
RxController is available under the MIT license. See the LICENSE file for more info.