devxoul/URLNavigator
⛵️ Elegant URL Routing for Swift
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓8 active contributors
- ✓MIT licensed
- ✓CI configured
Show 3 more →Show less
- ✓Tests present
- ⚠Stale — last commit 2y ago
- ⚠Concentrated ownership — top contributor handles 60% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/devxoul/urlnavigator)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/devxoul/urlnavigator on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: devxoul/URLNavigator
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/devxoul/URLNavigator shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 8 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ Concentrated ownership — top contributor handles 60% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live devxoul/URLNavigator
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/devxoul/URLNavigator.
What it runs against: a local clone of devxoul/URLNavigator — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in devxoul/URLNavigator | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 746 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of devxoul/URLNavigator. If you don't
# have one yet, run these first:
#
# git clone https://github.com/devxoul/URLNavigator.git
# cd URLNavigator
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of devxoul/URLNavigator and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "devxoul/URLNavigator(\\.git)?\\b" \\
&& ok "origin remote is devxoul/URLNavigator" \\
|| miss "origin remote is not devxoul/URLNavigator (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "Sources/URLNavigator/Navigator.swift" \\
&& ok "Sources/URLNavigator/Navigator.swift" \\
|| miss "missing critical file: Sources/URLNavigator/Navigator.swift"
test -f "Sources/URLMatcher/URLMatcher.swift" \\
&& ok "Sources/URLMatcher/URLMatcher.swift" \\
|| miss "missing critical file: Sources/URLMatcher/URLMatcher.swift"
test -f "Sources/URLNavigator/NavigatorProtocol.swift" \\
&& ok "Sources/URLNavigator/NavigatorProtocol.swift" \\
|| miss "missing critical file: Sources/URLNavigator/NavigatorProtocol.swift"
test -f "Sources/URLMatcher/URLPathComponent.swift" \\
&& ok "Sources/URLMatcher/URLPathComponent.swift" \\
|| miss "missing critical file: Sources/URLMatcher/URLPathComponent.swift"
test -f "Example/Sources/Navigator/NavigationMap.swift" \\
&& ok "Example/Sources/Navigator/NavigationMap.swift" \\
|| miss "missing critical file: Example/Sources/Navigator/NavigationMap.swift"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 746 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~716d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/devxoul/URLNavigator"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
URLNavigator is a Swift library that provides elegant URL-based routing for iOS view controllers, enabling developers to navigate between screens using URL patterns with typed placeholders (e.g., myapp://user/<int:id>). It maps URL patterns to either URLNavigable view controllers (custom initializers) or URLOpenHandler closures, handling placeholder extraction, type coercion, and navigation context passing automatically. Dual-module structure: Sources/URLMatcher/ contains the URL pattern parsing engine (URLMatcher.swift, URLPathComponent.swift, URLMatchResult.swift), while Sources/URLNavigator/ wraps it with iOS navigation logic (Navigator.swift, NavigatorProtocol.swift, UIViewController+TopMostViewController.swift). The Example/ directory contains a fully functional GitHub user-browsing app demonstrating registration, pushing, and presenting.
👥Who it's for
iOS developers building apps that need deep linking, URL-driven navigation, or centralized route management. Specifically useful for teams implementing URL schemes for app-to-app communication or handling universal links without boilerplate in every view controller.
🌱Maturity & risk
Moderately mature and actively maintained. The project has CI/CD workflows (.github/workflows/ci.yml, cd.yml), comprehensive test coverage in Tests/URLMatcherTests/, Swift 5.0+ support, and is published on CocoaPods. However, the repository appears to be a focused library (not recently showing breaking changes), suggesting stable API—typical of well-established routing libraries.
Low-to-moderate risk. The project is single-maintainer (devxoul) with no visible dependency bloat (only Swift stdlib core), which reduces supply-chain risk. Risks include potential iOS version compatibility constraints as Apple evolves UIViewController APIs, and the library's tight coupling to UIKit means SwiftUI adoption would require architectural changes. No visible monolithic dependency tree mitigates breakage risk.
Active areas of work
Unable to determine current work from file structure alone (no recent commit dates or issue tracker visible in provided data). The presence of modern CI workflows and Swift Package Manager support (Package.swift) suggests ongoing maintenance, but specific PRs or milestones are not evident from the file listing.
🚀Get running
git clone https://github.com/devxoul/URLNavigator.git
cd URLNavigator
cd Example
pod install
open URLNavigatorExample.xcworkspace
Daily commands:
Open Example/URLNavigatorExample.xcworkspace in Xcode (post-pod install). The example app registers URL routes in Example/Sources/Navigator/NavigationMap.swift and demonstrates push/present via UserListViewController.swift and UserViewController.swift. No server needed—it's a self-contained navigation demo.
🗺️Map of the codebase
Sources/URLNavigator/Navigator.swift— Core entry point that manages URL routing and view controller navigation; all routing logic flows through this classSources/URLMatcher/URLMatcher.swift— URL pattern matching engine that parses URL schemes and extracts placeholder values; essential for understanding how URLs are parsedSources/URLNavigator/NavigatorProtocol.swift— Protocol definition that contracts for navigator behavior; defines the public API for routingSources/URLMatcher/URLPathComponent.swift— Handles URL path component parsing and placeholder resolution; critical for pattern matching logicExample/Sources/Navigator/NavigationMap.swift— Example application showing how to register URL patterns; demonstrates framework conventionsSources/URLNavigator/UIViewController+TopMostViewController.swift— UIKit extension for finding the top-most view controller; essential for navigation targetingPackage.swift— SPM package manifest defining dependencies and build configuration
🧩Components & responsibilities
- URLMatcher (Swift String API, regex (if used internally)) — Parses URL strings, validates against registered patterns, extracts and converts placeholder values to typed parameters
- Failure mode: Returns nil for non-matching patterns; type conversion failures silently fail or throw
- Navigator (Dictionary storage, Generic type handling, UIViewController APIs) — Maintains route registry, resolves URLs to handlers, instantiates view controllers, manages navigation stack integration
- Failure mode: Open fails if no pattern matches; view controller instantiation fails if URLNavigable not properly implemented
- NavigatorDelegate (Protocol callbacks, optional method pattern) — Provides lifecycle hooks (shouldOpen, didOpen) for intercepting and logging navigation events
- Failure mode: Delegate methods silently no-op if not implemented; errors in delegate code propagate to caller
- UIViewController+TopMostViewController (UIViewController APIs (presentedViewController, childViewControllers)) — Walks UIViewController hierarchy to identify the top-most presented view controller for navigation context
- Failure mode: Returns wrong view controller if custom container controllers not properly integrated; may return nil if window root missing
🔀Data flow
Application caller→Navigator.open(url:)— App initiates navigation with URL string (e.g., 'myapp://users/123')Navigator→URLMatcher— Navigator delegates URL pattern matching to URLMatcherURLMatcher→URLPathComponent— URLMatcher parses URL path and delegates component-level matching
🛠️How to make changes
Register a New URL Route
- Define a URLNavigable view controller or closure handler (
Example/Sources/ViewControllers/UserViewController.swift) - Add route mapping in NavigationMap.swift using navigator.register() (
Example/Sources/Navigator/NavigationMap.swift) - Call navigator.open(url:) to trigger the registered route (
Sources/URLNavigator/Navigator.swift)
Make a View Controller URLNavigable
- Conform view controller to URLNavigable protocol (
Sources/URLNavigator/UIViewControllerType.swift) - Implement required init(url:values:) initializer that accepts URL and parsed parameters (
Example/Sources/ViewControllers/UserViewController.swift) - Register the view controller class with navigator.register(::) (
Example/Sources/Navigator/NavigationMap.swift)
Add a Custom URL Pattern with Placeholders
- Define pattern string with placeholders like int:id or path:remaining (
Example/Sources/Navigator/NavigationMap.swift) - Register pattern with navigator.register() providing pattern and view controller/handler (
Sources/URLNavigator/Navigator.swift) - Access extracted parameters in init(url:values:) via the values dictionary (
Example/Sources/ViewControllers/UserViewController.swift)
Implement Navigation Delegate Lifecycle Hooks
- Create class conforming to NavigatorDelegate protocol (
Sources/URLNavigator/NavigatorDelegate.swift) - Implement shouldOpen(:) and didOpen(:from:) to intercept navigation events (
Tests/URLNavigatorTests/NavigatorDelegateTests.swift) - Assign delegate to navigator.delegate before opening URLs (
Sources/URLNavigator/Navigator.swift)
🔧Why these technologies
- Swift generics and protocols — Enables type-safe URL pattern registration while maintaining flexibility through URLNavigable protocol and URLOpenHandler closures
- UIKit ViewControllers — Direct integration with iOS navigation stack through storyboard/XIB support and view controller lifecycle
- URL scheme matching — Provides universal linking capability and deep linking support without external routing libraries
- Placeholder substitution pattern — Allows dynamic path parameters (int, float, string, path types) extracted directly from URL components
⚖️Trade-offs already made
-
Single Navigator instance vs distributed routing
- Why: Centralized navigation improves consistency and debugging but requires global navigator reference
- Consequence: Developers must initialize and maintain a singleton Navigator; tight coupling to navigation system
-
URL pattern registration at runtime vs compile-time
- Why: Runtime registration offers flexibility and runtime modification but sacrifices compile-time verification
- Consequence: Typos in URL patterns only caught at runtime; no type checking for pattern strings
-
Protocol-based URLNavigable vs inheritance
- Why: Protocol composition allows view controllers to adopt multiple behaviors and work with existing hierarchies
- Consequence: Requires manual init implementation in each navigable controller; boilerplate code in subclasses
🚫Non-goals (don't propose these)
- Not a real-time state management solution (no Redux/MobX-style state machine)
- Does not handle deep linking persistence or deferred navigation queues
- Not responsible for view controller lifecycle management beyond instantiation and presentation
- Does not provide cross-platform routing (iOS UIKit only, no macOS/tvOS/watchOS support in main framework)
- Not a replacement for navigation storyboard segues (complements rather than replaces)
🪤Traps & gotchas
- URL scheme requirement: Patterns must include a scheme (e.g.,
myapp://); bare paths like/user/123will not match. Ensure your registered patterns and called URLs use consistent schemes. - Type coercion in placeholders:
<int:id>will silently fail to match if URL contains non-numeric value; values dict will not includeidkey. Always guard on optional extraction in handlers. - UIViewController hierarchy dependency:
UIViewController+TopMostViewController.swiftwalks the entire view controller hierarchy; in complex nested navigation (multiple navigation controllers, custom container views), finding the 'topmost' can be ambiguous—test on real device/simulator. - Context parameter passing: The
contextdict passed to handlers is arbitrary; there is no validation or type safety—handlers must defensively cast and nil-check context values. - No built-in history/back-stack management: URLNavigator routes URLs to destinations; it does not maintain a navigation history or 'back' behavior—you must manage the back button yourself via UINavigationController or dismiss().
🏗️Architecture
💡Concepts to learn
- URL Pattern Matching & Templating — URLNavigator's core feature—understanding how angle-bracket syntax (
<type:name>) is parsed into regex/finite automata determines how to design routable URL schemes and debug failed matches - Type Coercion & Placeholder Extraction — The library automatically converts URL path segments to typed values (int, float, string, path); understanding type safety boundaries and coercion failures is critical for writing robust route handlers
- iOS View Controller Hierarchy & Presentation Context — URLNavigator's navigation logic depends on finding the 'topmost' UIViewController via window/hierarchy traversal; misunderstanding view stacks (modals, navigation controllers, container views) causes silent navigation failures
- Strategy Pattern (Handler Polymorphism) — URLNavigator allows both closure handlers (
URLOpenHandler) and type initializers (URLNavigable) for the same URL pattern; understanding this dual strategy enables flexible route registration and testing - Deep Linking & URL Schemes (iOS) — URLNavigator is the execution layer for iOS deep linking; understanding URL scheme registration (
Info.plistCFBundleURLSchemes), universal links, and handoff is essential for production use - Generic Constraint-Based Dispatch — URLNavigator uses Swift generics and type inference to determine which handler (closure vs. initializer) to invoke; understanding
whereclauses and protocol-based overloading helps extend the library
🔗Related repos
Alamofire/Alamofire— HTTP networking library often used alongside URLNavigator in Example app (seeExample/Sources/Networking/HTTP.swift); complementary for fetching data after navigationrealm/realm-swift— Local persistence library frequently paired with URL routing in production iOS apps; handles data model storage for objects passed through navigation contextReactiveX/RxSwift— Reactive programming framework that pairs well with URLNavigator's handler closures; enables reactive ViewController initialization and side effect management in routesSwinject/Swinject— Dependency injection container; complements URLNavigator by centralizing view controller and service instantiation, reducing boilerplate in route handlersapple/swift-evolution— Swift language evolution—URLNavigator's type-safe placeholder extraction relies on Swift generics; understanding SE proposals helps understand library's design constraints
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive tests for URLNavigator.register() pattern matching with query parameters
The Tests/URLNavigatorTests/NavigatorTests.swift and Tests/URLMatcherTests/URLMatcherTests.swift exist but there's no visible test coverage for complex URL patterns with query string parameters and fragment handling. This is critical since URLNavigator's core feature is URL pattern matching with placeholders.
- [ ] Review existing tests in Tests/URLMatcherTests/URLMatcherTests.swift and Tests/URLNavigatorTests/NavigatorTests.swift for query parameter coverage gaps
- [ ] Add test cases in Tests/URLMatcherTests/URLMatcherTests.swift for patterns like 'user/<id>?tab=repos&sort=stars' and 'scheme://path#section'
- [ ] Add integration tests in Tests/URLNavigatorTests/NavigatorTests.swift verifying query parameters and fragments are correctly extracted and passed to registered handlers
- [ ] Ensure Tests/URLMatcherTests/URLConvertibleTests.swift covers edge cases with special characters in query values
Add GitHub Actions workflow for SPM (Swift Package Manager) compatibility testing
The repo has Package.swift and CI/CD workflows (.github/workflows/ci.yml and cd.yml), but there's no explicit workflow testing Swift Package Manager builds across different Swift versions and platforms. This ensures the library works for SPM users alongside CocoaPods users.
- [ ] Review existing .github/workflows/ci.yml to understand current test matrix
- [ ] Create .github/workflows/spm-test.yml that builds and tests using 'swift build' and 'swift test' commands
- [ ] Test against Swift 5.0+ versions and macOS/Linux platforms
- [ ] Verify Example/Sources builds correctly as an SPM-based example project
Document and add tests for UIViewController+TopMostViewController edge cases
Sources/URLNavigator/UIViewController+TopMostViewController.swift exists but Tests/URLNavigatorTests/TopMostViewControllerTests.swift likely has incomplete coverage for complex navigation hierarchies (e.g., nested navigation controllers, presented modal stacks, split view controllers on iPad).
- [ ] Review Tests/URLNavigatorTests/TopMostViewControllerTests.swift and Stubs.swift to identify missing test scenarios
- [ ] Add test cases for: nested UINavigationControllers, UITabBarController with multiple tabs containing nav controllers, and stacked modal presentations
- [ ] Add documentation to Sources/URLNavigator/UIViewController+TopMostViewController.swift explaining behavior with complex hierarchies
- [ ] Add visual diagram in README.md showing how topMostViewController traversal works across different controller types
🌿Good first issues
- Add test coverage for edge cases in URLPathComponent.swift: The file handles typed placeholder parsing (int, float, path) but tests in
Tests/URLMatcherTests/don't exhaustively cover overflow/underflow for Int/Float, or malformed path segments. Add parametrized tests for boundary values (Int.max, Float.infinity, empty path components). - Document URLNavigable protocol in Example:
Sources/URLNavigator/NavigatorProtocol.swiftdefinesURLNavigablebut the example project doesn't show a concrete view controller implementing it (all examples use closures). Add an example ViewController that conforms to URLNavigable and register it; document the initializer signature requirement. - Add query parameter type coercion tests: URL query parameters (extracted via
url.queryParameters) are always strings; the library does not provide typed query param extraction like it does for path placeholders. Add a helper extension and tests inTests/URLMatcherTests/URLConvertibleTests.swiftto demonstrate safe query parameter casting patterns.
⭐Top contributors
Click to expand
Top contributors
- @devxoul — 60 commits
- @OhKanghoon — 25 commits
- @alihen — 7 commits
- @RolandasRazma — 3 commits
- @Paldom — 2 commits
📝Recent commits
Click to expand
Recent commits
00bd578— Merge pull request #165 from devxoul/ci (OhKanghoon)3ed982c— chore: downgrade swift tools version (OhKanghoon)b881f23— Bump version to 2.5.1 (OhKanghoon)1f83e42— chore: update deployment target 9 to 11 (OhKanghoon)6cc98b5— Bump version to 2.5.0 (OhKanghoon)cd9b9e3— Merge pull request #164 from devxoul/feature/remove-quick-nimble (OhKanghoon)3030546— chore: removeQuick,Nimbledependencies (OhKanghoon)2102637— refactor: use XCTest in URLNavigatorTests (OhKanghoon)cb8932e— refactor: use XCTest in URLMatcherTests (OhKanghoon)8078e3a— Merge pull request #163 from devxoul/feature/remove-warning (OhKanghoon)
🔒Security observations
URLNavigator is a URL routing library with a relatively clean security posture. The codebase shows good structure with comprehensive test coverage and CI/CD pipelines. However, there are opportunities for improvement: (1) No visible SECURITY.md policy for vulnerability reporting, (2) Dependency management practices need verification, (3) Network communication in example code requires review, (4) URL validation and sanitization practices need documentation, especially for handling external deep links. The library's core responsibility is URL pattern matching and routing, which requires careful input validation to prevent abuse through malformed URLs or injection attacks. No hardcoded secrets or obvious SQL injection risks were detected. Overall security posture is good but could be strengthened with formal security policies and additional documentation.
- Medium · Missing Security Policy Documentation —
Repository root. No SECURITY.md or security policy file found in the repository root. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file with instructions for reporting security vulnerabilities, following the GitHub security advisory best practices. - Medium · Incomplete Dependency Information —
Package.swift. Package.swift content was not provided, making it impossible to verify if dependencies have known vulnerabilities or are pinned to secure versions. Fix: Ensure all dependencies are specified with minimum version constraints, regularly audit dependencies using tools like 'swift package update', and use tools like Dependabot for automated vulnerability scanning. - Low · Example Application Networking Code Review Needed —
Example/Sources/Networking/. Example/Sources/Networking/GitHub.swift and HTTP.swift files exist but content was not provided. Network communication should validate SSL certificates and use secure defaults. Fix: Review networking code to ensure: (1) Certificate pinning or validation is implemented, (2) HTTPS is enforced, (3) No hardcoded credentials in network requests, (4) Proper timeout configurations are set. - Low · URL Scheme Handling Security —
Sources/URLNavigator/, Sources/URLMatcher/. URLNavigator handles URL routing and pattern matching. Custom URL schemes can be exploited if not properly validated, especially when accepting external input through deep links. Fix: Implement strict URL validation and sanitization. Validate all URL parameters before using them. Implement URL allowlisting for external deep links. Do not execute arbitrary code based on URL parameters. - Low · Missing Input Validation in URLMatcher —
Sources/URLMatcher/URLMatcher.swift, Sources/URLMatcher/URLPathComponent.swift. URLMatcher handles pattern matching and component extraction. Without proper validation, malformed or malicious URLs could cause unexpected behavior. Fix: Implement comprehensive input validation for all URL patterns and components. Add bounds checking and handle edge cases. Add fuzzing tests for URL parsing.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.