Tutorials › Launch Lab Notes › Chapter 16

Three Levels, One Path

LabChapter 16 of the Launch Lab Notes22 minAugust 19, 2026Intermediate

Can you open Harbor → v1.4.0 → build 418 without three taps?

With a value-typed path you can: one write, three levels. With tap-only NavigationLinks and no path binding, you cannot — and a relaunch will not remember where you were either. This bench puts both next to each other and prints the depth on the cards.

Filmstrip: PATH tape fills Harbor › v1.4.0 › build 418 while LINKS stays at 0, then pops back to [].

Root — both at zero

PHASE ROOT: PATH 0 [], LINKS 0 stuck at root. PATH TAPE []. MODE ROOT PATH 0 · LINKS 0.
SideDepthDetail
PATH0[]
LINKS0stuck at root

PATH is a NavigationStack(path:) over [ShipRoute]. LINKS is a NavigationStack with nested links and no path binding — the control.

Deep — one append, three levels

path = [.app, .version, .build]  // Harbor › v1.4.0 › build 418
// Links has no path to write — depth stays 0
PHASE DEEP: PATH 3 Harbor › v1.4.0 › build 418. LINKS 0 stuck at root. MODE DEEP PATH 3 · LINKS 0.
SideDepthDetail
PATH3Harbor › v1.4.0 › build 418
LINKS0stuck at root

Same moment, same screen. The mint card moved; the rose card did not.

Value in, destination out

NavigationLink(_:value:) does not embed a destination view. navigationDestination(for:destination:) teaches the stack what to push for each type. Programmatic path = … and a user tap share that mapping — that is why one append can equal three taps.

Pop — clear the array

PHASE POP: PATH 0 [], LINKS 0. PATH TAPE []. Status removeAll. MODE POP PATH 0 · LINKS 0.
path = []  // removeAll — back to root

Observed: PATH 0, tape [], phase POP, status removeAll. LINKS was already at root.

Save, then relaunch

PHASE SAVED: PATH 3 Harbor › v1.4.0 › build 418. LINKS 0. Status defaults ← path. MODE SEED.

Seed mode deep-links, then writes the encoded [ShipRoute] to UserDefaults. Observed: PHASE SAVED, PATH 3, LINKS 0, status defaults ← path.

PHASE RESTORED after reload: PATH 3 Harbor › v1.4.0 › build 418. LINKS 0 stuck at root. Status path ← defaults. MODE RELOAD.

A fresh process with -mode reload reads the array back into path. Observed: PHASE RESTORED, PATH 3, tape Harbor › v1.4.0 › build 418, LINKS 0, status path ← defaults.

Links have nothing to restore

Without a path binding there is no array to encode. After kill, the control wakes at root every time — that is the point of the rose card on the relaunch still.

Mini-exercise

Change deepPath to only [.app, .version]. Re-run seed → reload. Confirm PATH settles at 2 and the tape stops at v1.4.0.

Challenges

  1. Swap [ShipRoute] for a NavigationPath and deep-link a second type (e.g. a review id) beside ShipRoute.
  2. Add a "Pop one" button that does path.removeLast() and photograph depth 3 → 2 → 1.
  3. Drive the same path from a simulated URL (harbor/v1.4.0/418) parsed into [ShipRoute].
  4. Put the bench back inside an outer NavigationStack and photograph how the destination steals the window — then fix it the way Launch Lab does for -bench launches.
  5. XCUITest: after -mode reload, assert static text contains RESTORED and PATH 3.

Key Points

Next up: gestures — drag, long-press, and simultaneous/sequenced composition, with a live readout of which gesture won — including scroll-vs-drag as the control.

SwiftUI
SwiftUI tutorials for building native app screens, layouts, navigation, and state-driven interfaces.
Swift
Swift fundamentals for app developers who want to understand the language behind real iOS and macOS apps.
Ship iOS
Shipping workflows for iOS apps.
📚 Go deeper with LIPAI WANG’s hands-on Udemy bootcampsBrowse all courses →
← Ch 15: Ten Thousand RowsCh 17: Who Won the Drag→
SwiftUIUltimate SwiftUI SeriesSwiftUI tutorials for building native app screens, layouts, navigation, and state-driven interfaces.SwiftUltimate Swift SeriesSwift fundamentals for app developers who want to understand the language behind real iOS and macOS apps.Ship iOSShip iOS Apps SeriesShipping workflows for iOS apps: signing, TestFlight, App Store Connect, CI, and release hygiene.

Ship your apps faster

When you're ready to publish your Swift app to the App Store, Simple App Shipper handles metadata, screenshots, TestFlight, and submissions — all in one place.

Try Simple App Shipper
5 free articles remainingSubscribe for unlimited access