Chapter 24. subject never completed

I was going to extend SceneCoordinator to add more transitions types like fade and so forth. I was quite successful doing it except of the moment where subject variable never emits onCompleted. I need it to reset navigation controller delegate to nil once the transition is done.

Once I do push, pop and again I got this log for the debug code snippet:

// one-off subscription to be notified when push complete
    _ = navigationController.rx.delegate
      .sentMessage(selector)
      .map { _ in }
      .debug()
      .bind(to: subject)
2018-11-10 16:33:05.757: SceneCoordinator.swift:150 (push(subject:controller:)) -> subscribed
2018-11-10 16:33:06.289: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:07.053: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:12.358: SceneCoordinator.swift:150 (push(subject:controller:)) -> subscribed
2018-11-10 16:33:12.870: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:12.870: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:13.474: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:13.475: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:18.552: SceneCoordinator.swift:150 (push(subject:controller:)) -> subscribed
2018-11-10 16:33:19.064: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:19.064: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:19.065: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:19.669: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:19.669: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())
2018-11-10 16:33:19.669: SceneCoordinator.swift:150 (push(subject:controller:)) -> Event next(())

Any help would be appreciated

@fpillet Can you please help with this when you get a chance? Thank you - much appreciated! :]

Hi @mike55,

You’re absolutely right. This is a bug in my sample implementation on ScreenCoordinator and I’ll fix it for the next iteration of the book, to come soon. In the meantime, you can use a simple fix:

// one-off subscription to be notified when push complete
   _ = navigationController.rx.delegate
     .sentMessage(selector)
     .take(1)
     .map { _ in }
     .debug()
     .bind(to: subject)

Note the addition of the take(1). The actual real fix could be more complex, depending on the scenarios you want to handle: if the push is interrupted midway, the completion callback would never be invoked, therefore this particular observable wouldn’t complete. In real life this would not happen frenquently, if at all – I foresee a couple cases, mainly where your code pushes twice in a row.

Also, you may want to filter out invocations where the pushed controller is not the one you pushed, and in this case either ignore or complete the sequence.

Hope this helps,
Florent

1 Like

@mike55 I revisited this issue while working on the book update and couldn’t reproduce the issue with the code. There is a take(1) on the subject returned by both transition(to:type:) and pop() which you may have forgotten

This topic was automatically closed after 166 days. New replies are no longer allowed.