Skip to content
This repository was archived by the owner on Sep 20, 2023. It is now read-only.

Commit 64f920a

Browse files
authored
new routing library and refactor shortcuts (#2241)
1 parent c45b35e commit 64f920a

16 files changed

+295
-108
lines changed

Classes/Search/SearchViewController.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ SearchResultSectionControllerDelegate {
104104
}
105105
}
106106

107+
func searchBarBecomeFirstResponder() {
108+
searchBar.becomeFirstResponder()
109+
}
110+
107111
// MARK: Data Loading/Paging
108112

109113
private func update(animated: Bool) {

Classes/Systems/AppDelegate.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2323
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
2424

2525
appController.appDidFinishLaunching(with: window)
26+
appController.setupRoutes()
2627

2728
// setup fabric
2829
Fabric.with([Crashlytics.self])
@@ -49,11 +50,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
4950
}
5051

5152
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
52-
guard let route = Route(shortcutItem: shortcutItem) else {
53-
completionHandler(false)
54-
return
55-
}
56-
completionHandler(appController.handle(route: route))
53+
appController.handle(path: shortcutItem.type, params: shortcutItem.params)
5754
}
5855

5956
func applicationDidBecomeActive(_ application: UIApplication) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// AppController+SetupRoutes.swift
3+
// Freetime
4+
//
5+
// Created by Ryan Nystrom on 10/7/18.
6+
// Copyright © 2018 Ryan Nystrom. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
extension AppController {
12+
13+
func setupRoutes() {
14+
register(route: BookmarkShortcutRoute.self)
15+
register(route: SwitchAccountShortcutRoute.self)
16+
register(route: SearchShortcutRoute.self)
17+
}
18+
19+
}

Classes/Systems/AppRouter/AppController.swift

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ final class AppController: LoginSplashViewControllerDelegate, GitHubSessionListe
1818
private var appClient: GithubClient?
1919
private var settingsNavigationController: UINavigationController?
2020
private var watchAppSync: WatchAppUserSessionSync?
21+
private var routes = [String: (Routable & RoutePerformable).Type]()
2122

2223
init() {
2324
sessionManager.addListener(listener: self)
@@ -51,18 +52,30 @@ final class AppController: LoginSplashViewControllerDelegate, GitHubSessionListe
5152
appClient?.badge.fetch(application: application, handler: completion)
5253
}
5354

