Skip to content

Commit 5da00e7

Browse files
committed
[BookmarkViewController] Add Bookmarks & Bookmark Links
1 parent d644ad4 commit 5da00e7

File tree

11 files changed

+213
-32
lines changed

11 files changed

+213
-32
lines changed

ReSwiftDev/ReSwiftRouter/ReSwiftRouter/NavigationActions.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ public struct SetRouteAction: StandardActionConvertible {
3333

3434
public struct SetRouteSpecificData: Action {
3535
let route: [RouteElementIdentifier]
36-
let data: AnyObject
36+
let data: Any?
3737

38-
public init(route: [RouteElementIdentifier], data: AnyObject) {
38+
public init(route: [RouteElementIdentifier], data: Any?) {
3939
self.route = route
4040
self.data = data
4141
}

ReSwiftDev/ReSwiftRouter/ReSwiftRouter/NavigationReducer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public struct NavigationReducer {
4040
static func setRouteSpecificData(
4141
var state: NavigationState,
4242
route: [RouteElementIdentifier],
43-
data: AnyObject) -> NavigationState{
43+
data: Any?) -> NavigationState{
4444
let routeHash = RouteHash(route: route)
4545

4646
state.routeSpecificState[routeHash] = data

ReSwiftDev/ReSwiftRouter/ReSwiftRouter/NavigationState.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public struct NavigationState {
2828
public init() {}
2929

3030
public var route: [RouteElementIdentifier] = []
31-
public var routeSpecificState: [RouteHash: AnyObject?] = [:]
31+
public var routeSpecificState: [RouteHash: Any?] = [:]
3232
}
3333

3434
extension NavigationState {

ReSwiftDev/ReSwiftRouter/ReSwiftRouter/Routable.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ public protocol Routable {
2525
extension Routable {
2626
public func changeRouteSegment(from: RouteElementIdentifier,
2727
to: RouteElementIdentifier, completionHandler: RoutingCompletionHandler) -> Routable {
28-
fatalError("This routable cannot change segments. You have not implemented it.")
28+
fatalError("This routable (\(self.dynamicType)) cannot change segments. You have not implemented it.")
2929
}
3030

3131
public func popRouteSegment(routeElementIdentifier: RouteElementIdentifier,
3232
completionHandler: RoutingCompletionHandler) {
33-
fatalError("This routable cannot change segments. You have not implemented it.")
33+
fatalError("This routable (\(self.dynamicType)) cannot change segments. You have not implemented it.")
3434
}
3535

3636
public func pushRouteSegment(routeElementIdentifier: RouteElementIdentifier,
3737
completionHandler: RoutingCompletionHandler) -> Routable {
38-
fatalError("This routable cannot change segments. You have not implemented it.")
38+
fatalError("This routable (\(self.dynamicType)) cannot change segments. You have not implemented it.")
3939
}
4040
}

ReSwiftDev/ReSwiftRouter/ReSwiftRouter/Router.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ public class Router<State: StateType>: StoreSubscriber {
7676

7777
let result = dispatch_semaphore_wait(semaphore, waitUntil)
7878

79-
if result != 0 {
80-
assertionFailure("[SwiftFlowRouter]: Router is stuck waiting for a" +
81-
" completion handler to be called. Ensure that you have called the " +
82-
" completion handler in each Routable element.")
83-
}
79+
// if result != 0 {
80+
// assertionFailure("[SwiftFlowRouter]: Router is stuck waiting for a" +
81+
// " completion handler to be called. Ensure that you have called the " +
82+
// " completion handler in each Routable element.")
83+
// }
8484
}
8585

8686
}

SwiftFlowGitHubBrowser.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
251A75DC1C94F92900EBEB32 /* BookmarkViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 251A75DB1C94F92900EBEB32 /* BookmarkViewController.swift */; };
1011
2532E8F61C8F8BFB003F5392 /* BookmarkActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2532E8F51C8F8BFB003F5392 /* BookmarkActions.swift */; };
1112
2532E92B1C8F8C49003F5392 /* BookmarksReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2532E92A1C8F8C49003F5392 /* BookmarksReducer.swift */; };
1213
258184351C3CC710008E200A /* State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 258184341C3CC710008E200A /* State.swift */; };
@@ -474,6 +475,7 @@
474475
/* End PBXCopyFilesBuildPhase section */
475476

476477
/* Begin PBXFileReference section */
478+
251A75DB1C94F92900EBEB32 /* BookmarkViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkViewController.swift; sourceTree = "<group>"; };
477479
2532E8F51C8F8BFB003F5392 /* BookmarkActions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkActions.swift; sourceTree = "<group>"; };
478480
2532E92A1C8F8C49003F5392 /* BookmarksReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarksReducer.swift; sourceTree = "<group>"; };
479481
258183DB1C3CBFAD008E200A /* OctoKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OctoKit.xcodeproj; path = Carthage/Checkouts/octokit.swift/OctoKit.xcodeproj; sourceTree = SOURCE_ROOT; };
@@ -738,6 +740,7 @@
738740
62EF0A6D1C700ABB00D13711 /* LoginViewController.swift */,
739741
62EF0A6F1C700AD500D13711 /* MainViewController.swift */,
740742
62C9357A1C8CDBDE00887A23 /* RepositoryDetailViewController.swift */,
743+
251A75DB1C94F92900EBEB32 /* BookmarkViewController.swift */,
741744
);
742745
path = ViewControllers;
743746
sourceTree = "<group>";
@@ -1328,6 +1331,7 @@
13281331
25C00EA21C3CDD1F0074655A /* GitHubAPIReducers.swift in Sources */,
13291332
25BB76211C3CB8CB008EA13B /* AppDelegate.swift in Sources */,
13301333
62EF0A6E1C700ABB00D13711 /* LoginViewController.swift in Sources */,
1334+
251A75DC1C94F92900EBEB32 /* BookmarkViewController.swift in Sources */,
13311335
258184351C3CC710008E200A /* State.swift in Sources */,
13321336
);
13331337
runOnlyForDeploymentPostprocessing = 0;

