I recently converted my first App Store approved app (Exhibit Finder DC) from the MVC to MVVM instead. MVC - Model View Controller - and MVVM - Model View ViewModel - are both design patterns; essentially methods of organization used within your app.
MVC is the design pattern which is typically taught first in Swift, and is generally speaking what Apple encourages developers to use. It consists of a Model that holds the data, a View that the user interacts with, and a Controller which acts as a go-between for the other two.
User actions in the View go through the Controller, which will provide the View with updates as needed. The Controller also updates the Model with changes, and the Model notifies the Controller if it has its own changes. Essentially the View and the Model never talk to each other directly (maybe they were estranged long ago) - their updates only get passed to each other via the Controller. The Model doesn't know what the View is doing, and the View can't tell what the Model is doing either. Each only knows what the Controller tells it.
In a common MVC setup in an Xcode project, a ViewController is the controller, the storyboard contains the View(s), and the Model is a class/struct which contains the data. This system works, and is easy enough to learn and implement, but it is by no means the only option out there.
MVC has earned a nickname of 'Massive View-Controller' from iOS developers in general, since the reliance upon the ViewController acting as a go-between for the View and Model often causes it to become bloated with code, and overburdened with responsibility. The unwieldy file then becomes hard to navigate and maintain, especially if the project grows.
This is where other design patterns can come into play. You may have seen some other abbreviations mentioned before, such as MVVM, VIP, MVP, and more - these other design patterns offer some options for solutions to the MVC problem. I'll focus on MVVM here, but I'd encourage you to learn more about the others too!
MVVM stands for Model View ViewModel, and consists of a Model for the data, a View the user interacts with, and a new piece - the ViewModel, which handles all manipulations of and interactions with the data. In this case we do still have a ViewController in the code, but its responsibilities are much diminished and it is only alluded to generally in the View part of the MVVM name.
MVVM is a helpful design pattern to use, since it better delegates responsibility in your project and abstracts the code out into user-friendly sections. Here, there is no longer any business logic in the controller. Its sole responsibility is to take care of the functionality of the View, and work those outlets and actions.
The Model holds onto all of the data, as before, but it does not perform any work on it. The ViewModel handles all manipulations of the data and gets data from the Model, but the only thing it knows about the Model; it is ignorant of the controller and never touches any of the controller actions etc and has no influence on the View.
When the controller needs to display data, it asks the ViewModel to give it what it needs, and the ViewModel gets that data from the Model, then passes it along. What the controller then does with that feedback is outside of the range of the ViewModel's knowledge, however.
Switching a MVC project over to be a MVVM one instead can be a bit daunting, but here are a few things to keep in mind while in the midst of the rearrangement:
- There should be no business logic in the view controller
- The view controller should only handle appearance/the view
- The model should simply hold onto the data
- The view model should handle all manipulation of the data
- The view model should not be aware of the controller
- The controller does not access data, but asks the view model for it
I hope this summary helps you see the essential differences between MVC and MVVM, and how you might use each! If you'd like to see specifically how a project changes from MVC to MVVM, please check out my Exhibit Finder DC repo, and see the difference between the older version and the new one! Happy coding!