Demo iOS application built to highlight MVP (Model View Presenter) and Clean Architecture concepts
Library is an iOS application built to highlight MVP (Model View Presenter) and Clean Architecture concepts
View
- delegates user interaction events to the Presenter
and displays data passed by the Presenter
UIViewController
, UIView
, UITableViewCell
subclasses belong to the View
layerPresenter
- contains the presentation logic and tells the View
what to present
Presenter
per scene (view controller)View
, but rather it references the View
protocol that is implemented usually by a UIViewController
subclassSwift
class and not reference any iOS
framework classes - this makes it easier to reuse it maybe in a macOS
applicationConfigurator
- injects the dependency object graph into the scene (view controller)
iOS
/ Swift
Router
- contains navigation / flow logic from one scene (view controller) to another
FlowController
iOS
framework classes so usually we try to keep it really simple and we don't write Unit Tests for itPresenter
but due to the func prepare(for segue: UIStoryboardSegue, sender: Any?)
method we some times need to reference it in the view controller as wellUseCase / Interactor
- contains the application / business logic for a specific use case in your application
Presenter
. The Presenter
can reference multiple UseCases
since it's common to have multiple use cases on the same screenEntities
and communicates with Gateways
to retrieve / persist the entitiesGateway
protocols should be defined in the Application Logic
layers and implemented by the Gateways & Framework Logic
Application Logic
depends on abstractions and not on actual frameworks / implementationsEntity
- plain Swift
classes / structs
Order
, Product
, Shopping Cart
, etcGateway
- contains actual implementation of the protocols defined in the Application Logic
layer
LocalPersistenceGateway
protocol using CoreData
or Realm
ApiGateway
protocol using URLSession
or Alamofire
UserSettings
protocol using UserDefaults
Persistence / API Entities
- contains framework specific representations
CoreDataOrder
that is a NSManagedObject
subclassCoreDataOrder
would not be passed to the Application Logic
layer but rather the Gateways & Framework Logic
layer would have to "transform" it to an Order
entity defined in the Application Logic
layerFramework specific APIs
- contains implementations of iOS
specific APIs such as sensors / bluetooth / cameraBooksPresenterTest
- highlights how you can test the presentation logicDeleteBookUseCaseTest
- highlights how you can test the application / business logic and also how to test async code that uses completion handlers and NotificationCenter
CacheBooksGatewayTest
- highlights how you can test a cache policyCoreDataBooksGatewayTest
- highlights how you can test a CoreData
gatewayApiClientTest
- highlights how you can test the API / Networking layer of your application by substituting the URLSession
stackGiving that a large majority of mobile apps are a thin client on top of a set of APIs and that most of them contain little business logic (since most of the business logic is found in the APIs) some of the Clean Architecture
concepts can be debatable in the mobile world. Below you can find some:
NSManagedObject
subclass for instance) leak in the other layers (see Parse
example that got discontinued)Use Cases / Interactors
simply delegate the actions to the Gateway
then maybe you don't need the Use Cases / Interactors
in the first place and you can use the Gateway
directly in the Presenter
display(xyz: String)
methods on a CellView
protocol is over-engineering and that passing a plane CellViewModel
object to the CellView
and have the view configure itself with the view model is more straightforward. If you want top keep the view as passive / dumb as possible then you should probably create the methods, but then again simply reading some strings from a view model and setting some labels is not really complex logicThe list above is definitely not complete, and if you identify other debatable decisions please create an issue and we can discuss about it and include it in the list above.
For the items listed above (and also for other items of your own) it is important that you use your own judgement and make an informed decision.
Keep in mind that you don't have to make all the design decisions up front and that you can refactor them in as you go.
Discuss about all the design decision with your team members and make sure you are all in agreement.
Please feel free to open an issue for any questions or suggestions you have!