SwiftFlowGitHubBrowser/Base.lproj/Main.storyboard

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,13 @@
4141
</mask>
4242
</variation>
4343
</view>
44-
<navigationItem key="navigationItem" id="XbV-GW-xhp"/>
44+
<navigationItem key="navigationItem" id="XbV-GW-xhp">
45+
<barButtonItem key="leftBarButtonItem" systemItem="bookmarks" id="fxm-SM-LX0">
46+
<connections>
47+
<action selector="bookmarkButtonTapped:" destination="yUK-y6-GzQ" id="vog-Ft-u1F"/>
48+
</connections>
49+
</barButtonItem>
50+
</navigationItem>
4551
<connections>
4652
<outlet property="tableView" destination="5Nv-6h-Sf8" id="7d1-dQ-HWz"/>
4753
</connections>
@@ -50,6 +56,51 @@
5056
</objects>
5157
<point key="canvasLocation" x="1772" y="228"/>
5258
</scene>
59+
<!--Bookmarks-->
60+
<scene sceneID="lt1-dn-ObG">
61+
<objects>
62+
<viewController storyboardIdentifier="BookmarkViewController" title="Bookmarks" id="A0E-XS-maW" customClass="BookmarkViewController" customModule="SwiftFlowGitHubBrowser" customModuleProvider="target" sceneMemberID="viewController">
63+
<layoutGuides>
64+
<viewControllerLayoutGuide type="top" id="EO9-br-Cf2"/>
65+
<viewControllerLayoutGuide type="bottom" id="tXf-EV-W6x"/>
66+
</layoutGuides>
67+
<view key="view" contentMode="scaleToFill" id="EFE-1Y-oqo">
68+
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
69+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
70+
<subviews>
71+
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="pIz-t6-i0Q">
72+
<rect key="frame" x="0.0" y="20" width="600" height="580"/>
73+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
74+
</tableView>
75+
</subviews>
76+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
77+
<constraints>
78+
<constraint firstAttribute="trailingMargin" secondItem="pIz-t6-i0Q" secondAttribute="trailing" id="47u-gc-ZJp"/>
79+
<constraint firstItem="tXf-EV-W6x" firstAttribute="top" secondItem="pIz-t6-i0Q" secondAttribute="bottom" id="9IN-JP-9ls"/>
80+
<constraint firstItem="pIz-t6-i0Q" firstAttribute="top" secondItem="EO9-br-Cf2" secondAttribute="bottom" id="Hau-7q-lpm"/>
81+
<constraint firstAttribute="trailing" secondItem="pIz-t6-i0Q" secondAttribute="trailing" id="QRF-af-HF4"/>
82+
<constraint firstItem="pIz-t6-i0Q" firstAttribute="top" secondItem="EO9-br-Cf2" secondAttribute="bottom" id="lTB-Ye-LPz"/>
83+
<constraint firstItem="pIz-t6-i0Q" firstAttribute="leading" secondItem="EFE-1Y-oqo" secondAttribute="leading" id="pit-dH-7Yr"/>
84+
<constraint firstItem="tXf-EV-W6x" firstAttribute="top" secondItem="pIz-t6-i0Q" secondAttribute="bottom" id="s5F-Ld-pMw"/>
85+
<constraint firstItem="pIz-t6-i0Q" firstAttribute="leading" secondItem="EFE-1Y-oqo" secondAttribute="leadingMargin" id="uDn-oZ-14W"/>
86+
</constraints>
87+
<variation key="default">
88+
<mask key="constraints">
89+
<exclude reference="47u-gc-ZJp"/>
90+
<exclude reference="Hau-7q-lpm"/>
91+
<exclude reference="uDn-oZ-14W"/>
92+
<exclude reference="s5F-Ld-pMw"/>
93+
</mask>
94+
</variation>
95+
</view>
96+
<connections>
97+
<outlet property="tableView" destination="pIz-t6-i0Q" id="LhS-va-IvA"/>
98+
</connections>
99+
</viewController>
100+
<placeholder placeholderIdentifier="IBFirstResponder" id="ffT-eb-XpI" userLabel="First Responder" sceneMemberID="firstResponder"/>
101+
</objects>
102+
<point key="canvasLocation" x="1704" y="946"/>
103+
</scene>
53104
<!--Title-->
54105
<scene sceneID="Cld-ce-Mc2">
55106
<objects>

