How are we expected to support programmatic navigation and deep linking in SwiftUI?
In traditional UIKit applications, supporting deep linking usually goes as follows:
- Parse deep link URL
- Determine target UIViewController
- Instantiate target UIViewController
- Push target UIViewController onto root UINaviationController
This functionality relies on the push/pop instance methods present on UINavigationController.
In the current iteration of SwiftUI we have access to NavigationView and NavigationLink. A NavigationView must be present in the containing view for NavigationLinks to function. NavigationLinks are effectively buttons that must be given a body view and a destination view.
If our application supports deep links to 10 separate screens, right now we would have to use NaviationLinks init(_:destination:isActive:) initializer to create 10 separate NavigationLinks. These NaviationLinks would all be configured with an EmptyView, dynamic destination determined by a model and unique isActive Binding Bool. Then when we are ready to deep link, we would need to determine which screen we are navigating to, set some sort of state in the model that sets the correct destination View and flips the correct Binding Bool to trigger the NavigationLink.
This approach is highly coupled and doesn’t scale well in larger applications.
Another example where this approach causes complexity is supporting AB testing. We often have a single button that can go to two or more unique screens depending on which test the user is in.
I would expect to see a similar mechanism to that of UINavigationController that allows us to push a SwiftUI View onto the current NavigationView from a model.
SwiftUI is a very different approach to UI development / management and I’m sure we are all struggling to transition from a UIKit mindset. I’d love to see some guidance from the SwiftUI team as to how to cleanly build an application that allows navigation to any View from any View without coupling every View together.