[ADD] Bookmarks per user account (#738)

This commit is contained in:
Rizwan Mohamed Ibrahim
2017-10-27 20:25:22 +05:30
committed by Ryan Nystrom
parent 908463a31a
commit 199ce48047
6 changed files with 98 additions and 54 deletions

View File

@@ -9,26 +9,33 @@
import Foundation
final class BookmarksStore {
static let shared = BookmarksStore()
private let archivePath: String = {
return FileManager.default
.urls(for: .documentDirectory, in: .userDomainMask)
// crash intentionally on startup if doesn't exist
.first!
.appendingPathComponent("bookmarks")
.path
}()
private var _bookmarks: Set<BookmarkModel>
private let fileManager = FileManager.default
private var documentDirectory: FileManager.SearchPathDirectory {
return .documentDirectory
}
private var archivePath: String {
guard let path = NSSearchPathForDirectoriesInDomains(documentDirectory, .userDomainMask, true).first else {
fatalError("App document directory cannot be found")
}
let folder = URL(fileURLWithPath: path).appendingPathComponent("com.whoisryannystrom.freetime.bookmarks")
if !fileManager.fileExists(atPath: folder.path) {
try? fileManager.createDirectory(at: folder, withIntermediateDirectories: false, attributes: nil)
}
return folder.appendingPathComponent(token).path
}
private var token: String
private var _bookmarks: Set<BookmarkModel> = []
// MARK: Init
init() {
if let bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: archivePath) as? Set<BookmarkModel> {
_bookmarks = bookmarks
} else {
_bookmarks = []
}
init(_ userToken: String?) {
guard let userToken = userToken else { fatalError() }
token = userToken
refresh()
}
// MARK: Public API
@@ -53,13 +60,31 @@ final class BookmarksStore {
}
var bookmarks: [BookmarkModel] {
refresh()
return Array(_bookmarks)
}
// MARK: Private API
func archive() {
NSKeyedArchiver.archiveRootObject(_bookmarks, toFile: self.archivePath)
func refresh() {
if let bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: archivePath) as? Set<BookmarkModel> {
_bookmarks = bookmarks
}
}
func archive() {
NSKeyedArchiver.archiveRootObject(_bookmarks, toFile: archivePath)
}
func clearStorage() {
do {
try FileManager.default.removeItem(atPath: archivePath)
} catch {
print("Can not delete bookmarks file")
}
}
var bookmarkPath: String {
return archivePath
}
}

View File

@@ -17,7 +17,7 @@ TabNavRootViewControllerType {
private let client: GithubClient
private let cellIdentifier = "bookmark_cell"
private let bookmarkStore = BookmarksStore.shared
private let bookmarkStore:BookmarksStore
private var searchController: UISearchController {
let controller = UISearchController(searchResultsController: nil)
@@ -39,6 +39,8 @@ TabNavRootViewControllerType {
init(client: GithubClient) {
self.client = client
self.bookmarkStore = BookmarksStore(client.userSession?.token)
super.init(nibName: nil, bundle: nil)
}

View File

@@ -282,7 +282,16 @@ IssueCommentSectionControllerDelegate {
title: current.title.attributedText.string
)
return AlertAction.bookmark(bookmarkModel)
let store = BookmarksStore(client.userSession?.token)
let isNewBookmark = !store.contains(bookmark: bookmarkModel)
return AlertAction.toggleBookmark(isNewBookmark) { _ in
if isNewBookmark {
store.add(bookmark: bookmarkModel)
} else {
store.remove(bookmark: bookmarkModel)
}
Haptic.triggerNotification(.success)
}
}
@objc

View File

@@ -112,7 +112,17 @@ NewIssueTableViewControllerDelegate {
owner: repo.owner,
hasIssueEnabled: repo.hasIssuesEnabled
)
return AlertAction.bookmark(bookmarkModel)
let store = BookmarksStore(client.userSession?.token)
let isNewBookmark = !store.contains(bookmark: bookmarkModel)
return AlertAction.toggleBookmark(isNewBookmark) { _ in
if isNewBookmark {
store.add(bookmark: bookmarkModel)
}
else {
store.remove(bookmark: bookmarkModel)
}
Haptic.triggerNotification(.success)
}
}
@objc

View File

@@ -138,19 +138,8 @@ struct AlertAction {
return UIAlertAction(title: Constants.Strings.clearAll, style: .destructive, handler: handler)
}
static func bookmark(_ bookmark: BookmarkModel) -> UIAlertAction {
let isNewBookmark = !BookmarksStore.shared.contains(bookmark: bookmark)
static func toggleBookmark(_ isNewBookmark: Bool, handler: AlertActionBlock? = nil) -> UIAlertAction {
let title = isNewBookmark ? Constants.Strings.bookmark : Constants.Strings.removeBookmark
return UIAlertAction(
title: title,
style: isNewBookmark ? .default : .destructive
) { _ in
if isNewBookmark {
BookmarksStore.shared.add(bookmark: bookmark)
} else {
BookmarksStore.shared.remove(bookmark: bookmark)
}
Haptic.triggerNotification(.success)
}
return UIAlertAction(title: title, style: isNewBookmark ? .default : .destructive, handler: handler)
}
}

View File

@@ -10,58 +10,67 @@ import XCTest
@testable import Freetime
final class BookmarkStoreTests: XCTestCase {
var store: BookmarksStore!
override func setUp() {
super.setUp()
store = BookmarksStore("user_token")
store.clear() // for a clean start
}
override func tearDown() {
super.tearDown()
BookmarksStore.shared.clear()
store.clear()
}
func test_addBookMark() {
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
BookmarksStore.shared.add(bookmark: b1)
store.add(bookmark: b1)
XCTAssert(BookmarksStore.shared.bookmarks.count == 1)
XCTAssert(BookmarksStore.shared.bookmarks.first == b1)
XCTAssert(store.bookmarks.count == 1)
XCTAssert(store.bookmarks.first == b1)
}
func test_duplicateBookmarks() {
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
let b2 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
BookmarksStore.shared.add(bookmark: b1)
BookmarksStore.shared.add(bookmark: b2)
store.add(bookmark: b1)
store.add(bookmark: b2)
XCTAssert(BookmarksStore.shared.bookmarks.count == 1)
XCTAssert(store.bookmarks.count == 1)
}
func test_clearBookmarks() {
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
BookmarksStore.shared.add(bookmark: b1)
BookmarksStore.shared.clear()
store.add(bookmark: b1)
store.clear()
XCTAssert(BookmarksStore.shared.bookmarks.count == 0)
XCTAssert(store.bookmarks.isEmpty)
}
func test_removeBookmark() {
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
BookmarksStore.shared.add(bookmark: b1)
BookmarksStore.shared.remove(bookmark: b1)
store.add(bookmark: b1)
store.remove(bookmark: b1)
XCTAssert(BookmarksStore.shared.bookmarks.count == 0)
XCTAssert(store.bookmarks.count == 0)
}
func test_containsBookmark() {
func test_bookmarksFromDifferentUser() {
let b1 = BookmarkModel(type: .repo, name: "GitHawk", owner: "rizwankce")
BookmarksStore.shared.add(bookmark: b1)
XCTAssert(BookmarksStore.shared.contains(bookmark: b1))
let store1 = BookmarksStore("user_token1")
let store2 = BookmarksStore("user_token2")
store1.add(bookmark: b1)
store2.add(bookmark: b1)
XCTAssert(store1.bookmarks.count == 1)
XCTAssert(store2.bookmarks.count == 1)
XCTAssert(store1.bookmarkPath != store2.bookmarkPath)
}
}