A deep link is not successful because its URL parsed. It is successful when the application reaches a valid navigable state.
Translate URLs at the app boundary:
enum AppRoute: Equatable {
case activeWorkout
case report(UUID)
}
The app reducer receives .routeOpened(route). For an active workout it selects the Fitness tab, loads or restores the current draft, and then presents the workout child state.
This ordering matters. Sending a navigation action to a child that does not exist loses the route or crashes an assumption.
Authentication and onboarding are gates. Store a pending route while the user completes the required flow, then consume it once. Avoid reparsing the raw URL in several feature reducers.
Deep links from notifications, widgets, Live Activities, and universal links should converge on the same typed route. Their transport metadata differs; destination behavior does not.
Test malformed URLs, missing identifiers, unauthenticated entry, cold launch, an already-running destination, and missing underlying data. Navigation is state, so deep-link handling belongs in the same deterministic state model as every other transition.