Skip to content

Universal Links are routable but untested, and one URLPathRouter serves only one scheme #13

Description

@nashysolutions-bot

Surfaced while gating async-digital-site#546, which proposes a public repo description naming Universal Links as a supported input. The capability is real but thinner than that claim implies, and nothing here is tested.

Measured on main @ depth-1 clone, 2026-08-30

  • URLPathRouter carries exactly one scheme: public let scheme: String, set once in init(scheme:routes:) (Sources/Iris/URLRoute.swift:142-148).
  • parse(_:) hard-rejects anything else: guard url.scheme == scheme else { return nil } (URLRoute.swift:153).
  • URLPattern takes its host from the first path segment of the pattern string: self.host = segments.first ?? "" (URLRoute.swift:73).
  • grep -rn https Sources/ returns zero hits.
  • The only router test constructs scheme: "demo" (Tests/IrisTests/URLPathRouterTests.swift:18).

What that means in practice

Universal Links are routable — URLPathRouter(scheme: "https", routes: [URLPattern("myapp.com/profile/:id")]) works. Three consequences follow that a reader of a one-line description would not expect:

  1. One router serves one scheme. An app accepting both myapp://profile/1 and https://myapp.com/profile/1 needs two URLPathRouter instances and its own dispatch between them. Nothing in the package composes them.
  2. Every Universal Link pattern must repeat the domain as its first segment, because pattern host is segment zero. A custom-scheme pattern reads profile/:id; the Universal Link equivalent reads myapp.com/profile/:id, and the two cannot share a route table.
  3. It is untested and undocumented for https. AGENTS.md names .onOpenURL as "the standard SwiftUI universal-link / custom-scheme entry point", which is true of the modifier but says nothing about the router behind it.

What breaks if this is never fixed

An adopter who picks the package up because its description promises Universal Links writes one router, gets nil from every https URL, and has to read the source to find the scheme guard. That is the friction the case-study series exists to argue we design out.

Options, not a prescription

  • Document the two-router pattern in AGENTS.md and add an https test. Cheapest, makes the existing behaviour honest.
  • Let URLPathRouter hold a set of accepted schemes, keeping host matching as-is.
  • Separate scheme from host in URLPattern so one table serves both.

Pick before the public description claims Universal Links as a headline capability.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions