Compass 0,0 travis-ci CocoaPods

:earth_africa: Compass helps you setup a central navigation system for your application

2 years after

Compass logo

Version Carthage Compatible License Platform CI Status Swift

Compass helps you setup a central navigation system for your application. This has many benefits, one of them being that controllers can now be decoupled, meaning that the list that presents the detail no longer knows about what its presenting. Controllers become agnostic and views stay stupid. The user experience stays the same but the logic and separation of concerns become clearer. The outcome is that your application will become more modular by default. Anything could potentially be presented from anywhere, but remember, with great power comes great responsibility.

Setup

Step 1

First you need to register a URL scheme for your application

Step 2

Now you need to configure Compass to use that URL scheme, a good place to do this is in your AppDelegate

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  Compass.scheme = "compass"
  return true
}

Step 3

Configure your application routes

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  Compass.scheme = "compass"
  Compass.routes = ["profile:{username}", "login:{username}", "logout"]
  return true
}

Step 4

Set up your application to respond to the URLs, this can be done in the AppDelegate but its up to you to find a more suitable place for it depending on the size of your implementation.

func application(_ app: UIApplication,
                 open url: URL,
                 options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
  guard let location = Compass.parse(url) else {
    return false
  }

  let arguments = location.arguments

  switch location.path {
    case "profile:{username}":
      let profileController = profileController(title: arguments["{username}"])
      self.navigationController?.pushViewController(profileController, animated: true)
    case "login:{username}":
      let loginController = LoginController(title: arguments["{username}"])
      self.navigationController?.pushViewController(loginController, animated: true)
    case "logout":
      logout()
    default: break
  }

  return true
}

Setting it up this way would mean that you could open any view from a push notification depending on the contents of the payload. Preferably you would add your own global function that you use for internal navigation.

Compass life hacks

Tip 1. Router

We also have some conventional tools for you that could be used to organize your route handling code and avoid huge switch cases.

  • Implement Routable protocol to keep your single route navigation code in one place:

    struct ProfileRoute: Routable {
    
    func navigate(to location: Location, from currentController: UIViewController) {
    guard let username = location.arguments["username"] else { return }
    
    let profileController = profileController(title: username)
    currentController.navigationController?.pushViewController(profileController, animated: true)
    }
    }
  • Create a Router instance and register your routes:

    let router = Router()
    router.routes = [
    "profile:{username}" : ProfileRoute(),
    // "logout" : LogoutRoute()
    ]
  • Parse URL with Compass and navigate to the route with a help of your Router instance.

    func application(_ app: UIApplication,
                 open url: URL,
                 options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool {
    guard let location = Compass.parse(url) else {
    return false
    }
    
    router.navigate(to: location, from: navigationController)
    
    return true
    }
Tip 2. Navigation handler

You could have multiple handlers depending on if a user is logged in or not.

struct NavigationHandler {

  static func routePreLogin(location: Location, navigationController: UINavigationController) {
    switch location.path {
    case "forgotpassword:{username}":
      let controller = ForgotPasswordController(title: location.arguments["{username}"])
      navigationController?.pushViewController(controller, animated: true)
    default: break
    }
  }

  static func routePostLogin(location: Location, navigationController: UINavigationController) {
    switch location.path {
    case "profile:{username}":
      let controller = ProfileController(title: location.arguments["{username}"])
      navigationController?.pushViewController(controller, animated: true)
    case "logout":
      AppDelegate.logout()
    default: break
    }
  }
}

If you use Router-based approach you could set up 2 routers depending on the auth state.

let routerPreLogin = Router()
routerPreLogin.routes = [
  "profile:{username}" : ProfileRoute()
]

let routerPostLogin = Router()
routerPostLogin.routes = [
  "login:{username}" : LoginRoute()
]

let router = isLoggedIn ? routerPostLogin : routerPreLogin
router.navigate(to: location, from: navigationController)
Tip 3. Global function

Add your own global function to easily navigate internally

import Compass

public func navigate(urn: String) {
  let stringUrl = "\(Compass.scheme)\(urn)"
  guard let appDelegate = UIApplication.sharedApplication().delegate as? ApplicationDelegate,
    url = URL(string: stringUrl) else { return }

  appDelegate.handleURL(url)
}

Installation

Compass is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Compass'

Compass is also available through Carthage. To install just write into your Cartfile:

github "hyperoslo/Compass"

Author

Hyper Interaktiv AS, [email protected]

Credits

The idea behind Compass came from John Sundell's tech talk "Components & View Models in the Cloud - how Spotify builds native, dynamic UIs"

License

Compass is available under the MIT license. See the LICENSE file for more info.

Related Repositories

grunt-contrib-compass

grunt-contrib-compass

Compile Compass to CSS. ...

compass-rails

compass-rails

compass rails integration ...

gulp-compass

gulp-compass

Compass plugin for gulp ...

compass-inuit

compass-inuit

:white_flower: Official Compass extension for inuit.css ...

compass-jquery-plugin

compass-jquery-plugin

Plugin adds jQuery to compass framework. ...


Top Contributors

zenangst vadymmarkov onmyway133 RamonGilabert jessearmand timkurvers

Releases

-   3.0.1 zip tar
-   3.0.0 zip tar
-   2.0.0 zip tar
-   1.4.0 zip tar
-   1.3.0 zip tar
-   1.2.4 zip tar
-   1.2.3 zip tar
-   1.2.2 zip tar
-   1.2.1 zip tar
-   1.2.0 zip tar
-   1.1.0 zip tar
-   1.0.0 zip tar