The last word VIPER structure tutorial


Swift design patterns and iOS architectures

A software program design sample is mainly a generic template of how one can remedy a selected – however normally native – scenario. Achitectural patterns have larger affect on the entire codebase, they’re excessive degree generic templates. Please keep in mind one factor:

there isn’t any such factor as a nasty structure

The weapon of alternative solely relies on the scenario, however you recognize every little thing is relative. Let’s stroll by all of the iOS design patterns and architectures actual fast and begin studying VIPER. 🐍

Swift design patterns

Let’s begin with the fundamentals, proper? If we do not get into UIKit, we will discover that there are numerous design patterns invented, possibly you recognize a few of them already. However hey, since we do not have that a lot time and I might like to speak about VIPER, let’s take a look at the fundamental precept of constructing UIKit apps utilizing the MVC sample.

MVC

The Mannequin-View-Controller (Huge-View-Controller) sample is a fundamental idea. You will have normally an enormous UIViewController subclass that controls all of the views and collects each mannequin that wanted to be displayed for the top person. For instance you name an API endpoint utilizing URLSession or Alamofire from the controller, do the response knowledge validation and formatting then you definately implement your desk or assortment view delegates on the view controller, so mainly all the applying logic goes inside that single overstuffed depressing view controller class. Does this ring a bell for you? 🙄

MVVM

After realizing the issue, the very first thing that you are able to do is outsourcing the info remodeling or binding half to a separate class. That is how the sensible folks at Microsoft invented the Mannequin-View-ViewModel structure sample. Now you are one step nearer, your knowledge fashions and the views can have their “get collectively” on a complete new degree inside shiny new recordsdata far-far away from controller land. Nonetheless this sample is not going to clear up all of the leftovers contained in the view controller. Do not forget that you continue to must feed the view controller with knowledge, deal with all of the completely different states.

MVP

What if we transfer out all the info loading and presentation stuff from the view controller and put it into a brand new class magically known as the Presenter? Sounds good, the view controller can personal the brand new presenter occasion and we will stay fortunately ever after. Come on folks we must always actually rename this to the Most Precious Sample ever! 😉

The Coordinator sample

Say hiya to The coordinator by Soroush Khanlou. Or ought to I merely name this because the Inverse Mannequin View Presenter sample? Look, right here is the deal, coordinators are on a complete new degree inside this evolution progress, however in addition they have an excessive amount of to do. It is in opposition to the Single Accountability precept, as a result of now you need to handle the presentation context, the info storage, the routing and all of the completely different states inside coordinators or sub-coordinators… however, lastly your view controller is free from all of the leftover baggage and it could possibly focus instantly on it is job, which is? 🙃

To be fucking dumb.

Presenting views utilizing UIKit associated stuff, and forwarding occasions.

I do not hate the design patters from above, I am simply merely making an attempt to level out (in a humorous / sarcastic means) why VIPER was born on the primary place. 😅

Are you continue to with me? 😬

The VIPER structure

To begin with DO NOT imagine that VIPER is unhealthy, simply because somebody misused it. I believe it is a freaking superb structure! You simply must be taught it correctly, which is tough, due to the shortage of excellent tutorials. Everyone seems to be evaluating architectures, however that is not what folks ought to do. So far as I can see, an MVP is nice for a small app with a couple of screens, it is best to by no means use VIPER for these apps. The true downside begins when you app grows and an increasing number of parts get into the sport.

If you’re planning to jot down a small app, simply begin with MVC. In a while you may repair the huge view controller downside with MVVM, however if you wish to take it one degree additional you may at all times use MVP or the coordinator sample to maintain maintainability. Which is totally positive, till you notice sooner or later that your code is filled with utility courses, managers, handlers and all of the nonsense objects. Sounds acquainted? 😅

As I discussed this earlier than there isn’t any such factor as a nasty structure. There are solely unhealthy selections, which lead us to hardly maintainable codebases. So let me information you thru probably the most helpful design sample that you’re going to ever wish to know to be able to write really scalable iOS purposes: VIPER with module builders = VIPER(B)

Understanding VIPER

