In the last blog post, we developed an app demonstrating dependency injection with Swinject in a simple architecture. In the series of blog posts from today, we are going to develop an app taking advantage of dependency injection in MVVM (Model-View-ViewModel) architecture with ReactiveCococa.
Through the series of the blog posts, you will learn:
- How to setup an Xcode project to explicitly represent MVVM architecture.
- How to inject dependencies in the architecture with Swinject.
- How to use ReactiveCocoa to propagate events from Model to ViewModel and ViewModel to View.
The blog posts concentrate on the practical development using dependency injection, Swinject, MVVM and ReactiveCocoa. Please refer to other articles to learn the details of them. Recommended articles will be referenced later in the blog posts.
The example app we are going to develop asynchronously searches, downloads and displays images obtained from Pixabay via its API, as shown in the GIF animation below.
The source code used in the blog posts is available at:
- SwinjectMVVMExample: Complete version of the project.
- SwinjectMVVMExample_ForBlog: Simplified version of the project to follow the blog posts.
MVVM
MVVM (Model-View-ViewModel) is an architecture or pattern to make dependencies of components simple as View depends on ViewModel and ViewModel depends on Model linearly. Its event flow is linearly, in reverse, from Model to ViewModel and ViewModel to View.
On the other hand, in MVC (Model-View-Controler) architecture or pattern, Controller depends on Model and View, and its event flow is from Model to Controller and View to Controller.
The problem of MVC is that Controller tends to get large and complex as a project evolves because it has to take care of both Model and View, which mean everything. Actually MVC is a good pattern in web applications with the support of frameworks such as Ruby on Rails or ASP.NET MVC, but in iOS apps MVC often makes monolithic and hard-to-maintain code.
For the disadvantage of MVC, MVVM is getting popular to develop mobile apps or desktop apps. In iOS apps, the “View” of MVVM is composed of “View” (UIView) and “ViewController” (UIViewController). View logic, e.g. a value 1000
should be displayed as "1,000"
, is implemented in ViewModel. View simply uses values provided by ViewModel to display. Model is responsible for business logic. Because of the separation of the responsibilities, an iOS app in MVVM architecture is easier to test.
References
- Introduction to MVVM
- ReactiveCocoa and MVVM, an Introduction
- MVVM Tutorial with ReactiveCocoa: Part 1⁄2
ReactiveCocoa
MVVM propagates events from Model to ViewModel and ViewModel to View. We are going to use ReactiveCocoa to handle the events. The framework provides APIs to compose and transform event streams. Without ReactiveCocoa, events are represented by delegate methods, callback closures, UIControl actions, or KVO (Key-Value Observation). We had to write a different way of handling to each type of events. With ReactiveCocoa, an event is represented by Event
and event streams are represented by Signal
or SignalProducer
. We can handle the events in the same abstracted way regardless of the original source of events. From the next blog post, we will take advantage of the simplicity of the events with ReactiveCocoa. If you are new to ReactiveCocoa, it is recommended to read the following articles before proceeding to the next post.
References
Conclusion
MVVM has the simple and linear dependencies of View on ViewModel and ViewModel on Model, and event flows from Model to ViewModel and ViewModel to View. ReactiveCocoa turns various kind of events, such as delegate methods or callback closures, into a single type Event
of events. For the simplicity, an iOS app in MVVM architecture with ReactiveCocoa is easier to maintain and test. From the next blog post, step-by-step development with MVVM, ReactiveCocoa, dependency injection and Swinject will be demonstrated.