54-
func handle(route: Route) -> Bool {
55-
switch route {
56-
case .tab(let tab):
57-
splitViewController.select(tabAt: tab.rawValue)
58-
return true
59-
case .switchAccount(let sessionIndex):
60-
if let index = sessionIndex {
61-
let session = sessionManager.userSessions[index]
62-
sessionManager.focus(session, dismiss: false)
63-
}
64-
return true
55+
@discardableResult
56+
func handle(url: URL) -> Bool {
57+
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
58+
else { return false }
59+
var params = [String: String]()
60+
for item in components.queryItems ?? [] {
61+
params[item.name] = item.value
6562
}
63+
return handle(path: url.path, params: params)
64+
}
65+
66+
@discardableResult
67+
func handle(path: String, params: [String: String]) -> Bool {
68+
guard let routeType = routes[path],
69+
let route = routeType.from(params: params)
70+
else { return false }
71+
return route.perform(
72+
sessionManager: sessionManager,
73+
splitViewController: splitViewController
74+
)
75+
}
76+
77+
func register<T: Routable & RoutePerformable>(route: T.Type) {
78+
routes[T.path] = T.self
6679
}
6780

6881
private func resetWatchSync(userSession: GitHubUserSession) {

Classes/Systems/AppRouter/AppSplitViewController.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,14 @@ final class AppSplitViewController: UISplitViewController {
2020
preferredDisplayMode = .allVisible
2121
}
2222

23-
private var detailNavigationController: UINavigationController? {
23+
var detailNavigationController: UINavigationController? {
2424
return viewControllers.last as? UINavigationController
2525
}
2626

27-
private var masterTabBarController: UITabBarController? {
27+
var masterTabBarController: UITabBarController? {
2828
return viewControllers.first as? UITabBarController
2929
}
3030

31-
func select(tabAt index: Int) {
32-
masterTabBarController?.selectedIndex = index
33-
}
34-
3531
func resetEmpty() {
3632
let controller = UIViewController()
3733
controller.view.backgroundColor = Styles.Colors.background
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// BookmarkShortcutRoute.swift
3+
// Freetime
4+
//
5+
// Created by Ryan Nystrom on 10/7/18.
6+
// Copyright © 2018 Ryan Nystrom. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import GitHubSession
11+
12+
struct BookmarkShortcutRoute: Routable {
13+
static func from(params: [String : String]) -> BookmarkShortcutRoute? {
14+
return BookmarkShortcutRoute()
15+
}
16+
static var path: String {
17+
return "com.githawk.shortcut.bookmark"
18+
}
19+
}
20+
21+
extension BookmarkShortcutRoute: RoutePerformable {
22+
func perform(
23+
sessionManager: GitHubSessionManager,
24+
splitViewController: AppSplitViewController
25+
) -> Bool {
26+
return splitViewController.masterTabBarController?.selectTab(of: BookmarkViewController.self) != nil
27+
}
28+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// Routable.swift
3+
// Freetime
4+
//
5+
// Created by Ryan Nystrom on 10/7/18.
6+
// Copyright © 2018 Ryan Nystrom. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
protocol Routable {
12+
static func from(params: [String: String]) -> Self?
13+
var encoded: [String: String] { get }
14+
static var path: String { get }
15+
}
16+
17+
extension Routable {
18+
var encoded: [String: String] { return [:] }
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// RoutePerformable.swift
3+
// Freetime
4+
//
5+
// Created by Ryan Nystrom on 10/7/18.
6+
// Copyright © 2018 Ryan Nystrom. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import GitHubSession
11+
12+
protocol RoutePerformable {
13+
@discardableResult
14+
func perform(
15+
sessionManager: GitHubSessionManager,
16+
splitViewController: AppSplitViewController
17+
) -> Bool
18+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// SearchShortcutRoute.swift
3+
// Freetime
4+
//
5+
// Created by Ryan Nystrom on 10/7/18.
6+
// Copyright © 2018 Ryan Nystrom. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import GitHubSession
11+
12+
struct SearchShortcutRoute: Routable {
13+
static func from(params: [String : String]) -> SearchShortcutRoute? {
14+
return SearchShortcutRoute()
15+
}
16+
static var path: String {
17+
return "com.githawk.shortcut.search"
18+
}
19+
}
20+
21+
extension SearchShortcutRoute: RoutePerformable {
22+
func perform(
23+
sessionManager: GitHubSessionManager,
24+
splitViewController: AppSplitViewController
25+
) -> Bool {
26+
guard let controller = splitViewController.masterTabBarController?.selectTab(of: SearchViewController.self)
27+
else { return false }
28+
controller.searchBarBecomeFirstResponder()
29+
return true
30+
}
31+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// SwitchAccountShortcutRoute.swift
3+
// Freetime
4+
//
5+
// Created by Ryan Nystrom on 10/7/18.
6+
// Copyright © 2018 Ryan Nystrom. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import GitHubSession
11+
12+
struct SwitchAccountShortcutRoute: Routable {
13+
let username: String
14+
static func from(params: [String : String]) -> SwitchAccountShortcutRoute? {
15+
guard let username = params["username"] else { return nil }
16+
return SwitchAccountShortcutRoute(username: username)
17+
}
18+
var encoded: [String : String] {
19+
return ["username": username]
20+
}
21+
static var path: String {
22+
return "com.githawk.shortcut.switch"
23+
}
24+
}
25+
26+
extension SwitchAccountShortcutRoute: RoutePerformable {
27+
func perform(
28+
sessionManager: GitHubSessionManager,
29+
splitViewController: AppSplitViewController
30+
) -> Bool {
31+
let userSessions = sessionManager.userSessions
32+
guard let needle = userSessions.first(where: { username == $0.username })
33+
else { return false }
34+
sessionManager.focus(needle, dismiss: false)
35+
splitViewController.masterTabBarController?.selectTab(of: NotificationsViewController.self)
36+
return true
37+
}
38+
}

0 commit comments

Comments
 (0)