The VIPER structure is predicated on the only accountability precept (S.O.L.I.D.)) which leads us to the speculation of a clear structure. The core parts or to illustrate layers of a VIPERB module are the next ones:

View

It is the interface layer, which implies UIKit recordsdata, largely UIViewController subclasses and all the opposite stuff. Views do not do something that is associated to enterprise logic, they’re only a presentation and occasion forwarding layer which is utilized by the presenter. As a result of the view is only a pure view controller, you need to use MVVM ideas or knowledge managers to make your venture much more concise.

Interactor

The interactor is answerable for retrieving knowledge from the mannequin layer, and its implementation is totally unbiased of the person interface. It is essential to do not forget that knowledge managers (community, database, sensor) usually are not a part of VIPER, so they’re handled as separate parts (providers), coming outdoors from the VIPER module land and they are often injected as dependencies for interactors.

The Interactor can put together or rework knowledge, that is coming from the service layer. For instance it could possibly do some sorting or filtering earlier than asking the correct community service implementation to request or save the info. However do not forget that the Interactor does not know the view, so it has no thought how the info needs to be ready for the view, that is the function of the Presenter. 🙄

Presenter

UIKit unbiased class that prepares the info within the format required by the view and take selections primarily based on UI occasions from the view, that is why generally it is referred as an occasion handler. It is the core class of a VIPER module, as a result of it additionally communicates with the Interactor and calls the router for wire-framing (aka. to current a brand new module or dismiss the present one).

It is the one class that communicates with virtually all the opposite parts. That is the ONLY job of the presenter, so it mustn’t know something about UIKit or low degree knowledge fashions. Mainly it is the guts of the applying, or some would say it is the place the place all of the enterprise logic will get applied. 💜

Entity

Plain mannequin courses used largely by the interactor. Normally I am defining them outdoors the VIPER module construction (within the service layer), as a result of these entities are shared throughout the system. We may separate them by module, however normally I do not like that strategy as a result of e.g. all of the CoreData fashions will be generated into one place. Similar factor applies in case you are utilizing Swagger or the same device.

Router

The navigation logic of the applying utilizing UIKit courses. For instance in case you are utilizing the identical iPhone views in a iPad utility, the one factor which may change is how the router builds up the construction. This lets you maintain every little thing else, however the Router untouched. It additionally listens for navigation move adjustments from the presenter, so it’s going to show the correct display screen if wanted. Additionally if you must open an exterior URL name UIApplication.shared.openURL(URL) contained in the Router as a result of that is additionally a routing motion, the identical logic applies for social media sharing utilizing UIActivityViewController.

Additionally if you need to move knowledge between VIPER modules it looks like a proper place to do that within the router. I normally talk between two module utilizing a delegate sample, so I picked up this behavior of calling delegate features within the router. 📲

Builder

Some individuals are utilizing the router to construct the entire module, however I do not like that strategy. That is why I am at all times utilizing a separate module builder class. It is solely accountability is to construct the whole module through the use of dependency injection for all of the exterior providers. It may possibly additionally construct mock or different variations of the identical module. That is fairly useful if it involves unit testing. Completely is sensible. 👍

NOT every little thing is a VIPER module

For instance if you wish to create a generic subclass from a UIViewWhatever please do not attempt to stuff that into the parts above. It’s best to create a spot outdoors your VIPER modules folder and put it there. There can be some use instances with particular courses which can be higher to not be VIPERized! 😉

Companies and utility particular code

I normally have 3 separate layers in my purposes. Modules, providers, and app. All of the VIPER modules are sitting contained in the Modules folder. Every little thing that is community or knowledge associated goes to the Companies folder (API service, core knowledge service, location service, and so forth.) and in a while will get used within the module builder relying the present surroundings (for instance mock implementation for testing). All of the remaining stuff like view subclassess, and different UI associated objects, app particular styling or design clever issues are positioned contained in the App listing.

Tips on how to write VIPER code?

I can not emphasize sufficient how essential is to be taught this structure earlier than you begin utilizing it. I imagine that issues can go actual unhealthy if somebody misunderstands VIPER and begin placing view logic in a presenter for instance. In the event you had a earlier unhealthy expertise with VIPER, take into consideration this quote: do not blame the device, blame the carpenter (simply as Ilya Puchka properly stated on a twitter dialog). 🔨

