route-composer: Route Composer does not find a ViewController inside a tab bar when it is being pushed
I really like your framework. It works great. However I found a small bug.
I have the following setup:
/// Selector scene
UINavigationController(Nav1):
AccountSelectorViewController
Pushes: ->
// Home Scene
UITabBar:
UINavigationController:
GreenViewController
UINavigationController:
RedViewController
Each ViewController
has NavigationContext
object that is Equatable
. This context is set on the TabBar
too.
When tabbar is pushed, first NavigationController
(Nav1) is being hidden.
When tabbar is popped, first NavigationController
(Nav1) is shown again
Here is routes configuration:
struct Path {
static var accountSelector: DestinationStep<AccountSelectorViewController, NavigationContext?> {
return StepAssembly(
finder: ClassFinder<AccountSelectorViewController, NavigationContext?>(),
factory: ClassFactory<AccountSelectorViewController, NavigationContext?>())
.using(UINavigationController.push())
.from(NavigationControllerStep())
.using(GeneralAction.replaceRoot())
.from(GeneralStep.current())
.assemble()
}
static var accountHome: DestinationStep <TabbarViewController, NavigationContext?> {
return StepAssembly(
finder: ClassWithContextFinder<TabbarViewController, NavigationContext?>(),
factory: TabBarFactory())
.using(UINavigationController.push())
.from(accountSelector.expectingContainer())
.assemble()
}
static var green: DestinationStep <GreenViewController, NavigationContext?> {
return StepAssembly(
finder: ClassWithContextFinder<GreenViewController, NavigationContext?>(),
factory: NilFactory())
.from(Path.accountHome)
.assemble()
}
static var red: DestinationStep <RedViewController, NavigationContext?> {
return StepAssembly(
finder: ClassWithContextFinder<RedViewController, NavigationContext?>(),
factory: NilFactory())
.from(Path.accountHome)
.assemble()
}
}
The bug happens when RedViewController
is selected and app tries to deeplink to RedViewController
but with a different context.
Here is full console output when this happens:
[Router] Started to search for the view controller to start the navigation process from.
[Router] BaseStep<ClassWithContextFinder<RedViewController, Optional<NavigationContext>>(iterator: RouteComposer.DefaultStackIterator(options: current, contained, presented, presenting, startingPoint: RouteComposer.DefaultStackIterator.StartingPoint.topmost, windowProvider: RouteComposer.KeyWindowProvider(), containerAdapterLocator: RouteComposer.DefaultContainerAdapterLocator())) : FinderFactory<ClassWithContextFinder<RedViewController, Optional<NavigationContext>>>(configuration: nil, finder: RouteComposer.ClassWithContextFinder<RouteComposerBug.RedViewController, Swift.Optional<RouteComposerBug.NavigationContext>>(iterator: RouteComposer.DefaultStackIterator(options: current, contained, presented, presenting, startingPoint: RouteComposer.DefaultStackIterator.StartingPoint.topmost, windowProvider: RouteComposer.KeyWindowProvider(), containerAdapterLocator: RouteComposer.DefaultContainerAdapterLocator()))))> hasn't found a corresponding view controller in the stack, so it will be built using FinderFactory<ClassWithContextFinder<RedViewController, Optional<NavigationContext>>>(configuration: nil, finder: RouteComposer.ClassWithContextFinder<RouteComposerBug.RedViewController, Swift.Optional<RouteComposerBug.NavigationContext>>(iterator: RouteComposer.DefaultStackIterator(options: current, contained, presented, presenting, startingPoint: RouteComposer.DefaultStackIterator.StartingPoint.topmost, windowProvider: RouteComposer.KeyWindowProvider(), containerAdapterLocator: RouteComposer.DefaultContainerAdapterLocator()))).
[Router] BaseStep<ClassWithContextFinder<TabbarViewController, Optional<NavigationContext>>(iterator: RouteComposer.DefaultStackIterator(options: current, contained, presented, presenting, startingPoint: RouteComposer.DefaultStackIterator.StartingPoint.topmost, windowProvider: RouteComposer.KeyWindowProvider(), containerAdapterLocator: RouteComposer.DefaultContainerAdapterLocator())) : TabBarFactory())> hasn't found a corresponding view controller in the stack, so it will be built using TabBarFactory().
[Router] BaseStep<ClassFinder<AccountSelectorViewController, Optional<NavigationContext>>(iterator: RouteComposer.DefaultStackIterator(options: current, contained, presented, presenting, startingPoint: RouteComposer.DefaultStackIterator.StartingPoint.topmost, windowProvider: RouteComposer.KeyWindowProvider(), containerAdapterLocator: RouteComposer.DefaultContainerAdapterLocator())) : ClassFactory<AccountSelectorViewController, Optional<NavigationContext>>(nibName: nil, bundle: nil, configuration: nil))> found <RouteComposerBug.AccountSelectorViewController: 0x7f94808049d0> to start the navigation process from.
[Router] Started to build the view controllers stack.
[Router] TabBarFactory() built a <RouteComposerBug.TabbarViewController: 0x7f9482847a00>.
[Router] PushAction<UINavigationController>() has applied to <RouteComposerBug.AccountSelectorViewController: 0x7f94808049d0> with <RouteComposerBug.TabbarViewController: 0x7f9482847a00>.
[Router] Composition Failed Error: ClassWithContextFinder<RedViewController, Optional<NavigationContext>>(iterator: RouteComposer.DefaultStackIterator(options: current, contained, presented, presenting, startingPoint: RouteComposer.DefaultStackIterator.StartingPoint.topmost, windowProvider: RouteComposer.KeyWindowProvider(), containerAdapterLocator: RouteComposer.DefaultContainerAdapterLocator())) hasn't found its view controller in the stack.
[Router] Unsuccessfully finished the navigation process.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 22 (15 by maintainers)
Commits related to this issue
- Made NavigationControllerAdapter transactional Fixed the [Issue 33](https://github.com/ekazaev/route-composer/issues/33) — committed to ekazaev/route-composer by ekazaev 5 years ago
- Made NavigationControllerAdapter transactional Fixed the [Issue 33](https://github.com/ekazaev/route-composer/issues/33) — committed to ekazaev/route-composer by ekazaev 5 years ago
@ekazaev thanks! You are doing a great work
@0rtm New 2.1.4 version of RouteComposer is released and the issue you are facing is fixed there. It is also covered by the UI test so it wont appear in future.
Thank you for help.
If you’ll have any other issues or questions, please do not hesitate to open another issue.
@0rtm https://www.dropbox.com/s/vwpl3so5kqykhit/BugFix.mov?dl=0 the behaviour after the fix
@0rtm I see the issue. It is not exactly the RouteComposer issue, but there is a way to avoid such UIKit behaviour for sure. So basically Router asks UIKit to run next commands: navigationController.popToViewController(accountViewController, animated: true) and then after navigationController.pushViewController(redViewController, animated: true) And this is what brings a confusion as UINavigationController is not always works fine with the sequence of calls. But i will be able to fix it and will come with the fix shortly.
I was waiting when this transaction issue will appear but could not come with the scenario. So it is an important thing to fix