Does somebody can explain me how to implement MVVM pattern, when project includes Storyboard?
In many examples I saw that I have to use .xib
files. And init
ViewControllers
like this:
-(instancetype)initWithModelView:(ViewModel *)viewModel{
self = [super init];
if(self){
_viewModel = viewModel;
}
return self;
}
But with Storyboard I cannot init
viewControllers
, storyboard does it for me.
Should I use properties instead?
i.e.
UINavigationController *nav = (UINavigationController *)[self.viewControllers objectAtIndex:0];
HomeViewController *hvc = (HomeViewController *)[nav.viewControllers objectAtIndex:0];
hvc.viewModel = viewModel;
self is UITabBarController
.
MVVM (Model View ViewModel) is a design pattern, which has been widely used as more event-driven apps have started emerging. A few years back, if anyone built a product, it has probably been built using MVC (Model View Controller). In recent times, the MVC architecture has lost its place as the default design pattern.
What most developers do to avoid the drawbacks of the MVC architecture is turn to the Model–View–ViewModel (MVVM) pattern. MVVM is better at separating logic and data, so it's a great choice to implement the thin controller, fat model concept.
In MVC, the controller is the entry point to the Application, while in MVVM, the view is the entry point to the Application. MVC Model component can be tested separately from the user, while MVVM is easy for separate unit testing, and code is event-driven.
As an iOS developer we all have used MVC architecture. Apple also recommends to use it and it's really popular architecure. But there is difference in how it pans out practically and how it should be in theory.
You can initialize a viewModel
property in prepareForSegue:sender:
method of your UIViewController
Here is a link to a great sample MVVM app C-41 by Ash Furrow
An example of a viewModel
initialization in that app:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:@"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
ASHDetailViewController *viewController = segue.destinationViewController;
viewController.viewModel = [self.viewModel detailViewModelForIndexPath:indexPath];
} else if ([[segue identifier] isEqualToString:@"editRecipe"]) {
ASHEditRecipeViewController *viewController = (ASHEditRecipeViewController *)[segue.destinationViewController topViewController];
viewController.viewModel = [self.viewModel editViewModelForNewRecipe];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With