Each single part will simply get into the appropriate place when you observe the foundations of VIPER.

Module era

By no means begin to create a VIPER module by hand, it is best to at all times use a code generator, as a result of (sadly) you may want a number of boilerplate code for every module. That appears fairly unlucky at first sight, however that is what provides the true energy of this structure. All members of your developer staff will know the place to search for if a particular challenge happens. If it is a view challenge, you need to repair the view, if it involves a navigation downside then it is a router downside.

There are numerous current code generator options (one of many well-known is Generamba), however I made my very own little Swift device for producing VIPER modules.

Naming conventions

Protocols are outlined for nearly each VIPER part. Each protocol can be prefixed with the module identify, and it will not have some other suffix besides from the layer identify (like MyModuleRouter, MyModulePresenter).

Default implementation is used for the fundamental situation, each protocol implementation follows the ModuleName+Default+Layer naming conference. So for instance MyModuleDefaultRouter or MyModuleDefaultPresenter.

Inter-module communication utilizing delegates

The move is one thing like this:

Router / Presenter

The presenter can ship occasions for the router utilizing the router protocol definition.

Presenter / Interactor

The interactor can notify the presenter by the presenter’s interface, and the presenter can name the interactor utilizing the outlined strategies contained in the interactor protocol.

Presenter / View

The view normally has setter strategies to replace it is contents outlined on the view protocol. It may possibly additionally notify the presenter of incoming or load occasions by the presenter protocol.

Knowledge switch between modules

Think about a listing, you choose an merchandise and go to a brand new controller scene. It’s a must to move not less than a singular identifier between VIPER modules to make this attainable.

It is normally performed considerably like this:

  • The view calls the didSelect technique on the presenter with the id
  • The presenter forwards the id to the router utilizing the routeFor(id) technique
  • The router calls the builder to construct a brand new module utilizing the id
  • The builder builds the brand new module utilizing the id
  • The router presents the brand new module utilizing it is view (controller)
  • The brand new module passes the id for everybody who wants it (router, presenter)
  • The brand new module’s presenter will get the id
  • The brand new module’s interactor masses the info and provides it for the presenter
  • The brand new module’s presenter provides the info for the view and presents it
  • Element display screen seems with correct knowledge.

If you’re presenting a controller modally you can too move the unique router as a delegate, so you can shut it correctly if it is wanted. 😎

Reminiscence administration

Lengthy story quick:

  • The builder holds no-one.
  • The router retains a weak reference of the view and the presenter.
  • The presenter holds the router and the interactor strongly
  • The interactor retains a weak reference of the presenter
  • The view retains a powerful reference of the presenter
  • UIKit holds the views.

It’s best to test this within the offered instance, no leaks – I hope so – every little thing will get launched good and easily after you return or dismiss a module. 🤞

Last conclusion: ought to I be taught VIPER?

Though VIPER is extremely criticized due to it is complexity, all I can say it is definitely worth the effort to be taught its ideas correctly. You will see that there are far more advantages of utilizing VIPER as a substitute of ignoring it.

Benefits

  • Simplicity – for big groups on advanced initiatives
  • Scalability – simultaneous work seamlessly
  • Reusability – decoupled app parts primarily based on roles
  • Consistency – module skeletons, separation of issues
  • Readability – Single duties (SOLID)
  • Testability – separated small courses, TDD, higher code protection
  • Interfaces – module independence, nicely outlined scopes
  • Bug fixing – simpler to trace points, find bugs and issues
  • Supply management – smaller recordsdata, much less conflicts, cleaner code
  • Straightforward – codebase appears to be like comparable, sooner to learn others work

Drawbacks

  • Verbosity – many recordsdata per module
  • Complexity – many protocols and delegates
  • On-boarding – lack of correct VIPER information
  • Engagement – VIPER is unhealthy, as a result of it is advanced, meh!

I made a follow-up article about VIPER greatest practices that I’ve be taught alongside the journey, yow will discover the pattern repository on GitHub. I hope that these tutorials will aid you to be taught this structure higher, you probably have any questions, be happy to contact me. 👨‍💻



Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles