Everything is clear and easy in theory, but there are some troubles in reality.
The first and the main problem — dependencies between parts of VIPER-module (Presenter, Interactor, etc.) There are 2 ways to solve this problem:
1) Inject all dependencies by own hands
2) Use some libraries for dependency injection (for example Typhoon).
The first variant is more complicated and waste more time than the second. Programmer have to inject dependencies in the right way and do it without memory leak. Why it's leaked? It happens because of double connections — Router has strong reference to Presenter, on the other hand, Presenter strong reference to Router. The same thing is between View and Presenter. To solve this problem we use 1 weak reference to object (from Presenter to View, from Presenter to Router) instead of 2 strong. So there are no cycles now and object will be destroyed when it become useless. Main advantage of this method — everything is clear and programmer controls live cycle of objects.
Using libraries can make programmer happier, because he doesn't have to think about dependency injection. But there is some new problem here — libraries could be changed or dissapeared. Taking into consideration the fact that the library is responsible for connectivity of application, missing of this library will be catastrophic. If it's happened, developer have to find new library or inject all dependencies by himself. Anyway, it wastes a lot of time.
Another trouble is that big part of libraries and some standard features of Swift and Objective C aren't compatible with VIPER (for example UITableVIew). It's often happened because principle of single responsibility is breaking by these things. Some of this errors we found in our project — before changing application structure to VIPER, we use some textField which has his own email validation. It's called from instance of this textField class. So there is logic inside View-layer. There are some ways to solve it:
— forget about single responsibility principle and leave well enough alone;
— send this textField to Interactor, but it's not simple object => breaking the VIPER principles;
— remove library from project and write validation methods inside Interactor by our own hands;
There is not so big problem here, which is solved very fast (we choose last way and write everything without library), but sometimes it can be very difficult to find way to fix it and not break VIPER principles. Anyway it waste a lot of time and require clever developer.