VIPER At-a-glance

When I started the Nabaal Shipyard project, I was looking for a better way to organize my projects. Primarily what I’d experienced was the effect of MVC – Massive View Controllers. In fact, even in large professional projects this isn’t something new. You often head of ViewControllers with lengths into the 10000s+.

Obviously this comes as a side effect of a number of things – but for me it primarily comes from balancing the two forces of ease and clarity.

On one hand, MassiveVC happens because it’s easy. The whole point of iOS development is to get something off the ground quickly – you don’t need to worry about instantiating views or view elements or styling every little thing at the forefront. Sometimes you just want a UIButton. So throwing something into the ViewController is the quick n’ dirty way.

Of course, this comes at the cost of clarity. Because you have massive view controllers now and becuase there’s a lot of tightly coupled complexity there, maintenance now becomes a nightmare. And god forbid you’re dealing with multiple ViewControllers – now you easily have a massive unwieldy application….

Enter….Viper…..

How It works

View

  • Displays information to the user
  • Detects user interactions

The view is told by the presenter what to display and tells the presenter when an event needs to happen.

Presenter: NSObject

  • Tell the view what to display
    • Format the data of the view (recieved from the interactor)
    • Take an object and replace with text
  • Handle events accordingly

Tell the view what to display and handle events from the interactor

Interactor: NSObject

  • Perform business logic
  • Receive data from presenter, process it, and return to the presenter
  • Represents a single use case of an app
  • Should be independent of any UI
  • Never pass entities to the presenter
  • Never work with NSManagedObjects
  • Initiate a network operation, but does not handle the code directly

Entities: NSObject

  • Only manipulated by the interactor
  • Are never passed to the presenter
  • Sit in front of CoreData usually, separate from Interactors

Data Store:

  • Provide entities to an interactor
  • Sits right in front of CoreData

Router/Wireframe

  • Initializes classes and connects them
  • Handles the routing to other views in the application.

Considerations

CORE DATA

  • Use this behind the Data Manager / Entities

STORYBOARDS

  • Don’t use segues
  • Segues make it difficult to keep separation between screens, UI and logic, intact
  • Try not to use segues if implementing the prepareForSegue looks necessary

MODULES

  • Thought of as features
  • Modules can have very clear and well defined interfaces and be independent
  • Easier to add/remove features or change the way the interface presents modules
  • May also implement presenters, views, interactors, entities, and data managers
  • Important to wrap them in a protocol and a delegate to inform about the status or what happened when a module is created.

STRUCTS

  • Swift structs are perfects as PONSOs that carry small amounts of data between layers such as from the Presenter to the View.

Resources