{"id":13396630,"url":"https://github.com/hyperoslo/Compass","last_synced_at":"2025-03-13T23:31:40.933Z","repository":{"id":56906443,"uuid":"43808690","full_name":"hyperoslo/Compass","owner":"hyperoslo","description":":earth_africa: Compass helps you setup a central navigation system for your application","archived":false,"fork":false,"pushed_at":"2020-11-19T11:32:21.000Z","size":353,"stargazers_count":826,"open_issues_count":6,"forks_count":47,"subscribers_count":22,"default_branch":"master","last_synced_at":"2024-11-24T16:48:59.236Z","etag":null,"topics":["compass","ios","navigation","scheme","swift","url"],"latest_commit_sha":null,"homepage":"http://hyper.no","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyperoslo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2015-10-07T10:25:56.000Z","updated_at":"2024-10-18T11:04:09.000Z","dependencies_parsed_at":"2022-08-20T19:20:26.150Z","dependency_job_id":null,"html_url":"https://github.com/hyperoslo/Compass","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperoslo%2FCompass","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperoslo%2FCompass/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperoslo%2FCompass/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperoslo%2FCompass/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperoslo","download_url":"https://codeload.github.com/hyperoslo/Compass/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243238970,"owners_count":20259126,"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":["compass","ios","navigation","scheme","swift","url"],"created_at":"2024-07-30T18:00:58.428Z","updated_at":"2025-03-13T23:31:40.593Z","avatar_url":"https://github.com/hyperoslo.png","language":"Swift","funding_links":[],"categories":["Misc","App Routing","Libs","Uncategorized","Utilities and Extensions","URL Scheme"],"sub_categories":["Other free courses","Utility","Uncategorized"],"readme":"⚠️ DEPRECATED, NO LONGER MAINTAINED\n\n![Compass logo](https://raw.githubusercontent.com/hyperoslo/Compass/master/Images/logo_v1.png)\n\n[![Version](https://img.shields.io/cocoapods/v/Compass.svg?style=flat)](http://cocoadocs.org/docsets/Compass)\n[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![License](https://img.shields.io/cocoapods/l/Compass.svg?style=flat)](http://cocoadocs.org/docsets/Compass)\n[![Platform](https://img.shields.io/cocoapods/p/Compass.svg?style=flat)](http://cocoadocs.org/docsets/Compass)\n[![CI Status](http://img.shields.io/travis/hyperoslo/Compass.svg?style=flat)](https://travis-ci.org/hyperoslo/Compass)\n![Swift](https://img.shields.io/badge/%20in-swift%203.0-orange.svg)\n\nCompass helps you setup a central navigation system for your application.\nThis has many benefits, one of them being that controllers can now be\ndecoupled, meaning that the list that presents the detail no longer knows\nabout what its presenting. Controllers become agnostic and views stay\nstupid. The user experience stays the same but the logic and separation of\nconcerns become clearer. The outcome is that your application will become\nmore modular by default. Anything could potentially be presented from\nanywhere, but remember, with great power comes great responsibility.\n\n## Getting Started\n\nBelow are tutorials on how to use Compass\n\n- [URL Routing in iOS apps: Compass Beginner Guide](https://medium.com/flawless-app-stories/url-routing-with-compass-d59c0061e7e2): basic introduction to Compass, how to use Router and multiple use cases for deep linking, push notifications\n\n## Setup\n\n#### Step 1\nFirst you need to register a URL scheme for your application.\n\n\u003cimg src=\"https://raw.githubusercontent.com/hyperoslo/Compass/master/Images/setup-url-scheme.png\"\u003e\n\n#### Step 2\nNow you need to configure Compass to use that URL scheme, a good place\nto do this is in your `AppDelegate`. Then configure all the routes you wish you support.\n\n```swift\nfunc application(_ application: UIApplication,\n                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -\u003e Bool {\n  Navigator.scheme = \"compass\"\n  Navigator.routes = [\"profile:{username}\", \"login:{username}\", \"logout\"]\n  return true\n}\n```\n\n#### Step 3\n\nRegister your location request handler\n\n\n```swift\nNavigator.handle = { [weak self] location in\n  let arguments = location.arguments\n\n  let rootController = self?.window.rootViewController as? UINavigationController\n\n  switch location.path {\n    case \"profile:{username}\":\n      let profileController = ProfileController(title: arguments[\"username\"])\n      rootController?.pushViewController(profileController, animated: true)\n    case \"login:{username}\":\n      let loginController = LoginController(title: arguments[\"username\"])\n      rootController?.pushViewController(loginController, animated: true)\n    case \"logout\":\n      self?.clearLoginSession()\n      self?.switchToLoginScreen()\n    default: \n      break\n  }\n}\n```\n\n#### Step 4\n\nAnywhere in your application, you can just use `Navigator` to navigate\n\n```swift\n@IBOutlet func logoutButtonTouched() {\n  Navigator.navigate(urn: \"logout\")\n}\n```\n\n#### Step 5\nOptional. If you want to support deep linking,  set up your application to respond to the URLs. Setting it up this way would mean that\nyou could open any view from a push notification depending on the contents of the payload.\n\n```swift\nfunc application(_ app: UIApplication,\n                 open url: URL,\n                 options: [UIApplicationOpenURLOptionsKey : Any]) -\u003e Bool {\n  do {\n    try Navigator.navigate(url: url)\n  } catch {\n    // Handle error\n  }\n\n  return true\n}\n```\n\n## Compass life hacks\n\n### Tip 1. Router\nWe also have some conventional tools for you that could be used to organize your\nroute handling code and avoid huge `switch` cases.\n\n- Implement `Routable` protocol to keep your single route navigation code\nin one place:\n```swift\nstruct ProfileRoute: Routable {\n\n  func navigate(to location: Location, from currentController: CurrentController) throws {\n    guard let username = location.arguments[\"username\"] else { return }\n\n    let profileController = ProfileController(title: username)\n    currentController.navigationController?.pushViewController(profileController, animated: true)\n  }\n}\n```\n\n- Create a `Router` instance and register your routes. Think of `Router` as a composite `Routable`\n```swift\nlet router = Router()\nrouter.routes = [\n  \"profile:{username}\": ProfileRoute(),\n  \"logout\": LogoutRoute()\n]\n```\n\n- Parse URL with **Compass** and navigate to the route with a help of your\n`Router` instance.\n```swift\nfunc application(_ app: UIApplication,\n                 open url: URL,\n                 options: [UIApplicationOpenURLOptionsKey : Any]) -\u003e Bool {\n  \n  return handle(url)\n}\n\nfunc handle(_ url: URL) -\u003e Bool {\n  guard let location = Navigator.parse(url) else {\n    return false\n  }\n\n  router.navigate(to: location, from: navigationController)\n\n  return true\n}\n```\n\n### Tip 2. Multiple routers\nYou could set up multiple routers depending on app states. For example, you could have 2 routers for pre and post login.\n\n```swift\nlet preLoginRouter = Router()\npreLoginRouter.routes = [\n  \"profile:{username}\" : ProfileRoute()\n]\n\nlet postLoginRouter = Router()\npostLoginRouter.routes = [\n  \"login:{username}\" : LoginRoute()\n]\n\nlet router = hasLoggedIn ? postLoginRouter : preLoginRouter\nrouter.navigate(to: location, from: navigationController)\n```\n\n## Installation\n\n**Compass** is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod 'Compass'\n```\n\n**Compass** is also available through [Carthage](https://github.com/Carthage/Carthage).\nTo install just write into your Cartfile:\n\n```ruby\ngithub \"hyperoslo/Compass\"\n```\n\n## Author\n\nHyper Interaktiv AS, ios@hyper.no\n\n## Credits\n\nThe idea behind Compass came from [John Sundell](https://github.com/JohnSundell)'s tech talk \"*Components \u0026 View Models in the Cloud - how Spotify builds native, dynamic UIs*\"\n\n## License\n\n**Compass** is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperoslo%2FCompass","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperoslo%2FCompass","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperoslo%2FCompass/lists"}