Your favorite Marvel characters in one app.
-
Fetch an online list of the marvel characters ✅
-
See the details of your favorite character when selecting a cell ✅
-
Search for specific characters by their names ✅
-
Use it on iPad and iPhone ✅
-
Support to Portrait and Landscape ✅
We are using the MVVM-C with a slight change: We have renamed our ViewModel to Reactor. We use a unidirectional flow between the View and the Reactor.
What is a Reactor?
A Reactor is an UI-independent layer that manages the state of a view. The foremost role of a reactor is to separate control flow from a view. Every view has its corresponding reactor and delegates all logic to its reactor. A reactor has no dependency to a view, so it can be easily tested.
The code is designed for simplicity, reusability, and testability. All classes are tested.
While using the traditional bindings between a View and a View Model, we might end up having several communications going on, and to make it even harder there are also the side effects. The image below speaks for itself.
By using unidirectional flow into the View Model, we have the following benefits:
- Combining all inputs into one stream containing an enum of user intents
- Combining all outputs into one stream of state objects
- The Reactor(ViewModel) reacts to user input and triggers an output as a
State
, regardless of the side effects. - The view listens to the state and reacts to it accordingly.
- It's very easy to test as we just have to provide inputs and expect outputs(See the
CharactersReactorTest
for instance)
That being said, we can achieve the following result:
The project is structured in multiple targets:
-
🦸♂️ MarvelHeroes - The app's main target. It uses all other targets as dependencies.
-
🧿 Core - The core target provides the base and reusable classes and extensions that can be used by the main target. For instance: classes such as a
BaseCoordinator
, useful extensions forRxSwift
,UIKit
and so on. -
📡 Network - Provides an abstraction of the network layer as a service. Through this target, we can use all operations we need for network requests. Furthermore, as we just expose the API we can easily replace the network framework/components without affecting the Network's target consumers.
-
📒 Domain - Provides raw structs of models that are being used in the project.
- RxSwift - Reactive programming for Swift
- ReactorKit - Reactive and unidirectional Swift application architecture
- SnapKit - DSL to make Auto Layout easy on iOS.
- Kingfisher - Library for downloading and caching images from the web
- Moya - Network abstraction layer.
- RxExpect - A testing framework for RxSwift