SwiftUI Navigation: The Point

Episode #168 • Nov 15, 2021 • Subscriber-Only

We’ve claimed that the way we handle navigation in SwiftUI unlocks the ability to deep link to any screen in your application, so let’s put that claim to the test. We will add real-world deep linking to our application, from scratch, using the parsing library we open sourced many months ago.

The Point
Introduction
00:05
Deep linking in iOS
02:26
swift-parsing
07:45
Breaking down parsing problems
12:00
Parsing query parameters
33:40
Parsing dynamic paths
45:48
Conclusion
56:03

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Introduction

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 @StateObjects 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.

This episode is for subscribers only.

Subscribe to Point-Free

Access this episode, plus all past and future episodes when you become a subscriber.

See plans and pricing

Already a subscriber? Log in

Exercises

  1. Add a deep linker route for duplicating an item.

  2. Refactor the inventoryDeepLinker to group the “add” and “color picker” routes so that the add path component is parsed at most a single time.

  3. Add the ability to deep-link into the edit and duplicate screens and further pre-fill fields and link further into the color picker screens. Try to re-use the ItemRoute and item parser to handle these routes.

    Note that parsing Items as is will prevent you from deep-linking to edit or duplicate and overriding a single field. Instead, introduce a new data structure that allows you to selectively override an Item’s fields.

References

SwiftUI Navigation

Brandon Williams & Stephen Celis • Tuesday Nov 16, 2021

After 9 episodes exploring SwiftUI navigation from the ground up, we open sourced a library with all new tools for making SwiftUI navigation simpler, more ergonomic and more precise.

Swift Parsing

Brandon Williams & Stephen Celis • Tuesday Dec 21, 2021

A library for turning nebulous data into well-structured data, with a focus on composition, performance, generality, and invertibility.

Collection: Derived Behavior

Brandon Williams & Stephen Celis • Monday May 17, 2021

The ability to break down applications into small domains that are understandable in isolation is a universal problem, and yet there is no default story for doing so in SwiftUI. We explore the problem space and solutions, in both vanilla SwiftUI and the Composable Architecture.

Downloads