QuickBirdEng / XCoordinator

🎌 Powerful navigation library for iOS based on the coordinator pattern
MIT License
2.26k stars 177 forks source link

DeepLink chain not executed as expected #246

Open anhntsi opened 1 year ago

anhntsi commented 1 year ago

Thank you for the wonderful Coordinator library. I am having an issue related to deeplink chain.

The issue is that the deeplink only runs to the MarketsRoute route, while the StockMarketRoute does not execute.

return .multiple(
                .dismissToRoot(),
                .popToRoot(),
                deepLink(AppRoute.home, HomeRoute.markets, MarketsRoute.stocks, StockMarketRoute.counterDetail)
)

I will explain a little bit about the Coordinator in the demo project. HomeTabCoordinator is a tab bar controller that contains 3 tabs: NewsCoordinator, MarketsCoordinator, UsersCoordinator. MarketsCoordinator is a page view controller that has 2 pages: StockMarketCoordinator and UTMarketCoordinator.

Can you help me identify where the problem is?

matthewshehan commented 3 months ago

This really depends on how you're using XCoodinator. I'd have to see how you're using XCoordinator to give you better advice, but my general solution to this is to wrap your ViewControllers in a wrapper object that conforms to Presentable then override this function in that that wrapper where the strongRouter is the Coordinator that presents that ViewController

public func router<R: Route>(for route: R) -> StrongRouter<R>?

basically when you transiton a ViewController despite UIViewController conforming to presentable, it itself is not a Router the coordinator that displays that ViewController is the Router so you have to point to that router in that function in order for deep linking to execute as expected.

You could do something like this

class  MyModule: Presentable {
  let viewController: UIViewController! 
  unowned var presentingCoordinator: MyCoordinator 

  init(viewController: MyViewController, coordinator: MyCoordinator ) {
    self.viewController = viewController 
    self.coordinator = coordinator 
  }
  public func router<R: Route>(for route: R) -> StrongRouter<R>? {
      coordinator.strongRouter 
  }
}

.... 

class MyCoordinator {
... 

  override func prepareForTransition(on route: MyRoute) -> TransitionType {
    switch route {
      case .initialRoute: 
         let module = MyModule(viewController: MyViewController(), coordinator: self)
         return .present(module) 
     .... 
    }
  }
}

now since you presented the module that knows about the router Deep linking should start working properly. This problem actually comes up again in other situations. This is my general workaround.