Ribs: [Both platforms] Recommended approach for navigational flows - granular RIBs or Views?

Created on 28 Nov 2017  Â·  5Comments  Â·  Source: uber/RIBs

I realize that the RIBs framework is flexible enough to allow multiple approaches, but I'd like to collect some thoughts on design philosophy here.

Imagine a scenario in which we have a menu of options, the MainMenu RIB, which links to a child, ProfileMenu. ProfileMenu then links to each of three possible screens: ProfilePhotos, ProfileSummary, and ProfileHistory. The hierarchy looks like this:

    |
    |__ProfileMenu
        |
        |__ProfilePhotos
        |
        |__ProfileSummary
        |
        |__ProfileHistory

Would it be best practice to combine the Photos, Summary, and History RIBs into one and call it Profile which can display multiple Views, or should these indeed be separate RIBs?

Essentially, ProfileMenu performs no business/data logic aside from routing to the chosen menu selection. And each of its child RIBs are relatively minimal themselves. This is what leads me to prefer the approach of combining all four Profile RIBs into one, and just having the ProfileInteractor decide which new View to display, given the user's selection.

Is there any precedent for this in the sample code? I didn't see any examples in the tutorials of RIBs displaying multiple ViewControllers.

Given the best practices established at Uber, I'm curious about whether it's smart to create more granular RIBs like in the diagram above, or whether it's appropriate sometimes to have multiple ViewControllers per RIB. The answer is likely going to be "RIBs makes no requirement, do what's best for your app"; though I'd still like to hear some thoughts on the matter.

Thanks!

question

Most helpful comment

At Life360 (http://engineering.life360.com/), we're building some pretty major upcoming features using RIBs for our iOS and Android apps. We actually had developed our own implementation of RIBs since May which we based on the Uber Mobility talks and your blog post.

Luckily the implementation we've been working with has a lot of similarities with the "official" version here, so the RIB components can interoperate pretty seamlessly. And you guys added a LOT of features that we didn't have, so that's pretty exciting.

All 5 comments

The answer is likely going to be "RIBs makes no requirement, do what's best for your app"; though I'd still like to hear some thoughts on the matter.

You're right. That is the answer :)

Some things to consider are:

  • Creating each screen as a RIB will discourage coupling between these screens. If you write this as a single RIB then a bunch of the business logic will end up living in the ProfileMenu (or being inlined into ViewControllers which are likely hard to test). Creating each screen as its own RIB will create a bit more boilerplate. If each of these screens does highly distinct things, may get complex, may have different owners, may have child RIBs or store intermediate state it may make sense to separate the screens into different RIBs.
  • If each screen is just a different view of the same data, and likely to stay that way, you may get little benefits from splitting them up into multiple RIBs.
  • Creating each screen as a RIB will make your application lazier (ie more performant). If each profile screen does a little bit of logic, then splitting each screen into its own RIB prevents any of that logic from accidentally being executed eagerly

Hey @AttwellBrian, thanks a lot for the response.

If each of these screens does highly distinct things, may get complex, may have different owners, may have child RIBs or store intermediate state it may make sense to separate the screens into different RIBs.

That's a good suggestion to apply this rubric. Often I find myself looking at a screen with subcomponents and deciding which components should be broken up into RIBs vs. simply Views; this question can be answered by the question:

Does this component represent a distinct, discrete logic logical substate of the application, and if so, might it spawn children with their own substates?

Another question we find ourselves asking to help answer the question of RIB vs. View is this:

If our designer were to make this look different, like by combining these screens into one, or splitting this screen into many, would that have a big impact on our RIB hierarchy?

We're trying to stay as close to "No, the RIB hierarchy is rather decoupled from how the screens look" as we can. That said, you have great points regarding decoupling, testing, and lazy-performance that support more RIB granularity.

I think it's important to stay focused on the business-logic components, and not let the RIB hierarchy be dictated by what the app looks like. This is oftentimes difficult because you can't _see_ the business logic hierarchy of an application.

Anyway, great work so far on the RIBs framework, documentation, and outreach. I'm super excited to have this tool and to be able to have a much smarter, cleaner, app architecture because of it.

Glad you're finding this useful. I'm curious: what apps are you using this in Jake?

At Life360 (http://engineering.life360.com/), we're building some pretty major upcoming features using RIBs for our iOS and Android apps. We actually had developed our own implementation of RIBs since May which we based on the Uber Mobility talks and your blog post.

Luckily the implementation we've been working with has a lot of similarities with the "official" version here, so the RIB components can interoperate pretty seamlessly. And you guys added a LOT of features that we didn't have, so that's pretty exciting.

Here is some guidance that we landed on:

A good rule of thumb that I use when deciding whether some UI should be a rib are these questions:

“Does this UI ever attach a child to itself, or does it just inform its parent that it was clicked?“
If it attaches children, then creating the Router makes sense.

“Furthermore, does this component consist of several files and components that need to be hooked up together?“
If so, then creating a Builder for it makes sense.

“Finally, does this component talk to the network or database, or have some business logic that needs to be unit tested?“
If so, then creating the Interactor makes sense.

There are several cases I’ve seen in which we create a RIB structure for what is essentially just a small control / button. Typically a button would never attach a child to itself, nor would it have multiple components that need to be attached together, nor would it have lots of built-in business logic. Creating a Router, Interactor, and Builder just for a button may cause challenges in the future, making it more difficult to move this button around or change the UI, because it’s now a whole RIB.
It’s okay for a View to have subviews—especially if these subviews are pretty minimal in that they just report single events back to their Interactor.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ZH3057 picture ZH3057  Â·  4Comments

ermik picture ermik  Â·  7Comments

almozavr picture almozavr  Â·  4Comments

5torm5h4dow picture 5torm5h4dow  Â·  4Comments

kronik picture kronik  Â·  3Comments