I am using MVVM with Coordinator to design an application. One thing that i am having doubts on is on how to pass data between different ViewModels
. Normally the previous viewModel would just create the next viewModel and would just do a method dependency injection in prepareforsegue
. However now that i am responsible for all the navigation how do i achieve this ?
Class AppCoordinator : NSObject, Coordinator, UINavigationControllerDelegate {
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
var dependencyContainer : MainDependencyContainer
func start() {
let vc = ViewController.instantiate()
vc.coordinator = self
vc.viewModel = dependencyContainer.makeMainViewModel()
navigationController.delegate = self
navigationController.pushViewController(vc, animated: true)
}
func createAccount() {
let vc = CreateAccountViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: true)
}
}
I could ofcourse create the ViewModel
for CreateAccountViewController
in MainViewModel
and pass the ViewModel
as a paramter in createAccount
method but is it the right way to do it here ? What will be the unit testing implications here ?
Ideally, you don't want both ViewModels to interact with each other and keep both elements separated.
One way to deal with it is to pass through the minimum data required for the navigation.
Going further, you can create a specific Coordinator for
CreateAccountViewController
that will get initialized with those data. Thestart()
method will do create whatever is needed for its ViewController.In this last example, the coordinator is only responsible to build its view and pass through essential information to next coordinator whenever needed. The viewModel is only exposed to its view, and eventually the view is unaware of both. It could be a good alternative in your case.
Finally, you can test using a protocol abstraction to make sure
performAction
triggersshowAccount
, thatshowAccount
create a child coordinator, and so on.