VIPER of many faces — Part 2: iOS Demo

Mladen Despotovic
iOS App Development
5 min readAug 9, 2018
Courtesy of iStockPhoto

… continuing from Part 1, where we explained the motivation, we shall now introduce the demo project.

To make it easy to understand this demo codebase in the fastest possible way, I will first present a simple sequence diagrams for the following actions:

  • Dashboard gets loaded for the first time
  • User taps any of the Top Highlights
  • User selects a payment from Last Payments list

These actions will be presented through the sequence diagrams of 3 view controllers:

DashboardViewController

This one is basically our main view

DashboardViewController Sequence Diagram

LastPaymentsViewController and PaymentDetailViewController

LastPaymentsViewController is embedded into theDashboardViewController. and the PaymentsDetailViewController is presented from it.

These 2 diagrams show following sequence of actions:

  • after viewDidLoad() method of DashboardViewController is called, then tap target-action on Highlights is configured
  • Mocked API is called, which returns back TopHighlightobjects to the DashboardPresenter which returns the call to DashboardViewController with the TopHighlightsSectionViewModel, which basically contains the state of expanded/collapsed presentation mode and array of TopHighlightViewModel objects
  • DashboardViewController calls its subview Highlights and passes it TopHighlightsSectionViewModel which uses it to populate the views
  • viewDidLoad() method of LastPaymentsViewController is also called, because the latter is the subview of DashboardViewController
  • similarly as with the Top Highlights, we call to the API and populate the UITableView
  • tapping any Top Highlight will collapse or expand the Top Highlights View
  • tapping any payment cell will navigate to PaymentDetailViewController

Code example

To complement sequence diagrams with short description above, I will just past the link to this short code example, there’s no need to explain the parts separately here.

You will see, that it uses the Module Oriented Architecture concept, which is not the focus of this blog, of couse.

Highlights of the demo project

Class structure is not rigid

We’ve already described this in the Part 1, but it doesn’t hurt to reiterate is here. We’ve been very pragmatic in how we’ve used the business logic, service layer and the views, yet we didn’t sacrifice the quality and provided high test coverage. Keep in mind that we are talking here only about Dashboard module coverage, of course… There’s quite a lot of boilerplate elsewhere which is not tested.

Boilerplate code

We can see, that thanks to Module Oriented Architecture and use of protocol extensions, we have reduced the boilerplate to the total minimum:

  • Wireframes are reduced to a minimum of instantiating variables
  • Presenters implement 3 mini functions of ModuleRoutable protocol
  • Module classes also contain measely 4 variables…

Almost no boilerplate code of whatsoever… Also, not a lot of code to add at all, to make the core VIPER classes functioning, which greatly reduces the time and also learning curve. This makes ideal base also for prototypes and small projects, gives almost a commodity of kind of framework that does the job for you.

Seamless integration of Apple’s MVC and Storyboards

For those who have read already the Module Oriented Architecture series, but especially the Part 6 — Outsmarting the MVC, you already understand, how complexity of integrating your business flow with UI Navigation elements was made smooth and without them taking over our architecture and application flow.

Complex communication between the classes

I think we’ve dealt with that one too in a clean and safe way from memory management perspective, again, benefiting from Module Oriented Architecture, VIPER and fundamental OOP principles. To substantiate this, I will use the class schema from Part 1 again:

  • View Controller communicates with the Presenter unilaterally and also owns it
  • Presenters do the same with Wireframes
  • Wireframes create View Controllers and assign them to application’s View/Navigation stack
  • Model objects are never persisted or made stateful in any other way
  • Presenter is the only one that owns View Models
  • View objects don’ t reference any other object in a class
  • Module doesn’t own any class, it acts merely as an gateway to create Presenter and as soon as the latter creates View Controller through Wireframe, is gets assigned to it and it’s gone from the Model’s function scope/loop and there is no connection to it from the outside
  • As soon as the structure is formed, we can see, that there is only one owner of the whole graph, which is basically UIWindow and as soon as user, for example, taps ‘back’ button, View Controller is deallocated and with it the whole structure. No way, we can incurr and large scale memory leaks

What could go wrong?

Few things. One would argue that Presenter ideally shouldn’t have the state. Although I think that would be a bit too assertive, I agree if this wouldn’t be Dashboard, but some service module, we would have to synchronize the access to the properties at least. Still, making it stateless would either create one additional API call for populating thePaymentDetailViewController or creating the latter in one go and retain it somewhere else, which would be a very dirty solution…

Also, what would be more general, if the view would be more complex, we would get much more relations between the objects and Presenter could become a busy junction with too many tasks and too much coupled.

But that is something, what we shall tackle in the next part, where things will get a bit more complicated…

Conclusion

Our demo project in its first stage delivers well against the expectations set in the Part 1 and we need to see, whether it will withstand the test of complexity. However, as mentioned beforehand, this is something for the Part 3

Stay tuned.

--

--