5

I read about VIPER architecture here http://www.objc.io/issue-13/viper.html (and in a few other sources), but I still can't figure out one thing, should each presenter interacts with at most one Interactor?

Here is a longer discussion about it that might better explain my question: Use Case with 2 ways for the same action

Community
  • 1
  • 1
Rodrigo Ruiz
  • 4,248
  • 6
  • 43
  • 75

5 Answers5

10

As I get it, the presenter is unique per VC. However, when a presenter needs several interactors, he may use them.

The interactors as for my opinion is a layer of business logic, they can interact with each other and the presenters can interact with many of them.

However, it's important to put the right logic in the right layer. For instance, be careful not to put the business logic in the presenter layer since its very tempting to while having to navigate between several interactors. Keep in mind to put the business logic only in the interactors.

Asaf Shveki
  • 736
  • 8
  • 11
  • 2
    How do I know what is business logic? – Rodrigo Ruiz Mar 15 '15 at 05:37
  • 3
    Think about the logic that doesn't include UI logic, something that serve your business needs. For instance - fetching data, playing with permissions, calling to API A for case A and to API B in case B.. – Asaf Shveki Mar 16 '15 at 16:33
2

Ideally, NO. One Presenter should know about the existance of only ONE Interactor. But the interactor itself can have many Data Managers. I usually use at least two data maangers: one for API requests and one for Local Data management.

For more advanced tips and helpful good practices on VIPER architecture, I recommend this post: https://www.ckl.io/blog/best-practices-viper-architecture (sample project included)

Marcelo Gracietti
  • 3,121
  • 1
  • 16
  • 24
  • It's fine and dandy when you have one screen/module doing one thing. But what do you do when you have 5+ screens where the user can login from? Are you going to put service.doLogin(), and handle the response in every Interactor? And promptly **duplicate your Business Logic** in every Interactor? – Lord Zsolt Sep 13 '19 at 08:47
1

A little bit late to the party, but I just Googled this question searching for something else.

It really depends on your implementation of VIPER. There is no single correct one, from what I've seen people implement it in really different ways and it should be adjusted to fit your specific needs.

Some projects have tightly coupled interactor per view, where the view displays data, presenter passes the data between the view and interactor (converting it in the process) and the interactor handles the business logic per view. In this case the presenter would talk to only a single interactor.

Other projects implement interactors per use case, or in other words, "minor" feature. That way you can avoid duplicating business logic between the modules. The presenter can talk to multiple interactors here.

There are also projects that implement large interactor per "big" feature or should we say per area of the app. That way the interactors tend to be pretty large, but also really become the "smart" layer responsible for the business logic decision for the app and they tend to have access to everything they need to make those decisions.

Let's give an example here - let's say you have a log out button in the side menu of your app and also in the settings and that for the log out you need to clear your database, keychain, user defaults and the networking session. A rather common scenario.

In the first case, where you have and interactor per view, you'd obviously have duplicated business logic. I believe that's how the "original" VIPER works, but it's probably not the best approach.

In the second case you'd probably have a "user session interactor" handling just logging in and out the user.

In the third case, you'd have a "user interactor" that would not only handle the session, but also save and manage all the user's data.

My usual approach is the third option, with the big downside of the need to split the interactors over multiple files. Many people use the second option. It may also happen that for your project the first option is the best - for example if there is little overlap between screens in your project and they are tightly aligned with features.

0

Ideally no, as Marcelo points out. However I feel like adding the "D" to VIPER for data managers is also not ideal.

A big problem in VIPER is that the presenter already knows which use case to "fire off" upon receiving input from the view, therefore it already has some apriori knowledge of the business use cases. This fact alone calls into question the entire architecture in my view, since if the presenter merely notified the interactor of a use-case-agnostic or purely UI event on the view, it would serve no purpose for existing. The presenter in VIPER has to have a tiny bit of "business logic", no matter what.

So, since the presenter already must orchestrate use cases by talking to the interactor, have one interactor per business use case, and the presenter can connect them if there is more than one business use case per "module". The boundaries in VIPER are often times difficult to maintain in practice without workarounds, but it is a nice architecture for forcing devs to think about separation of concerns.

paperview
  • 33
  • 1
  • 4
0

According to the CheeseCake Best Pratices, the only what to connect multiple VIPER modules should be by using the Router Layer. This way, if you remove any module the only layer that will present errors in other related modules would be the Router. Also, to avoid coupling, Entities may be put in a separate module exclusive for this purpose. Finally, to mitigate the code duplication, similar entities (e.g., user and profile) would be grouped into the same data managers.

  • My opinion is: try to find out the trade-off between code replication and module decoupling. I'm refactoring just now my code and the code replication saved a lot of time when removing particular modules that were without any dependencies.