So, we have now had 8 entire episodes on navigation in SwiftUI: 2 on just tab views and alerts, 3 on sheets and popovers, and 3 on navigation links. We didn’t expect it to take this long to cover these basic forms of navigation in SwiftUI, but here we are.
Along the way we dove deep into the concepts of driving navigation from state, most importantly optional and enum state, which forced us to construct all new tools for abstracting over the shape of enums, such as case paths. We’ve seen that if you treat navigation primarily as a domain modeling problem, and if you have the tools necessary for modeling your domain, there are a ton of benefits to reap. We instantly unlock the ability to deep link into any part of our application, and it’s as simple as building a nested piece of state that describes exactly where you want to navigate to, hand it off to SwiftUI, and let it do the rest.
And, for free, we also get to test more of our application by asserting on how independent pieces of the application interact with each other.
While exploring these topics we’ve also seen that we had to give up some of SwiftUI’s tools in order to embrace our goals of deep linking and testability. For example, although using local @State
in views can be really handy, the moment you do you lose the ability to influence that state from the outside, which means it’s not possible to deep link into those states or test how those states influence your application. And although we didn’t discuss it in this series of episodes, the same applies to @StateObject
s too.
Another example of a SwiftUI tool we had to give up was using SwiftUI’s “fire-and-forget” navigation patterns, such as the initializers on TabView
and NavigationLink
that do not take bindings. Those tools allow us to get things on the screen very quickly, but sadly are not helpful if we need to deep link or write tests.
But now that we are done with the core series on navigation, we’d like to add one more thing. We’ve paid a lot of lip service to deep linking, and we’ve showed how it’s theoretically possible by constructing a large piece of state, handing it to the view, and then letting SwiftUI do its thing, but we haven’t shown how one could add actual, real world deep linking to the application. That is, how does one actually intercept a URL in order to parse it, understand what destination in your application it represents, and then actually navigate to that place.