The Clean-er Architecture for iOS Apps
Clean Architecture for iOS was popularised by VIPER. On comparison with the original by Uncle Bob there turns out to be a small yet fundamental difference!
For the past year I’ve had the intellectual pleasure of discussing with friends in the business the various architectural patterns that can be used in iOS*.
The discussion often returns to ideas from the article ‘The Clean Architecture’. We try to understand it in the context of an iOS app and how it fits with the other patterns idiomatic of the platform like Model View Controller & Storyboards.
One recurring theme is understanding the ‘correct’ role of ‘Presenter’ — the most concrete example of which is detailed in Architecting iOS Apps with VIPER. VIPER has rightly been popular as the first working example and explanation of Uncle Bob’s Clean Architecture approach applied to iOS**
On closer comparison with the original source it turns out there’s an unexplained inconsistency between Clean Architecture and VIPER when it comes to the Presenter that seems quite fundamental.
We are introduced to the role of Presenter in VIPER with the following simple explanation:
Presenter: contains view logic for preparing content for display (as received from the Interactor) and for reacting to user inputs (by requesting new data from the Interactor)
The Clean Architecture
This seems reasonable until we compare it to the diagram from the original Clean Architecture article.
Did you see it? The innocous little pink line scribbled almost as an after thought! It goes on to explain:
The models are likely just data structures that are passed from the controllers to the use cases, and then back from the use cases to the presenters and views.
Note the flow of control. It begins in the controller, moves through the use case, and then winds up executing in the presenter. Note also the source code dependencies. Each one of them points inwards towards the use cases.
This becomes clearer (maybe) when you see a more detailed sequence diagram of all the participants.
VIPER adopts the traditional stack architecture approach where communication is bidirectional e.g flowing down through layers and then back up again. In The Clean Architecture the flow of control only ever travels round in one direction.
View -> Interactor -> Presenter -> View
The presenter isn’t the central coordinator of flow between the View and Interactor its single responsibility is as an interface adaptor to convert input from the Interactor into something convenient e.g. the View Model to pass across the boundary.
That’s it — a very small yet quite significant change. Suddenly the architecture becomes ever more simplified. There is a lovely elegance to the flow of control being in one direction and the benefits seem to be several:
- Easier reasoning about the architecture
- Improved separation of concerns
- Removing unnecessary boilerplate between Presenter <-> Interactor
- Removing temptation to intercept input passing through the Presenter
- Greater adherence to The Dependancy Rule
If your using VIPER then you’re already probably seeing most of the benefit of Clean Architecture in your project. Changing to the Clean-er Architecture probably isn’t worth starting a debate in your team over. That said it might be worth trying when you implement your next feature.