A small Swift package for routing incoming URLs (custom-scheme deep links and Universal Links alike) into typed SwiftUI navigation, without hand-rolling navigation plumbing for each new screen.
- Turns an incoming URL into an app-defined
Intentvia yourURLParsingcodec. - A
NavigationFlowtranslates each intent into a list ofStepvalues:Step.nav(.push/.present/.popToRoot/.dismissSheet): structural navigation, dispatched by Iris.Step.effect(_): consumer-defined side-effects, handled in your coordinator'sapply(_:_:).
PlumbedCoordinatorBase<Flow>ships the navigators, facade, executors, and stack/sheetHandoffRegistrys out of the box; subclasses just declare theirFlowand overrideapply(_:_:)when there are effects to handle.- Latest-wins cancellation so a newer link supersedes one in flight.
- Hand-off batons let destination views consume the link payload once
the screen mounts; the registry auto-cleans on
.delivered.
- iOS 17+ or macOS 14+
- Swift 6.0 / Xcode 16+
Add to your Package.swift:
dependencies:[.package(url:"https://github.com/async-digital-ltd/iris.git", from:"1.0.0")]…and depend on the Iris product from any target that needs it.
// 1. Define your flow.
enumMyFlow:NavigationFlow{typealiasIntent=MyIntenttypealiasRoute=TopLevel.StackRoutetypealiasSheetRoute=TopLevel.SheetRoutestaticfunc operations(intent:Intent)->[Step<Route,SheetRoute,Never>]{switch intent {case.showInbox:return[.nav(.popToRoot),.nav(.push(.inbox))]case.showProfile(let id):return[.nav(.popToRoot),.nav(.push(.profile(id: id)))]case.unknown:return[]}}}
// 2. Subclass PlumbedCoordinatorBase.
@MainActor@ObservablefinalclassAppCoordinator:PlumbedCoordinatorBase<MyFlow>{}
// 3. Drive NavigationStack from the inherited facade.
NavigationStack(path: coordinator.nav.pathBinding){RootView().navigationDestination(for:TopLevel.StackRoute.self){ route in
// …
}}.sheet(item: coordinator.nav.sheetBinding){ route in
// …
}Sources/Iris/Excluded/Skills/ holds five SKILL.md templates aimed
at coding agents (excluded from the SwiftPM target). They scaffold a new
consumer end to end:
iris-bootstrap: generates the Intent / routes / flow / codec / coordinator / app-entry wiring.iris-test-scaffold: generates Swift Testing suites for codec, flow, and handoff lifecycle.iris-audit: runs eight wiring-coverage checks against an existing consumer.iris-visualize: produces a Mermaid diagram of the URL → Intent → Step → Route → View pipeline.iris-url-catalog: produces a Markdown table of every supported URL.
See LICENSE.