All Posts
Post
A tangled web of push/pop calls and segues can slow teams down — but you can migrate to state‑driven navigation incrementally without a big rewrite. Here’s a practical approach I’ve seen work in teams moving UIViewController navigation toward SwiftUI’s NavigationStack.
Key ideas:
- Model routes as Hashable value types and keep a single source of truth (e.g., a Router ObservableObject owning a NavigationPath).
- Incrementally embed SwiftUI with UIHostingController or UIViewControllerRepresentable; expose a small adapter layer to translate Router state into existing UINavigationController actions.
- Gate higher‑risk flows (auth, payments) behind feature flags and roll them out in stages.
- Validate navigation behavior with UI tests (XCTest) and use profiling/logging tools (Instruments, breadcrumbs) to diagnose issues in the wild.
Tradeoff/decision guidance:
- Prefer a full NavigationStack for flows that map naturally to value‑typed routes.
- Defer or wrap UI‑only container behaviors (first‑responder chains, complex child view controller coordination) until you can safely rework them; keep the adapter deterministic to limit scope.
Callouts: NavigationStack, NavigationPath, UIHostingController, Instruments, XCTest.
Have you migrated navigation incrementally? What adapter patterns helped (or didn’t) for your team?