{"id":761,"url":"https://github.com/aronbalog/CoreNavigation","last_synced_at":"2025-07-30T19:32:30.401Z","repository":{"id":56906685,"uuid":"114574435","full_name":"aronbalog/CoreNavigation","owner":"aronbalog","description":"📱📲 Navigate between view controllers with ease. 💫 🔜 More stable version (written in Swift 5) coming soon.","archived":false,"fork":false,"pushed_at":"2019-12-12T10:00:39.000Z","size":12796,"stargazers_count":74,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-27T11:30:41.679Z","etag":null,"topics":["api-wrapper","carthage","cocoapods","controller-navigation","deeplinking","ios","navigation","protection","router","routing","state-restoration","swift","view-controller","xcode"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aronbalog.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-17T22:48:42.000Z","updated_at":"2024-06-13T14:12:07.000Z","dependencies_parsed_at":"2022-08-20T19:20:26.157Z","dependency_job_id":null,"html_url":"https://github.com/aronbalog/CoreNavigation","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aronbalog%2FCoreNavigation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aronbalog%2FCoreNavigation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aronbalog%2FCoreNavigation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aronbalog%2FCoreNavigation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aronbalog","download_url":"https://codeload.github.com/aronbalog/CoreNavigation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228178890,"owners_count":17881105,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-wrapper","carthage","cocoapods","controller-navigation","deeplinking","ios","navigation","protection","router","routing","state-restoration","swift","view-controller","xcode"],"created_at":"2024-01-05T20:15:30.755Z","updated_at":"2024-12-04T19:31:59.866Z","avatar_url":"https://github.com/aronbalog.png","language":"Swift","funding_links":[],"categories":["App Routing"],"sub_categories":["Getting Started"],"readme":"# CoreNavigation 📱📲\n\nNavigate between view controllers with ease. 💫\n\n🔜 More stable version (written in Swift 5) coming soon.\n\n[![Platform](https://img.shields.io/cocoapods/p/CoreNavigation.svg?style=flat)](https://github.com/aronbalog/CoreNavigation)\n[![Build Status](https://travis-ci.org/aronbalog/CoreNavigation.svg?branch=master)](https://travis-ci.org/aronbalog/CoreNavigation)\n[![Documentation](docs/badge.svg)](http://aronbalog.github.io/CoreNavigation)\n[![codecov](https://codecov.io/gh/aronbalog/CoreNavigation/branch/master/graph/badge.svg)](https://codecov.io/gh/aronbalog/CoreNavigation)\n[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/CoreNavigation.svg)](https://img.shields.io/cocoapods/v/CoreNavigation.svg)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\n- [Getting Started]\n- [API Reference]\n- [Example Use]\n    - [Defining view controller]\n    - [Presenting view controller]\n    - [Pushing view controller]\n    - [Routing \u0026 deep linking]\n    - [Configuration]\n        - [Animating]\n        - [Observing completion]\n        - [Observing success]\n        - [Observing failure]\n        - [Embedding]\n        - [Passing data]\n        - [Caching]\n        - [Protection]\n        - [State restoration]\n        - [Specifying origin view controller]\n- [Example Apps]\n    - [BiometricAuthExample]\n    - [PassingDataExample]\n    - [DeepLinkingExample]\n- [Running the Tests]\n- [Versioning]\n- [Authors]\n- [License]\n\n[Getting Started]: #getting-started\n[API Reference]: #api-reference\n[Example Use]: #example-use\n[Defining view controller]: #defining-view-controller\n[Presenting view controller]: #presenting-view-controller\n[Pushing view controller]: #pushing-view-controller\n[Routing \u0026 deep linking]: #routing--deep-linking\n[Configuration]: #configuration\n[Example Apps]: #example-apps\n[Running the Tests]: #running-the-tests\n[Versioning]: #versioning\n[Authors]: #authors\n[License]: #license\n\n## Getting Started\n\nThese instructions will help you integrate CoreNavigation into your project.\n\n### Prerequisities\n\n- Xcode 9 or higher\n- iOS 8 or higher\n- Cocoapods\n\n### Installation\n\n#### CocoaPods\n\n[CocoaPods](http://cocoapods.org/) is a dependency manager for Cocoa projects. You can install it with the following command:\n\n```bash\n$ gem install cocoapods\n```\n\n\u003e CocoaPods 1.1+ is required to build CoreNavigation 1.0+.\n\nTo integrate CoreNavigation into your Xcode project using CocoaPods, specify it in your Podfile:\n\n```ruby\ntarget '\u003cYour Target Name\u003e' do\n    use_frameworks!\n    \n    pod 'CoreNavigation', '1.0.0-beta-4'\nend\n```\n\nThen, run the following command:\n\n```bash\n$ pod install\n```\n\n#### Carthage\n\n[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.\n\nYou can install Carthage with [Homebrew](http://brew.sh/) using the following command:\n\n```bash\n$ brew update\n$ brew install carthage\n```\n\nTo integrate CoreNavigation into your Xcode project using Carthage, specify it in your Cartfile:\n\n```\ngithub \"aronbalog/CoreNavigation\" == \"1.0.0-beta-4\"\n```\n\n## API Reference\n\n### [API reference](https://docs.corenavigation.org)\n\n## Example Use\n\n### Defining view controller:\n\n```swift\nclass PersonProfileViewController: UIViewController, DataReceivable {\n\n    // DataReceivable associatedtype\n    typealias DataType = Person\n\n    func didReceiveData(_ data: Person) {\n        // configure UI with data\n    }\n}\n```\n\n### Presenting view controller:\n\n[Code Example](Playgrounds/Presenting.playground/Contents.swift)\n\n```swift\nNavigate.present { $0\n    .to(PersonProfileViewController())\n    .withData(person)\n}\n```\n\n### Pushing view controller:\n\n[Code Example](Playgrounds/Pushing.playground/Contents.swift)\n\n```swift\nNavigate.push { $0\n    .to(PersonProfileViewController())\n    .withData(person)\n}\n```\n\n### Routing \u0026 deep linking:\n\n- [DeepLinkingExample App][DeepLinkingExample]\n\nWhy use the `Destination` instead navigating directly to view controller?\n\nRead about it on Medium:\n\n- [#0 present \u0026 push… For how long?](https://medium.com/@aronbalog/0-ios-reinventing-view-controller-navigation-c371175fbb7a)\n- [#1 Forget about segues.](https://medium.com/@aronbalog/1-ios-reinventing-view-controller-navigation-c2745b60bb6c)\n- [#2 Passing data between view controllers.](https://medium.com/@aronbalog/2-ios-reinventing-view-controller-navigation-6d3499d4df73)\n- [#3 Handle Universal Links Like a Boss.](https://medium.com/@aronbalog/3-ios-reinventing-view-controller-navigation-c5bf972bf4b4)\n\n#### Defining `Destination`\n\n[Code Example](Playgrounds/Routing.playground/Contents.swift)\n\n```swift\nstruct PersonProfile: Destination, Routable {\n\n    // Destination associatedtype\n    typealias ViewControllerType = PersonProfileViewController\n\n    // Routable patterns\n    static var patterns: [String] = [\n        \"https://myapp.com/person/:personId(.*)\",\n        \"https://myapp.com/user/:personId(.*)\"\n    ]\n    \n    let personId: String\n    \n    init(_ personId: String) {\n        self.personId = personId\n    }\n    \n    var parameters: [String : Any]? {\n        return [\n            \"personId\": personId\n        ]\n    }\n\n    static func resolve(context: Context\u003cPersonProfile\u003e) {\n        guard let personId = context.parameters?[\"personId\"] as? String else {\n            // cancel navigation with some error\n            context.cancel(error: NavigationError.Destination.notFound)\n            return\n        }\n        \n        // fetch person\n        fetchPerson(id: personId, completion: { (person: Person) in\n            // continue to navigation\n            context.complete(data: person)\n        }, failure: { (error: Error) in\n            // cancel navigation with some error\n            context.cancel(error: error)\n        })\n    }\n}\n```\n\n---\n\n#### Registering `Routable` types\n\nIn order to use `Matchable` types (`String`, `URL`, etc.) to navigate, every `Destination` type must be registered. Think about it as internal DNS.\n\n```swift\nPersonProfile.register()\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eAdditional syntax\u003c/summary\u003e\n\n```swift\nNavigate.router.register(routableType: PersonProfile.self)\n```\n\n\u003c/details\u003e\n\n---\n\n`Destination` type can be routable without conforming to `Routable` protocol. Use this if you intend to create some kind of destination manifest and/or if route patterns are fetched from an external source:\n\n```swift\nNavigate.router.register(destinationType: PersonProfile.self, patterns: [\n    \"https://myapp.com/person/:personId(.*)\",\n    \"https://myapp.com/user/:personId(.*)\"\n])\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eAdditional syntax\u003c/summary\u003e\n\n```swift\nPersonProfile.self \u003c- [\n    \"https://myapp.com/person/:personId(.*)\",\n    \"https://myapp.com/user/:personId(.*)\"\n]\n\nSettings.self \u003c- [\n    \"https://myapp.com/settings\"\n]\n```\n\n\u003c/details\u003e\n\n---\n\n#### Navigating using `Destination`\n\n```swift\n// present\nNavigate.present { $0\n    .to(PersonProfile(\"sherlock_holmes\"))\n    ...\n}\n\n// or push\nNavigate.push { $0\n    .to(PersonProfile(\"sherlock_holmes\"))\n    ...\n}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eAdditional syntax\u003c/summary\u003e\n\n```swift\n// present\nPersonProfile(\"sherlock_holmes\").present { $0\n    ...\n}\n\n// or push\nPersonProfile(\"sherlock_holmes\").push { $0\n    ...\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eAdditional syntax\u003c/summary\u003e\n\n```swift\n// present\nPersonProfile(\"sherlock_holmes\").present()\n\n// or push\nPersonProfile(\"sherlock_holmes\").push()\n```\n\n\u003c/details\u003e\n\n---\n\n#### Navigating using route\n\n[Code Example](Playgrounds/Routing.playground/Contents.swift)\n\n```swift\n// present\nNavigate.present { $0\n    .to(\"https://myapp.com/person/sherlock_holmes\")\n    ...\n}\n\n// or push\nNavigate.push { $0\n    .to(\"https://myapp.com/person/sherlock_holmes\")\n    ...\n}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eAdditional syntax\u003c/summary\u003e\n\n```swift\n// present\n\"https://myapp.com/person/sherlock_holmes\".present { $0\n    ...\n}\n\n// or push\n\"https://myapp.com/person/sherlock_holmes\".push { $0\n    ...\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eAdditional syntax\u003c/summary\u003e\n\n```swift\n// present\n\"https://myapp.com/person/sherlock_holmes\".present()\n\n// or push\n\"https://myapp.com/person/sherlock_holmes\".push()\n```\n\n\u003c/details\u003e\n\n---\n\n#### Getting view controller asynchronously using `Destination`\n\n```swift\nPersonProfile(\"sherlock_holmes\").viewController { (viewController) in\n    // vc is `PersonProfileViewController`\n}\n```\n\n---\n\n#### Getting view controller asynchronously using route\n\n```swift\n\"https://myapp.com/person/sherlock_holmes\".viewController { (viewController) in\n    ...\n}\n```\n\n---\n\n#### Getting view controller synchronously using `Destination`\n\n[Code Example](Playgrounds/Routing.playground/Contents.swift)\n\n```swift\ndo {\n    let viewController = try PersonProfile(\"sherlock_holmes\").viewController()\n} catch let error {\n    // handle error\n}\n```\n\n---\n\n#### Getting view controller synchronously using route\n\n```swift\ndo {\n    let viewController = try \"https://myapp.com/person/sherlock_holmes\".viewController()\n} catch let error {\n    // handle error\n}\n```\n\nNote:\n\n*If you implement custom destination resolving, **it must happen on the main thread**; otherwise, an error is thrown.*\n\n---\n\n#### Matchable protocol\n\n`URL` types can also be used to navigate or resolve view controller. Actually, any type conforming `Matchable` protocol can be used.\n\n##### Conforming to matchable:\n\n```swift\nstruct Person {\n    let id: String\n    ...\n}\n\nextension Person: Matchable {\n    var uri: String {\n        return \"https://myapp.com/person/\" + id\n    }\n}\n```\n\n##### Example usage:\n\n```swift\nlet person: Person = Person(id: \"sherlock_holmes\", ...)\n\n// getting view controller\nlet personProfileViewController = try! person.viewController\n\n// or navigating\nperson.present()\nperson.push()\n\n// or more configurable syntax\nNavigate.present { $0\n    .to(person)\n    ...\n}\n```\n\n### Configuration\n\n- [Animating]\n- [Observing completion]\n- [Observing success]\n- [Observing failure]\n- [Embedding]\n- [Passing data]\n- [Caching]\n- [Protection]\n- [State restoration]\n- [Specifying origin view controller]\n\n## Example Apps\n\n- [BiometricAuthExample]\n- [PassingDataExample]\n- [DeepLinkingExample]\n\n## Running the Tests\n\nAvailable in `CoreNavigationTests` target.\n\n## Versioning\n\nCurrent release:\n\n- 1.0.0-beta-4\n\n## Authors\n\n- Aron Balog - [GitHub](https://github.com/aronbalog) | [Twitter](https://twitter.com/Aron_Balog) | [LinkedIn](https://www.linkedin.com/in/aronbalog/) | [Medium](https://medium.com/@aronbalog)\n\n### Contributing\n\nPlease read [Contributing](CONTRIBUTING.md) for details on code of conduct, and the process for submitting pull requests.\n\n## License\n\nThis project is licensed under the **MIT License** - see the [LICENSE](LICENSE.md) file for details.\n\n\n[Animating]: Documentation/CONFIGURATION.md#animating\n[Observing completion]: Documentation/CONFIGURATION.md#observing-completion\n[Observing success]: Documentation/CONFIGURATION.md#observing-success\n[Observing failure]: Documentation/CONFIGURATION.md#observing-failure\n[Embedding]: Documentation/CONFIGURATION.md#embedding\n[Passing data]: Documentation/CONFIGURATION.md#passing-data\n[Caching]: Documentation/CONFIGURATION.md#caching\n[Protection]: Documentation/CONFIGURATION.md#protection\n[State restoration]: Documentation/CONFIGURATION.md#state-restoration\n[Specifying origin view controller]: Documentation/CONFIGURATION.md#specifying-origin-view-controller\n\n\u003c!--- example apps --\u003e\n\n[BiometricAuthExample]: Examples/BiometricAuthExample\n[PassingDataExample]: Examples/PassingDataExample\n[DeepLinkingExample]: Examples/DeepLinkingExample\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faronbalog%2FCoreNavigation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faronbalog%2FCoreNavigation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faronbalog%2FCoreNavigation/lists"}