Move AccountManager to Account.framework.

This commit is contained in:
Brent Simmons
2017-09-17 12:20:32 -07:00
parent e78fc0d696
commit 121fbf3c27
6 changed files with 23 additions and 21 deletions

View File

@@ -34,7 +34,8 @@ public final class Account: DisplayNameProvider, Hashable {
var topLevelObjects = [AnyObject]()
var feedIDDictionary = [String: Feed]()
var username: String?
var refreshInProgress = false
static public let accounts = [String: Account]()
init?(dataFolder: String, settingsFile: String, type: AccountType, accountID: String) {

View File

@@ -20,6 +20,7 @@
846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */; };
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */; };
846E77521F6EFDFB00A165E2 /* Feed+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77511F6EFDFB00A165E2 /* Feed+Account.swift */; };
846E77541F6F00E300A165E2 /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846E77531F6F00E300A165E2 /* AccountManager.swift */; };
848935001F62484F00CEBD24 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848934F61F62484F00CEBD24 /* Account.framework */; };
848935051F62485000CEBD24 /* AccountTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935041F62485000CEBD24 /* AccountTests.swift */; };
/* End PBXBuildFile section */
@@ -110,6 +111,7 @@
8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountDelegate.swift; sourceTree = "<group>"; };
8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountRefresher.swift; sourceTree = "<group>"; };
846E77511F6EFDFB00A165E2 /* Feed+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Feed+Account.swift"; sourceTree = "<group>"; };
846E77531F6F00E300A165E2 /* AccountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = "<group>"; };
848934F61F62484F00CEBD24 /* Account.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Account.framework; sourceTree = BUILT_PRODUCTS_DIR; };
848934FA1F62484F00CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
848934FF1F62484F00CEBD24 /* AccountTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccountTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -211,6 +213,7 @@
848934EC1F62484F00CEBD24 = {
isa = PBXGroup;
children = (
846E77531F6F00E300A165E2 /* AccountManager.swift */,
848935101F62486800CEBD24 /* Account.swift */,
841974241F6DDCE4006346C4 /* AccountDelegate.swift */,
841974001F6DD1EC006346C4 /* Folder.swift */,
@@ -441,6 +444,7 @@
846E77451F6EF9B900A165E2 /* Container.swift in Sources */,
8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */,
841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */,
846E77541F6F00E300A165E2 /* AccountManager.swift in Sources */,
846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */,
841974011F6DD1EC006346C4 /* Folder.swift in Sources */,
846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */,

View File

@@ -0,0 +1,223 @@
//
// AccountManager.swift
// Evergreen
//
// Created by Brent Simmons on 7/18/15.
// Copyright © 2015 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import RSCore
import Data
let AccountsDidChangeNotification = "AccountsDidChangeNotification"
private let localAccountFolderName = "OnMyMac"
private let localAccountIdentifier = "OnMyMac"
final class AccountManager: UnreadCountProvider {
static let sharedInstance = AccountManager()
private let accountsFolder = RSDataSubfolder(nil, "Accounts")!
private var accountsDictionary = [String: Account]()
let localAccount: Account
var unreadCount = 0 {
didSet {
postUnreadCountDidChangeNotification()
}
}
var accounts: [Account] {
get {
return Array(accountsDictionary.values)
}
}
var sortedAccounts: [Account] {
get {
return accountsSortedByName()
}
}
var refreshInProgress: Bool {
get {
for oneAccount in accountsDictionary.values {
if oneAccount.refreshInProgress {
return true
}
}
return false
}
}
init() {
// The local "On My Mac" account must always exist, even if it's empty.
let localAccountFolder = (accountsFolder as NSString).appendingPathComponent("OnMyMac")
do {
try FileManager.default.createDirectory(atPath: localAccountFolder, withIntermediateDirectories: true, attributes: nil)
}
catch {
assertionFailure("Could not create folder for OnMyMac account.")
abort()
}
let localAccountSettingsFile = accountFilePathWithFolder(localAccountFolder)
localAccount = Account(dataFolder: localAccountFolder, settingsFile: localAccountSettingsFile, type: .onMyMac, accountID: localAccountIdentifier)!
accountsDictionary[localAccount.accountID] = localAccount
readNonLocalAccountsFromDisk()
NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil)
}
// MARK: API
func existingAccountWithID(_ accountID: String) -> Account? {
return accountsDictionary[accountID]
}
func refreshAll() {
accounts.forEach { (account) in
account.refreshAll()
}
}
func anyAccountHasAtLeastOneFeed() -> Bool {
for account in accounts {
if account.hasAtLeastOneFeed() {
return true
}
}
return false
}
func anyAccountHasFeedWithURL(_ urlString: String) -> Bool {
for account in accounts {
if let _ = account.existingFeed(withURL: urlString) {
return true
}
}
return false
}
// MARK: UnreadCountProvider
func updateUnreadCount() {
let updatedUnreadCount = calculateUnreadCount(accounts)
if updatedUnreadCount != unreadCount {
unreadCount = updatedUnreadCount
}
}
// MARK: Notifications
@objc dynamic func unreadCountDidChange(_ notification: Notification) {
guard let _ = notification.object as? Account else {
return
}
updateUnreadCount()
}
// MARK: Private
private func createAccount(_ accountSpecifier: AccountSpecifier) -> Account? {
return nil
}
private func createAccount(_ filename: String) -> Account? {
let folderPath = (accountsFolder as NSString).appendingPathComponent(filename)
if let accountSpecifier = AccountSpecifier(folderPath: folderPath) {
return createAccount(accountSpecifier)
}
return nil
}
private func readNonLocalAccountsFromDisk() {
var filenames: [String]?
do {
filenames = try FileManager.default.contentsOfDirectory(atPath: accountsFolder)
}
catch {
print("Error reading Accounts folder: \(error)")
return
}
filenames?.forEach { (oneFilename) in
guard oneFilename != localAccountFolderName else {
return
}
if let oneAccount = createAccount(oneFilename) {
accountsDictionary[oneAccount.accountID] = oneAccount
}
}
}
private func accountsSortedByName() -> [Account] {
// LocalAccount is first.
return accounts.sorted { (account1, account2) -> Bool in
if account1 === localAccount {
return true
}
if account2 === localAccount {
return false
}
//TODO: Use localizedCaseInsensitiveCompare:
return account1.nameForDisplay < account2.nameForDisplay
}
}
}
private let accountDataFileName = "AccountData.plist"
private func accountFilePathWithFolder(_ folderPath: String) -> String {
return NSString(string: folderPath).appendingPathComponent(accountDataFileName)
}
private struct AccountSpecifier {
let type: String
let identifier: String
let folderPath: String
let folderName: String
let dataFilePath: String
init?(folderPath: String) {
self.folderPath = folderPath
self.folderName = NSString(string: folderPath).lastPathComponent
let nameComponents = self.folderName.components(separatedBy: "-")
let satisfyCompilerFolderName = self.folderName
assert(nameComponents.count == 2, "Cant determine account info from \(satisfyCompilerFolderName)")
if nameComponents.count != 2 {
return nil
}
self.type = nameComponents[0]
self.identifier = nameComponents[1]
self.dataFilePath = accountFilePathWithFolder(self.folderPath)
}
}

View File

@@ -13,7 +13,7 @@ public extension Feed {
var account: Account? {
get {
return Account.existingAccountWithID(accountID)
return AccountManager.sharedInstance.existingAccountWithID(accountID)
}
}
}