SwiftFlowGitHubBrowser/Routes/Routes.swift

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ import SafariServices
1212
let loginRoute: RouteElementIdentifier = "Login"
1313
let oAuthRoute: RouteElementIdentifier = "OAuth"
1414
let mainViewRoute: RouteElementIdentifier = "Main"
15+
let bookmarkRoute: RouteElementIdentifier = "BookMark"
1516
let repositoryDetailRoute: RouteElementIdentifier = "RepositoryDetail"
1617

1718
let storyboard = UIStoryboard(name: "Main", bundle: nil)
1819

1920
let loginViewControllerIdentifier = "LoginViewController"
2021
let mainViewControllerIdentifier = "MainViewController"
2122
let repositoryDetailControllerIdentifier = "RepositoryDetailViewController"
23+
let bookmarkControllerIdentifier = "BookmarkViewController"
2224

2325
class RootRoutable: Routable {
2426

@@ -113,14 +115,46 @@ class MainViewRoutable: Routable {
113115
func pushRouteSegment(
114116
routeElementIdentifier: RouteElementIdentifier,
115117
completionHandler: RoutingCompletionHandler) -> Routable {
116-
let detailViewController = storyboard.instantiateViewControllerWithIdentifier(repositoryDetailControllerIdentifier)
117-
(self.viewController as! UINavigationController).pushViewController(
118-
detailViewController,
119-
animated: true,
120-
completion: completionHandler
121-
)
122-
123-
return RepositoryDetailRoutable()
118+
if routeElementIdentifier == repositoryDetailRoute {
119+
let detailViewController = storyboard.instantiateViewControllerWithIdentifier(repositoryDetailControllerIdentifier)
120+
(self.viewController as! UINavigationController).pushViewController(
121+
detailViewController,
122+
animated: true,
123+
completion: completionHandler
124+
)
125+
126+
return RepositoryDetailRoutable()
127+
128+
} else if routeElementIdentifier == bookmarkRoute {
129+
let bookmarkViewController = storyboard.instantiateViewControllerWithIdentifier(bookmarkControllerIdentifier)
130+
(self.viewController as! UINavigationController).pushViewController(
131+
bookmarkViewController,
132+
animated: true,
133+
completion: completionHandler
134+
)
135+
136+
return BookmarkRoutable()
137+
}
138+
139+
fatalError("Cannot handle this route change!")
140+
}
141+
142+
func changeRouteSegment(from: RouteElementIdentifier, to: RouteElementIdentifier, completionHandler: RoutingCompletionHandler) -> Routable {
143+
144+
if from == bookmarkRoute && to == repositoryDetailRoute {
145+
(self.viewController as! UINavigationController).popViewController(true) {
146+
let repositoryDetailViewController = storyboard.instantiateViewControllerWithIdentifier(repositoryDetailControllerIdentifier)
147+
(self.viewController as! UINavigationController).pushViewController(
148+
repositoryDetailViewController,
149+
animated: true,
150+
completion: completionHandler
151+
)
152+
}
153+
154+
return BookmarkRoutable()
155+
}
156+
157+
fatalError("Cannot handle this route change!")
124158
}
125159

126160
func popRouteSegment(
@@ -131,10 +165,8 @@ class MainViewRoutable: Routable {
131165
}
132166
}
133167

134-
class RepositoryDetailRoutable: Routable {
135-
136-
}
137-
168+
class RepositoryDetailRoutable: Routable {}
169+
class BookmarkRoutable: Routable {}
138170
class OAuthRoutable: Routable {}
139171

140172
extension UINavigationController {
@@ -147,6 +179,14 @@ extension UINavigationController {
147179
pushViewController(viewController, animated: animated)
148180
CATransaction.commit()
149181
}
182+
183+
func popViewController(animated: Bool, completion: Void -> Void) {
184+
185+
CATransaction.begin()
186+
CATransaction.setCompletionBlock(completion)
187+
popViewControllerAnimated(animated)
188+
CATransaction.commit()
189+
}
150190

151191
}
152192

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//
2+
// BookmarkViewController.swift
3+
// SwiftFlowGitHubBrowser
4+
//
5+
// Created by Benji Encz on 3/12/16.
6+
// Copyright © 2016 Benji Encz. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import ReSwift
11+
import ReSwiftRouter
12+
import OctoKit
13+
import ListKit
14+
15+
class BookmarkTableViewCell: UITableViewCell, ListKitCellProtocol {
16+
var model: Bookmark? {
17+
didSet {
18+
if let repository = model?.routeSpecificData as? Repository {
19+
self.textLabel!.text = repository.name ?? ""
20+
}
21+
}
22+
}
23+
}
24+
25+
class BookmarkViewController: UIViewController, StoreSubscriber {
26+
27+
@IBOutlet var tableView: UITableView!
28+
29+
var dataSource: ArrayDataSource<BookmarkTableViewCell, Bookmark>?
30+
31+
override func viewWillAppear(animated: Bool) {
32+
super.viewWillAppear(animated)
33+
34+
self.dataSource = ArrayDataSource(array: [], cellType: BookmarkTableViewCell.self)
35+
tableView.dataSource = dataSource
36+
tableView.delegate = self
37+
38+
// Subscribe after other setup is complete
39+
store.subscribe(self) { state in
40+
state.bookmarks
41+
}
42+
}
43+
44+
override func viewWillDisappear(animated: Bool) {
45+
super.viewWillDisappear(animated)
46+
47+
store.unsubscribe(self)
48+
}
49+
50+
func newState(state: [Bookmark]) {
51+
dataSource?.array = state
52+
tableView.reloadData()
53+
}
54+
55+
}
56+
57+
//MARK: UITableViewDelegate
58+
59+
extension BookmarkViewController: UITableViewDelegate {
60+
61+
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
62+
let selectedBookmark = self.dataSource!.array[indexPath.row]
63+
let routeAction = ReSwiftRouter.SetRouteAction(selectedBookmark.route)
64+
let setDataAction = ReSwiftRouter.SetRouteSpecificData(route:
65+
selectedBookmark.route,
66+
data: selectedBookmark.routeSpecificData)
67+
68+
store.dispatch(setDataAction)
69+
store.dispatch(routeAction)
70+
}
71+
72+
}

SwiftFlowGitHubBrowser/ViewControllers/MainViewController.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class MainViewController: UIViewController, StoreSubscriber {
4545
}
4646

4747
override func viewWillDisappear(animated: Bool) {
48+
super.viewWillDisappear(animated)
49+
4850
store.unsubscribe(self)
4951
}
5052

@@ -57,6 +59,10 @@ class MainViewController: UIViewController, StoreSubscriber {
5759
}
5860
}
5961

62+
@IBAction func bookmarkButtonTapped(sender: AnyObject) {
63+
let newRoute = [mainViewRoute, bookmarkRoute]
64+
store.dispatch(ReSwiftRouter.SetRouteAction(newRoute))
65+
}
6066
}
6167

6268
//MARK: UITableViewDelegate

0 commit comments

Comments
 (0)