Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Iris

Swift Versions Platforms License: MIT

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.

What it does

  • Turns an incoming URL into an app-defined Intent via your URLParsing codec.
  • A NavigationFlow translates each intent into a list of Step values:
    • Step.nav(.push/.present/.popToRoot/.dismissSheet): structural navigation, dispatched by Iris.
    • Step.effect(_): consumer-defined side-effects, handled in your coordinator's apply(_:_:).
  • PlumbedCoordinatorBase<Flow> ships the navigators, facade, executors, and stack/sheet HandoffRegistrys out of the box; subclasses just declare their Flow and override apply(_:_:) 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.

Case studies

Iris is the package behind Deep linking as an input language, a series of measurement-led writeups on the problems it exists to solve: where URL handling should live, resolving the same URL to the right meaning from anywhere in the app, keeping taps and URLs on one resolver, and what happens when links arrive faster than the UI can mount them. Iris internals: how it works walks the pipeline this package implements.

Requirements

  • iOS 17+ or macOS 14+
  • Swift 6.0 / Xcode 16+

Installation

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.

Quick sketch

// 1. Define your flow.
enum MyFlow: NavigationFlow {
    typealias Intent = MyIntent
    typealias Route = TopLevel.StackRoute
    typealias SheetRoute = TopLevel.SheetRoute

    static func 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 @Observable
final class AppCoordinator: 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
    // …
}

Scaffolding skills

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.

Stability

Iris follows Semantic Versioning. The public API is stable and will not break within a major version: no source-breaking change ships in a minor or patch release. Anything that would break a consumer waits for the next major version and is documented in that release's notes.

The promise covers the public surface of the Iris product. Internal symbols and the templates under Sources/Iris/Excluded/ are outside it and may change at any time.

Contributing

Issues are welcome: bug reports, questions about wiring a host app, and proposals for changes all belong in the issue tracker.

Please open an issue before opening a pull request. Agreeing the shape of a change first avoids work that cannot be merged, and keeps the public API promise above intact.

Licence

Iris is available under the MIT License. See LICENSE for the full text.

About

Routes incoming URLs into typed SwiftUI navigation, without hand-rolling plumbing for each new screen.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages