Skip to content

Commit

Permalink
Merge pull request #24 from hyperoslo/feature/comventional-routes
Browse files Browse the repository at this point in the history
Feature: conventional routers & routes
  • Loading branch information
zenangst committed Jan 18, 2016
2 parents 3f50eb7 + 66eb289 commit 5124c1c
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 2 deletions.
12 changes: 12 additions & 0 deletions Compass.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
BDF7B4111C3FF43F00576737 /* TestCompass.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDF7B40F1C3FF43F00576737 /* TestCompass.swift */; };
BDF7B4151C3FF51100576737 /* Sugar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BDF7B4141C3FF51100576737 /* Sugar.framework */; };
BDF7B4171C3FF51800576737 /* Sugar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BDF7B4161C3FF51800576737 /* Sugar.framework */; };
D5A2A7931C4CEB1C00B51356 /* Routable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A2A7921C4CEB1C00B51356 /* Routable.swift */; };
D5A2A7971C4CEB7C00B51356 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A2A7961C4CEB7C00B51356 /* Router.swift */; };
D5A2A79A1C4CEDDA00B51356 /* TestRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A2A7991C4CEDDA00B51356 /* TestRouter.swift */; };
D5B2E8AA1C3A780C00C0327D /* Compass.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5B2E89F1C3A780C00C0327D /* Compass.framework */; };
D5C6294A1C3A7FAA007F7B7C /* Compass.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5C629401C3A7FAA007F7B7C /* Compass.framework */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -43,6 +46,9 @@
BDF7B40F1C3FF43F00576737 /* TestCompass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCompass.swift; sourceTree = "<group>"; };
BDF7B4141C3FF51100576737 /* Sugar.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sugar.framework; path = Carthage/Build/Mac/Sugar.framework; sourceTree = "<group>"; };
BDF7B4161C3FF51800576737 /* Sugar.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sugar.framework; path = Carthage/Build/iOS/Sugar.framework; sourceTree = "<group>"; };
D5A2A7921C4CEB1C00B51356 /* Routable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Routable.swift; sourceTree = "<group>"; };
D5A2A7961C4CEB7C00B51356 /* Router.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = "<group>"; };
D5A2A7991C4CEDDA00B51356 /* TestRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestRouter.swift; path = Sources/iOS/TestRouter.swift; sourceTree = SOURCE_ROOT; };
D5B2E89F1C3A780C00C0327D /* Compass.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Compass.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D5B2E8A91C3A780C00C0327D /* Compass-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Compass-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
D5C629401C3A7FAA007F7B7C /* Compass.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Compass.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -134,7 +140,9 @@
D5C6296A1C3A809D007F7B7C /* iOS */ = {
isa = PBXGroup;
children = (
D5A2A7921C4CEB1C00B51356 /* Routable.swift */,
BDF7B40D1C3FF41500576737 /* Compass+Navigate.swift */,
D5A2A7961C4CEB7C00B51356 /* Router.swift */,
);
path = iOS;
sourceTree = "<group>";
Expand Down Expand Up @@ -170,6 +178,7 @@
D5C629921C3A8BDA007F7B7C /* iOS */ = {
isa = PBXGroup;
children = (
D5A2A7991C4CEDDA00B51356 /* TestRouter.swift */,
);
path = iOS;
sourceTree = "<group>";
Expand Down Expand Up @@ -396,7 +405,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D5A2A7971C4CEB7C00B51356 /* Router.swift in Sources */,
BDF7B4091C3FF40300576737 /* Compass.swift in Sources */,
D5A2A7931C4CEB1C00B51356 /* Routable.swift in Sources */,
BDF7B40E1C3FF41500576737 /* Compass+Navigate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -405,6 +416,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D5A2A79A1C4CEDDA00B51356 /* TestRouter.swift in Sources */,
BDF7B4101C3FF43F00576737 /* TestCompass.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
60 changes: 58 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,46 @@ Preferably you would add your own global function that you use for internal navi

## Compass life hacks

##### Tip 1. NavigationHandler.swift
##### 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:
```swift
struct ProfileRoute: Routable {
func resolve(arguments: [String: String], navigationController: UINavigationController?) {
guard let username = arguments["username"] else { return }

let profileController = profileController(title: username)
navigationController?.pushViewController(profileController, animated: true)
}
}
```

- Create a `Router` instance and register your routes:
```swift
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.
```swift
func application(app: UIApplication,
openURL url: NSURL,
options: [String : AnyObject]) -> Bool {
return Compass.parse(url) { route, arguments in
router.navigate(route, arguments: arguments,
navigationController: navigationController)
}
}
```

##### Tip 2. Navigation handler
You could have multiple handlers depending on if a user is logged in or not.
```swift
struct NavigationHandler {
Expand Down Expand Up @@ -102,7 +141,24 @@ struct NavigationHandler {
}
```

##### Tip 2. Compass.swift
If you use `Router`-based approach you could set up 2 routers depending on the
auth state.
```swift
let routerPreLogin = Router()
routerPreLogin.routes = [
"profile:{username}" : ProfileRoute()
]

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

let router = isLoggedIn ? routerPostLogin : routerPreLogin
router.navigate(route, arguments: arguments, navigationController: navigationController)
```

##### Tip 3. Global function
Add your own global function to easily navigate internally
``` swift
import Compass
Expand Down
6 changes: 6 additions & 0 deletions Sources/iOS/Routable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import UIKit

public protocol Routable {

func resolve(arguments: [String: String], navigationController: UINavigationController?)
}
14 changes: 14 additions & 0 deletions Sources/iOS/Router.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import UIKit

public struct Router {

public var routes = [String: Routable]()

public init() {}

public func navigate(route: String, arguments: [String: String], navigationController: UINavigationController?) {
guard let route = routes[route] else { return }

route.resolve(arguments, navigationController: navigationController)
}
}
37 changes: 37 additions & 0 deletions Sources/iOS/TestRouter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Foundation
import XCTest
import Compass

class TestRoute: Routable {

var resolved = false

func resolve(arguments: [String: String], navigationController: UINavigationController?) {
resolved = true
}
}

class TestRouter: XCTestCase {

var router: Router!
var navigationController = UINavigationController()
var route: TestRoute!

override func setUp() {
router = Router()
route = TestRoute()
}

func testNavigateIfRouteRegistered() {
router.routes["test"] = route
router.navigate("test", arguments: [:], navigationController: navigationController)

XCTAssertTrue(route.resolved)
}

func testNavigateIfRouteNotRegistered() {
router.navigate("test", arguments: [:], navigationController: navigationController)

XCTAssertFalse(route.resolved)
}
}

0 comments on commit 5124c1c

Please sign in to comment.