Ribs: Question about closing current view in a sequence

Created on 20 Nov 2017  路  13Comments  路  Source: uber/RIBs

Imagine this sequence:
Root(owns view) -> A(not owns view) -> B(not owns view) -> C(owns view).

If CViewController is closed by itself, I'd like to back to Root state.

So, on CViewController, I have a button to close current view.
I suppose that this button would call:

self.listener.didCloseTap()

I can imagine that this listener is B Interactor. However, what should B interactor do?

I don't know how to come back.

Could somebody help me with this?

P.S.: Sorry about opening multiple questions.. It's because I really need this in a short time.

Thanks.

question

Most helpful comment

Yip, the thing to remember is the interactor is always responsible for making logic decisions wether that be telling the router to detach or telling its listener i.e its parent interactor that it needs to make a decision based on some thing.

Regarding interactor making two commands, its totally fine for this to be async i.e pass a competition closure to the router to dismiss a view controller and for the router to call the closure once it has finished the dismiss so the interactor can make its next call.

All 13 comments

You would propagate that listener message all the way back to root in this case.

i.e Root(owns view) <- self.listener.myMethodOtherForClose() A(not owns view) <- self.listener.myMethodForClose() B(not owns view) <- self.listener.didCloseTap() C(owns view)

@sbarow thank you for your answer!

But if I do that, CViewController won't be dismissed since Root does not have access to dismiss C view controller... Only B router has access to dismiss C view controller..

You can choose who dismisses the view controller, which can either be done by C itself or by B, the message i.e the self.listener.myMethodForClose() can still be called letting A know something has happened.

@sbarow
We know that B has attached C... So, B is the responsible for detaching and dismissing C. I need something more concrete...

Are the next steps possible AND good approaches?

  • CViewController calls its self.listener.didCCloseTap()
  • self.listener is B Interactor
  • So, B Interactor calls router.detach()
  • Router detaches current child and dismiss C ViewController and calls self.iteractor.listener.didBClose()
  • Since self.iteractor.listener is A Interactor, A Interactor calls: self.router.detach()
  • self.router is A Router. It detaches current child and calls: self.interactor.listener.didAClose()
  • Since self.iteractor.listener is Root Interactor, Root Interactor calls: self.router.detach()
  • self.router is Root Router. It detaches current child stop there.

@sbarow it won't help. Since router detach method is able to dismiss current attached view controller but has not business intelligence/logic to call next parent interactor.

I really need a clear instruction about this.

  • "So, B Interactor calls router.detach()" - and calls listener (from interactor) So, B Interactor calls self.listener.didBClose()

Same pattern follows.

@sbarow

Same pattern follows.

It's impossible. Since router.detach() knows that it should detach current view, however, it does not know who has called him so as to decide that it should now call self.interactor.listener.didBClose() ...

Imagine if another kind of state not related to our sample has called router.detach()? Then we have a problem..

I am not sure I follow. B router attached C router right?

If so:

  • C view controller calls listener (C interactor ) to say its done i.e back/close button tapped.
  • C interactor calls listener (B interactor) to say C is done, decide what to do.
  • B Interactor tells B router detach C router.
  • B Interactor tells listener (A Interactor) to say B is done, decide what to do.
  • A interactor tells A router detach B router.
  • A interactor tells listener (Root interactor) to say A is done, decide what to do.
  • Root decides what to do.

Make sense?

B Interactor tells B router detach C router.
B Interactor tells listener (A Interactor) to say B is done, decide what to do.

Two commands made by B Interactor, right? First informing router to detach and after informing its listener that it needs to be detached...

Did I understand you?

Yip, the thing to remember is the interactor is always responsible for making logic decisions wether that be telling the router to detach or telling its listener i.e its parent interactor that it needs to make a decision based on some thing.

Regarding interactor making two commands, its totally fine for this to be async i.e pass a competition closure to the router to dismiss a view controller and for the router to call the closure once it has finished the dismiss so the interactor can make its next call.

@sbarow AWESOME! I got it.

I guess it would be more safe If B Router detach's method could offer a completion callback, am I right? Since there is an animation dismissing C ViewController, it's better to execute second command (which is: letting A Interactor to be informed) after dismissing completion.

Am I right, @sbarow ?

Yeah, I updated my previous comment with that info :-)

@sbarow Thank you so much! Now I'm feeling well again. lol

Was this page helpful?
0 / 5 - 0 ratings