Hey @darrarski, thanks for the detailed report!
It may seem like that
assertFailure is a little strict, but it is indeed what we want, and without it you would be silently hiding a bug rather than loudly complaining of a programmer error
The bug is that when the dismiss button is tapped you immediately
nil out the detail state, which causes the detail view to go away, which then causes the
onDisappear to be invoked, which finally sends the
.stopTimer action. However, that action will never be delivered to your reducer because the state has already been
nil'd out, and so there is no longer anything to reducer on. That essentially means that without the
assertionFailure the timer would be quietly running forever, sending actions to the store, and you wouldn't know unless you happen to have
.debug() on the reducer to see everything that was coming in.
So, the assertion really is trying to catch a potential bug, but that's not to say that this is the best way to handle the situation. The
optional higher-order reducer is good for optionally showing/hiding views based on state, but if you need to hook into the lifecycle methods from within that view, in particular
onDisappear, then you are always going to run into that assertion.
So this has motivated us to find a version of
optional that is lifecycle aware. We have sketched a version of the higher-order reducer here, along with a case study:
We want to spend a little more time with it and see if there is any more polish we can apply, but the results are promising so far. Want to give it a spin and see if it helps you?