diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 96606a0c3..720651296 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -33,11 +33,16 @@ public final class Account: DisplayNameProvider, Hashable { let settingsFile: String let dataFolder: String let database: Database - var topLevelObjects = [Any]() + var topLevelObjects = [AnyObject]() var feedIDDictionary = [String: Feed]() var username: String? var refreshInProgress = false - var supportsSubFolders; + + var supportsSubFolders: Bool { + get { + return delegate.supportsSubFolders + } + } init?(dataFolder: String, settingsFile: String, type: AccountType, accountID: String) { @@ -129,45 +134,34 @@ public final class Account: DisplayNameProvider, Hashable { extension Account { - public func plist() -> AnyObject? { - return nil // TODO - } - private struct Key { static let children = "children" } func pullObjectsFromDisk() { - guard let d = NSDictionary(contentsOf: settingsFile) as? [String: Any] else { + let settingsFileURL = URL(fileURLWithPath: settingsFile) + guard let d = NSDictionary(contentsOf: settingsFileURL) as? [String: Any] else { return } - guard let childrenArray = d[Key.children] as? [Any] else { + guard let childrenArray = d[Key.children] as? [[String: Any]] else { return } topLevelObjects = objects(with: childrenArray) updateFeedIDDictionary() } - func objects(with diskObjects: [[String: Any]]) -> [Any] { + func objects(with diskObjects: [[String: Any]]) -> [AnyObject] { return diskObjects.flatMap { object(with: $0) } } - func object(with diskObject: Any) -> Any { + func object(with diskObject: [String: Any]) -> AnyObject? { - guard let d = diskObject as? [String: Any] else { - return nil - } - if diskObjectIsFeed(diskObject) { + if Feed.isFeedDictionary(diskObject) { return Feed(accountID: accountID, dictionary: diskObject) } - return Folder(accountID: accountID, dictionary: diskObject) - } - - private func diskObjectIsFeed(_ diskObject: [String: Any]) -> Bool { - - return d[Feed.Key.url] != nil + return Folder(account: self, dictionary: diskObject) } } diff --git a/Frameworks/Account/AccountDelegate.swift b/Frameworks/Account/AccountDelegate.swift index 518390c6e..61b5d5ce0 100644 --- a/Frameworks/Account/AccountDelegate.swift +++ b/Frameworks/Account/AccountDelegate.swift @@ -10,6 +10,9 @@ import Foundation public protocol AccountDelegate { + // Local account does not; some synced accounts might. + var supportsSubFolders: Bool { get } + func refreshAll(for account: Account) } diff --git a/Frameworks/Account/Container/Folder+Container.swift b/Frameworks/Account/Container/Folder+Container.swift index 3532bdaa9..89f219ab4 100644 --- a/Frameworks/Account/Container/Folder+Container.swift +++ b/Frameworks/Account/Container/Folder+Container.swift @@ -14,7 +14,7 @@ extension Folder: Container { public func flattenedFeeds() -> Set { var feeds = Set() - for oneChild in childObjects { + for oneChild in children { if let oneFeed = oneChild as? Feed { feeds.insert(oneFeed) } @@ -27,14 +27,12 @@ extension Folder: Container { public func isChild(_ obj: AnyObject) -> Bool { - return childObjects.contains(where: { (oneObject) -> Bool in - return oneObject === obj - }) + return children.contains { $0 === obj } } public func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool { - for oneObject in childObjects { + for oneObject in children { if let oneContainer = oneObject as? Container { if visitBlock(oneObject) { diff --git a/Frameworks/Account/Folder.swift b/Frameworks/Account/Folder.swift index 280db75bc..22aa8a3c3 100644 --- a/Frameworks/Account/Folder.swift +++ b/Frameworks/Account/Folder.swift @@ -12,14 +12,15 @@ import Data public final class Folder: DisplayNameProvider, UnreadCountProvider { public let account: Account - var children = [Any]() + var children = [AnyObject]() var name: String? + static let untitledName = NSLocalizedString("Untitled ƒ", comment: "Folder name") // MARK: - DisplayNameProvider public var nameForDisplay: String { get { - return name ?? NSLocalizedString("Untitled ƒ", comment: "Folder name") + return name ?? Folder.untitledName } } @@ -47,14 +48,15 @@ public final class Folder: DisplayNameProvider, UnreadCountProvider { struct Key { static let name = "name" static let unreadCount = "unreadCount" - static let childrenKey = "children" + static let children = "children" } convenience public init?(account: Account, dictionary: [String: Any]) { - self.name = dictionary[Key.name] as? String - - if let childrenArray = dictionary[Key.childrenKey] as? [String: Any] { + let name = dictionary[Key.name] as? String ?? Folder.untitledName + self.init(account: account, name: name) + + if let childrenArray = dictionary[Key.children] as? [[String: Any]] { self.children = account.objects(with: childrenArray) } @@ -74,20 +76,25 @@ public final class Folder: DisplayNameProvider, UnreadCountProvider { d[Key.unreadCount] = unreadCount } - // TODO: children as dictionaries - use method in Account - - let childObjects = children.flatMap { (child) -> [String: Any]? in if let feed = child as? Feed { - + return feed.dictionary } + if let folder = child as? Folder, account.supportsSubFolders { + return folder.dictionary + } + assertionFailure("Expected a feed or a folder."); + return nil + } + + if !childObjects.isEmpty { + d[Key.children] = childObjects } return d } } - } extension Folder: OPMLRepresentable { diff --git a/Frameworks/Account/Local/LocalAccountDelegate.swift b/Frameworks/Account/Local/LocalAccountDelegate.swift index 578811743..f9e4ef010 100644 --- a/Frameworks/Account/Local/LocalAccountDelegate.swift +++ b/Frameworks/Account/Local/LocalAccountDelegate.swift @@ -10,6 +10,8 @@ import Foundation struct LocalAccountDelegate: AccountDelegate { + let supportsSubFolders = false + func refreshAll(for account: Account) { // TODO diff --git a/Frameworks/Data/Feed.swift b/Frameworks/Data/Feed.swift index b69f290dc..4d800beff 100644 --- a/Frameworks/Data/Feed.swift +++ b/Frameworks/Data/Feed.swift @@ -52,7 +52,7 @@ public final class Feed: DisplayNameProvider, UnreadCountProvider, Hashable { // MARK: - Disk Dictionary - struct Key { + private struct Key { static let url = "url" static let feedID = "feedID" static let homePageURL = "homePageURL" @@ -84,6 +84,11 @@ public final class Feed: DisplayNameProvider, UnreadCountProvider, Hashable { } } + public static func isFeedDictionary(_ d: [String: Any]) -> Bool { + + return d[Key.url] != nil + } + public var dictionary: [String: Any] { get { var d = [String: Any]() @@ -106,7 +111,7 @@ public final class Feed: DisplayNameProvider, UnreadCountProvider, Hashable { d[Key.unreadCount] = unreadCount } if let conditionalGetInfo = conditionalGetInfo { - d[Key.conditionalGetInfo] = conditionalGetInfo.dOictionary + d[Key.conditionalGetInfo] = conditionalGetInfo.dictionary } return d