diff --git a/Frameworks/Account/Account+OPMLRepresentable.swift b/Frameworks/Account/Account+OPMLRepresentable.swift deleted file mode 100644 index e021058bc..000000000 --- a/Frameworks/Account/Account+OPMLRepresentable.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// Account+OPMLRepresentable.swift -// DataModel -// -// Created by Brent Simmons on 7/2/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -extension Account: OPMLRepresentable { - - public func OPMLString(indentLevel: Int) -> String { - - var s = "" - for oneObject in topLevelObjects { - if let oneOPMLObject = oneObject as? OPMLRepresentable { - s += oneOPMLObject.OPMLString(indentLevel: indentLevel + 1) - } - } - return s - } -} diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index e899f45ab..fe1756c21 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -8,9 +8,7 @@ import Foundation import RSCore - -// Various model objects include an accountInfo property that Accounts can use to store extra data. -public typealias AccountInfo = [String: Any] +import Data public enum AccountType: Int { @@ -53,57 +51,6 @@ public final class Account: Hashable { } } -extension Account: Container { - - public func hasAtLeastOneFeed() -> Bool { - - return !feedIDDictionary.isEmpty - } - - public func flattenedFeeds() -> Set { - - return Set(feedIDDictionary.values) - } - - public func existingFeed(with feedID: String) -> Feed? { - - return feedIDDictionary[feedID] - } - - public func canAddItem(_ item: AnyObject) -> Bool { - - return delegate.canAddItem(item, toContainer: self) - } - - public func isChild(_ obj: AnyObject) -> Bool { - - return topLevelObjects.contains(where: { (oneObject) -> Bool in - return oneObject === obj - }) - } - - public func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool { - - for oneObject in topLevelObjects { - - if let oneContainer = oneObject as? Container { - if visitBlock(oneObject) { - return true - } - if recurse && oneContainer.visitObjects(recurse, visitBlock) { - return true - } - } - else { - if visitBlock(oneObject) { - return true - } - } - } - - return false - } -} extension Account: PlistProvider { @@ -112,3 +59,16 @@ extension Account: PlistProvider { } } +extension Account: OPMLRepresentable { + + public func OPMLString(indentLevel: Int) -> String { + + var s = "" + for oneObject in topLevelObjects { + if let oneOPMLObject = oneObject as? OPMLRepresentable { + s += oneOPMLObject.OPMLString(indentLevel: indentLevel + 1) + } + } + return s + } +} diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index a9e0d6afe..54531ce56 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -7,11 +7,82 @@ objects = { /* Begin PBXBuildFile section */ + 841973FD1F6DD1B7006346C4 /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973E51F6DD195006346C4 /* Data.framework */; }; + 841973FE1F6DD1BC006346C4 /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973EF1F6DD19E006346C4 /* RSCore.framework */; }; + 841973FF1F6DD1C5006346C4 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973FA1F6DD1AC006346C4 /* RSParser.framework */; }; + 841974011F6DD1EC006346C4 /* Folder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974001F6DD1EC006346C4 /* Folder.swift */; }; + 841974181F6DD535006346C4 /* Folder+Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974171F6DD535006346C4 /* Folder+Container.swift */; }; + 8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974191F6DD583006346C4 /* Account+Container.swift */; }; + 8469F8171F6DD0AD0084783E /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8401A17D1F6DC388002B1BE2 /* Database.framework */; }; + 8469F81C1F6DD15E0084783E /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935101F62486800CEBD24 /* Account.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 */ /* Begin PBXContainerItemProxy section */ + 8401A17C1F6DC388002B1BE2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 844BEE371F0AB3AA004AB7CD; + remoteInfo = Database; + }; + 8401A17E1F6DC388002B1BE2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 844BEE401F0AB3AB004AB7CD; + remoteInfo = DatabaseTests; + }; + 841973E41F6DD195006346C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841973DF1F6DD194006346C4 /* Data.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 844BEE5B1F0AB3C8004AB7CD; + remoteInfo = Data; + }; + 841973E61F6DD195006346C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841973DF1F6DD194006346C4 /* Data.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 844BEE641F0AB3C9004AB7CD; + remoteInfo = DataTests; + }; + 841973EE1F6DD19E006346C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84CFF4F41AC3C69700CEA6C8; + remoteInfo = RSCore; + }; + 841973F01F6DD19E006346C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84CFF4FF1AC3C69700CEA6C8; + remoteInfo = RSCoreTests; + }; + 841973F21F6DD19E006346C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 842DD7BC1E14993900E061EB; + remoteInfo = RSCoreiOS; + }; + 841973F91F6DD1AC006346C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84FF5F841EFA285800C15A01; + remoteInfo = RSParser; + }; + 841973FB1F6DD1AC006346C4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84FF5F8D1EFA285800C15A01; + remoteInfo = RSParserTests; + }; 848935011F62484F00CEBD24 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 848934ED1F62484F00CEBD24 /* Project object */; @@ -22,13 +93,20 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Database.xcodeproj; path = ../Database/Database.xcodeproj; sourceTree = ""; }; + 841973DF1F6DD194006346C4 /* Data.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Data.xcodeproj; path = ../Data/Data.xcodeproj; sourceTree = ""; }; + 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; + 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = ../RSParser/RSParser.xcodeproj; sourceTree = ""; }; + 841974001F6DD1EC006346C4 /* Folder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = ""; }; + 8419740D1F6DD25F006346C4 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; + 841974171F6DD535006346C4 /* Folder+Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Container.swift"; sourceTree = ""; }; + 841974191F6DD583006346C4 /* Account+Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Container.swift"; sourceTree = ""; }; 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 = ""; }; 848934FF1F62484F00CEBD24 /* AccountTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AccountTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 848935041F62485000CEBD24 /* AccountTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTests.swift; sourceTree = ""; }; 848935061F62485000CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 848935101F62486800CEBD24 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; - 848935201F62498B00CEBD24 /* Account+OPMLRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+OPMLRepresentable.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -36,6 +114,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 841973FF1F6DD1C5006346C4 /* RSParser.framework in Frameworks */, + 841973FE1F6DD1BC006346C4 /* RSCore.framework in Frameworks */, + 841973FD1F6DD1B7006346C4 /* Data.framework in Frameworks */, + 8469F8171F6DD0AD0084783E /* Database.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -50,11 +132,71 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 8401A1731F6DC387002B1BE2 /* Products */ = { + isa = PBXGroup; + children = ( + 8401A17D1F6DC388002B1BE2 /* Database.framework */, + 8401A17F1F6DC388002B1BE2 /* DatabaseTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 841973E01F6DD194006346C4 /* Products */ = { + isa = PBXGroup; + children = ( + 841973E51F6DD195006346C4 /* Data.framework */, + 841973E71F6DD195006346C4 /* DataTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 841973E91F6DD19E006346C4 /* Products */ = { + isa = PBXGroup; + children = ( + 841973EF1F6DD19E006346C4 /* RSCore.framework */, + 841973F11F6DD19E006346C4 /* RSCoreTests.xctest */, + 841973F31F6DD19E006346C4 /* RSCore.framework */, + ); + name = Products; + sourceTree = ""; + }; + 841973F51F6DD1AC006346C4 /* Products */ = { + isa = PBXGroup; + children = ( + 841973FA1F6DD1AC006346C4 /* RSParser.framework */, + 841973FC1F6DD1AC006346C4 /* RSParserTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 841974141F6DD4FF006346C4 /* Container */ = { + isa = PBXGroup; + children = ( + 8419740D1F6DD25F006346C4 /* Container.swift */, + 841974191F6DD583006346C4 /* Account+Container.swift */, + 841974171F6DD535006346C4 /* Folder+Container.swift */, + ); + path = Container; + sourceTree = ""; + }; + 8469F80F1F6DC3C10084783E /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */, + 841973DF1F6DD194006346C4 /* Data.xcodeproj */, + 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */, + 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */, + ); + name = Frameworks; + sourceTree = ""; + }; 848934EC1F62484F00CEBD24 = { isa = PBXGroup; children = ( 848935101F62486800CEBD24 /* Account.swift */, - 848935201F62498B00CEBD24 /* Account+OPMLRepresentable.swift */, + 841974001F6DD1EC006346C4 /* Folder.swift */, + 841974141F6DD4FF006346C4 /* Container */, + 8469F80F1F6DC3C10084783E /* Frameworks */, 848934FA1F62484F00CEBD24 /* Info.plist */, 848935031F62484F00CEBD24 /* AccountTests */, 848934F71F62484F00CEBD24 /* Products */, @@ -159,6 +301,24 @@ mainGroup = 848934EC1F62484F00CEBD24; productRefGroup = 848934F71F62484F00CEBD24 /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 841973E01F6DD194006346C4 /* Products */; + ProjectRef = 841973DF1F6DD194006346C4 /* Data.xcodeproj */; + }, + { + ProductGroup = 8401A1731F6DC387002B1BE2 /* Products */; + ProjectRef = 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */; + }, + { + ProductGroup = 841973E91F6DD19E006346C4 /* Products */; + ProjectRef = 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */; + }, + { + ProductGroup = 841973F51F6DD1AC006346C4 /* Products */; + ProjectRef = 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 848934F51F62484F00CEBD24 /* Account */, @@ -167,6 +327,72 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 8401A17D1F6DC388002B1BE2 /* Database.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Database.framework; + remoteRef = 8401A17C1F6DC388002B1BE2 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 8401A17F1F6DC388002B1BE2 /* DatabaseTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = DatabaseTests.xctest; + remoteRef = 8401A17E1F6DC388002B1BE2 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841973E51F6DD195006346C4 /* Data.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Data.framework; + remoteRef = 841973E41F6DD195006346C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841973E71F6DD195006346C4 /* DataTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = DataTests.xctest; + remoteRef = 841973E61F6DD195006346C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841973EF1F6DD19E006346C4 /* RSCore.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSCore.framework; + remoteRef = 841973EE1F6DD19E006346C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841973F11F6DD19E006346C4 /* RSCoreTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSCoreTests.xctest; + remoteRef = 841973F01F6DD19E006346C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841973F31F6DD19E006346C4 /* RSCore.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSCore.framework; + remoteRef = 841973F21F6DD19E006346C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841973FA1F6DD1AC006346C4 /* RSParser.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSParser.framework; + remoteRef = 841973F91F6DD1AC006346C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841973FC1F6DD1AC006346C4 /* RSParserTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSParserTests.xctest; + remoteRef = 841973FB1F6DD1AC006346C4 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 848934F41F62484F00CEBD24 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -189,6 +415,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8469F81C1F6DD15E0084783E /* Account.swift in Sources */, + 8419741A1F6DD583006346C4 /* Account+Container.swift in Sources */, + 841974011F6DD1EC006346C4 /* Folder.swift in Sources */, + 841974181F6DD535006346C4 /* Folder+Container.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -336,7 +566,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - INFOPLIST_FILE = Account/Info.plist; + INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Account; @@ -360,7 +590,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - INFOPLIST_FILE = Account/Info.plist; + INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Account; @@ -373,6 +603,7 @@ 8489350E1F62485000CEBD24 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = M8L2WTLA8W; @@ -387,6 +618,7 @@ 8489350F1F62485000CEBD24 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; DEVELOPMENT_TEAM = M8L2WTLA8W; diff --git a/Frameworks/Account/Container/Account+Container.swift b/Frameworks/Account/Container/Account+Container.swift new file mode 100644 index 000000000..d9c9ce2f0 --- /dev/null +++ b/Frameworks/Account/Container/Account+Container.swift @@ -0,0 +1,61 @@ +// +// Account+Container.swift +// Account +// +// Created by Brent Simmons on 9/16/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +extension Account: Container { + + public func hasAtLeastOneFeed() -> Bool { + + return !feedIDDictionary.isEmpty + } + + public func flattenedFeeds() -> Set { + + return Set(feedIDDictionary.values) + } + + public func existingFeed(with feedID: String) -> Feed? { + + return feedIDDictionary[feedID] + } + + public func canAddItem(_ item: AnyObject) -> Bool { + + return delegate.canAddItem(item, toContainer: self) + } + + public func isChild(_ obj: AnyObject) -> Bool { + + return topLevelObjects.contains(where: { (oneObject) -> Bool in + return oneObject === obj + }) + } + + public func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool { + + for oneObject in topLevelObjects { + + if let oneContainer = oneObject as? Container { + if visitBlock(oneObject) { + return true + } + if recurse && oneContainer.visitObjects(recurse, visitBlock) { + return true + } + } + else { + if visitBlock(oneObject) { + return true + } + } + } + + return false + } +} diff --git a/Frameworks/Data/Protocols/Container.swift b/Frameworks/Account/Container/Container.swift similarity index 100% rename from Frameworks/Data/Protocols/Container.swift rename to Frameworks/Account/Container/Container.swift diff --git a/Frameworks/Account/Container/Folder+Container.swift b/Frameworks/Account/Container/Folder+Container.swift new file mode 100644 index 000000000..93fa7981d --- /dev/null +++ b/Frameworks/Account/Container/Folder+Container.swift @@ -0,0 +1,55 @@ +// +// Folder+Container.swift +// Account +// +// Created by Brent Simmons on 9/16/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +extension Folder: Container { + + public func flattenedFeeds() -> Set { + + var feeds = Set() + for oneChild in childObjects { + if let oneFeed = oneChild as? Feed { + feeds.insert(oneFeed) + } + else if let oneContainer = oneChild as? Container { + feeds.formUnion(oneContainer.flattenedFeeds()) + } + } + return feeds + } + + public func isChild(_ obj: AnyObject) -> Bool { + + return childObjects.contains(where: { (oneObject) -> Bool in + return oneObject === obj + }) + } + + public func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool { + + for oneObject in childObjects { + + if let oneContainer = oneObject as? Container { + if visitBlock(oneObject) { + return true + } + if recurse && oneContainer.visitObjects(recurse, visitBlock) { + return true + } + } + else { + if visitBlock(oneObject) { + return true + } + } + } + return false + } +} + diff --git a/Frameworks/Account/Folder.swift b/Frameworks/Account/Folder.swift new file mode 100644 index 000000000..f2baf62d0 --- /dev/null +++ b/Frameworks/Account/Folder.swift @@ -0,0 +1,99 @@ +// +// Folder.swift +// DataModel +// +// Created by Brent Simmons on 7/1/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import Foundation +import Data + +public final class Folder: DisplayNameProvider, UnreadCountProvider { + + public let accountID: String + var childObjects = [AnyObject]() + + // MARK: - DisplayNameProvider + + public var nameForDisplay: String + + // MARK: - UnreadCountProvider + + public var unreadCount = 0 { + didSet { + if unreadCount != oldValue { + postUnreadCountDidChangeNotification() + } + } + } + + // MARK: - Init + + init(accountID: String, nameForDisplay: String) { + + self.accountID = accountID + self.nameForDisplay = nameForDisplay + +// NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) + } + + + // MARK: Notifications + +// @objc dynamic public func unreadCountDidChange(_ note: Notification) { +// +// guard let obj = note.object else { +// return +// } +// let potentialChild = obj as AnyObject +// if isChild(potentialChild) { +// updateUnreadCount() +// } +// } + +// public var unreadCount = 0 { +// didSet { +// if unreadCount != oldValue { +// postUnreadCountDidChangeNotification() +// } +// } +// } + +// public func updateUnreadCount() { +// +// unreadCount = calculateUnreadCount(childObjects) +// } +} + +extension Folder: OPMLRepresentable { + + public func OPMLString(indentLevel: Int) -> String { + + let escapedTitle = nameForDisplay.rs_stringByEscapingSpecialXMLCharacters() + var s = "\n" + s = s.rs_string(byPrependingNumberOfTabs: indentLevel) + + var hasAtLeastOneChild = false + + let _ = visitChildren { (oneChild) -> Bool in + + if let oneOPMLObject = oneChild as? OPMLRepresentable { + s += oneOPMLObject.OPMLString(indentLevel: indentLevel + 1) + hasAtLeastOneChild = true + } + return false + } + + if !hasAtLeastOneChild { + s = "\n" + s = s.rs_string(byPrependingNumberOfTabs: indentLevel) + return s + } + + s = s + NSString.rs_string(withNumberOfTabs: indentLevel) + "\n" + + return s + } +} + diff --git a/Frameworks/Data/Data.xcodeproj/project.pbxproj b/Frameworks/Data/Data.xcodeproj/project.pbxproj index 44a393010..8ef8297c2 100644 --- a/Frameworks/Data/Data.xcodeproj/project.pbxproj +++ b/Frameworks/Data/Data.xcodeproj/project.pbxproj @@ -8,10 +8,12 @@ /* Begin PBXBuildFile section */ 840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405C91F1A8E4300DF0296 /* DatabaseID.swift */; }; + 8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */; }; + 841974201F6DD672006346C4 /* DisplayNameProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419741F1F6DD672006346C4 /* DisplayNameProvider.swift */; }; + 841974231F6DD804006346C4 /* OPMLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974221F6DD804006346C4 /* OPMLRepresentable.swift */; }; 843079FA1F0AB57F00B4B7F7 /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEEA31F0AB512004AB7CD /* RSCore.framework */; }; 844BEE651F0AB3C9004AB7CD /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE5B1F0AB3C8004AB7CD /* Data.framework */; }; 844BEE6A1F0AB3C9004AB7CD /* DataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE691F0AB3C9004AB7CD /* DataTests.swift */; }; - 844BEE7B1F0AB4BE004AB7CD /* Folder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE7A1F0AB4BE004AB7CD /* Folder.swift */; }; 844BEE7D1F0AB4C4004AB7CD /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */; }; 844BEE7F1F0AB4CA004AB7CD /* Article.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE7E1F0AB4CA004AB7CD /* Article.swift */; }; 844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE801F0AB4D0004AB7CD /* Author.swift */; }; @@ -19,12 +21,6 @@ 844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */; }; 844BEE871F0AB4E3004AB7CD /* BatchUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */; }; 844BEE891F0AB4E7004AB7CD /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE881F0AB4E7004AB7CD /* Notifications.swift */; }; - 844BEE901F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE8C1F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift */; }; - 844BEE911F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE8D1F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift */; }; - 844BEE921F0AB4EF004AB7CD /* OPMLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE8E1F0AB4EF004AB7CD /* OPMLRepresentable.swift */; }; - 844BEE981F0AB4F8004AB7CD /* AccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE941F0AB4F8004AB7CD /* AccountDelegate.swift */; }; - 844BEE991F0AB4F8004AB7CD /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE951F0AB4F8004AB7CD /* Container.swift */; }; - 844BEE9A1F0AB4F8004AB7CD /* DisplayNameProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE961F0AB4F8004AB7CD /* DisplayNameProvider.swift */; }; 848935221F6249AC00CEBD24 /* AccountInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935211F6249AC00CEBD24 /* AccountInfo.swift */; }; /* End PBXBuildFile section */ @@ -61,12 +57,14 @@ /* Begin PBXFileReference section */ 840405C91F1A8E4300DF0296 /* DatabaseID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseID.swift; sourceTree = ""; }; + 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadCountProvider.swift; sourceTree = ""; }; + 8419741F1F6DD672006346C4 /* DisplayNameProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameProvider.swift; sourceTree = ""; }; + 841974221F6DD804006346C4 /* OPMLRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OPMLRepresentable.swift; sourceTree = ""; }; 844BEE5B1F0AB3C8004AB7CD /* Data.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Data.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 844BEE641F0AB3C9004AB7CD /* DataTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DataTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 844BEE691F0AB3C9004AB7CD /* DataTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTests.swift; sourceTree = ""; }; 844BEE6B1F0AB3C9004AB7CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 844BEE761F0AB444004AB7CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 844BEE7A1F0AB4BE004AB7CD /* Folder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = ""; }; 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = ""; }; 844BEE7E1F0AB4CA004AB7CD /* Article.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Article.swift; sourceTree = ""; }; 844BEE801F0AB4D0004AB7CD /* Author.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Author.swift; sourceTree = ""; }; @@ -74,12 +72,6 @@ 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleStatus.swift; sourceTree = ""; }; 844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatchUpdates.swift; sourceTree = ""; }; 844BEE881F0AB4E7004AB7CD /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; - 844BEE8C1F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Feed+OPMLRepresentable.swift"; sourceTree = ""; }; - 844BEE8D1F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Folder+OPMLRepresentable.swift"; sourceTree = ""; }; - 844BEE8E1F0AB4EF004AB7CD /* OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OPMLRepresentable.swift; sourceTree = ""; }; - 844BEE941F0AB4F8004AB7CD /* AccountDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountDelegate.swift; sourceTree = ""; }; - 844BEE951F0AB4F8004AB7CD /* Container.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; - 844BEE961F0AB4F8004AB7CD /* DisplayNameProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayNameProvider.swift; sourceTree = ""; }; 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; 848935211F6249AC00CEBD24 /* AccountInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountInfo.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -107,7 +99,6 @@ 844BEE511F0AB3C8004AB7CD = { isa = PBXGroup; children = ( - 844BEE7A1F0AB4BE004AB7CD /* Folder.swift */, 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */, 844BEE7E1F0AB4CA004AB7CD /* Article.swift */, 844BEE801F0AB4D0004AB7CD /* Author.swift */, @@ -117,8 +108,9 @@ 840405C91F1A8E4300DF0296 /* DatabaseID.swift */, 844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */, 844BEE881F0AB4E7004AB7CD /* Notifications.swift */, - 844BEE8A1F0AB4EF004AB7CD /* OPML */, - 844BEE931F0AB4F8004AB7CD /* Protocols */, + 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */, + 8419741F1F6DD672006346C4 /* DisplayNameProvider.swift */, + 841974221F6DD804006346C4 /* OPMLRepresentable.swift */, 844BEE761F0AB444004AB7CD /* Info.plist */, 844BEE681F0AB3C9004AB7CD /* DataTests */, 844BEE5C1F0AB3C8004AB7CD /* Products */, @@ -144,26 +136,6 @@ path = DataTests; sourceTree = ""; }; - 844BEE8A1F0AB4EF004AB7CD /* OPML */ = { - isa = PBXGroup; - children = ( - 844BEE8C1F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift */, - 844BEE8D1F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift */, - 844BEE8E1F0AB4EF004AB7CD /* OPMLRepresentable.swift */, - ); - path = OPML; - sourceTree = ""; - }; - 844BEE931F0AB4F8004AB7CD /* Protocols */ = { - isa = PBXGroup; - children = ( - 844BEE941F0AB4F8004AB7CD /* AccountDelegate.swift */, - 844BEE951F0AB4F8004AB7CD /* Container.swift */, - 844BEE961F0AB4F8004AB7CD /* DisplayNameProvider.swift */, - ); - path = Protocols; - sourceTree = ""; - }; 844BEE9D1F0AB512004AB7CD /* Products */ = { isa = PBXGroup; children = ( @@ -324,20 +296,16 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 844BEE911F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift in Sources */, - 844BEE901F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift in Sources */, 844BEE7F1F0AB4CA004AB7CD /* Article.swift in Sources */, 844BEE7D1F0AB4C4004AB7CD /* Feed.swift in Sources */, + 841974231F6DD804006346C4 /* OPMLRepresentable.swift in Sources */, 844BEE891F0AB4E7004AB7CD /* Notifications.swift in Sources */, 848935221F6249AC00CEBD24 /* AccountInfo.swift in Sources */, - 844BEE9A1F0AB4F8004AB7CD /* DisplayNameProvider.swift in Sources */, - 844BEE991F0AB4F8004AB7CD /* Container.swift in Sources */, - 844BEE7B1F0AB4BE004AB7CD /* Folder.swift in Sources */, - 844BEE981F0AB4F8004AB7CD /* AccountDelegate.swift in Sources */, 844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */, + 8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */, + 841974201F6DD672006346C4 /* DisplayNameProvider.swift in Sources */, 844BEE871F0AB4E3004AB7CD /* BatchUpdates.swift in Sources */, 844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */, - 844BEE921F0AB4EF004AB7CD /* OPMLRepresentable.swift in Sources */, 840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */, 844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */, ); diff --git a/Frameworks/Data/DatabaseID.swift b/Frameworks/Data/DatabaseID.swift index 2729a04b2..8f89eadcf 100644 --- a/Frameworks/Data/DatabaseID.swift +++ b/Frameworks/Data/DatabaseID.swift @@ -16,7 +16,7 @@ import RSCore private var databaseIDCache = [String: String]() private var databaseIDCacheLock = os_unfair_lock_s() -public func databaseIDWithString(_ s: String) -> String { +func databaseIDWithString(_ s: String) -> String { os_unfair_lock_lock(&databaseIDCacheLock) defer { diff --git a/Frameworks/Data/Protocols/DisplayNameProvider.swift b/Frameworks/Data/DisplayNameProvider.swift similarity index 100% rename from Frameworks/Data/Protocols/DisplayNameProvider.swift rename to Frameworks/Data/DisplayNameProvider.swift diff --git a/Frameworks/Data/Feed.swift b/Frameworks/Data/Feed.swift index f5dc1ee37..93c212e8b 100644 --- a/Frameworks/Data/Feed.swift +++ b/Frameworks/Data/Feed.swift @@ -9,7 +9,7 @@ import Foundation import RSCore -public final class Feed: DisplayNameProvider, Hashable { +public final class Feed: DisplayNameProvider, UnreadCountProvider, Hashable { public let accountID: String public let url: String @@ -17,24 +17,29 @@ public final class Feed: DisplayNameProvider, Hashable { public var homePageURL: String? public var name: String? public var editedName: String? - public var articles = Set
() public var accountInfo: AccountInfo? //If account needs to store more data public let hashValue: Int - + + // MARK: - DisplayNameProvider + public var nameForDisplay: String { get { return (editedName ?? name) ?? NSLocalizedString("Untitled", comment: "Feed name") } } -// public var unreadCount = 0 { -// didSet { -// if unreadCount != oldValue { -// postUnreadCountDidChangeNotification() -// } -// } -// } + // MARK: - UnreadCountProvider + public var unreadCount = 0 { + didSet { + if unreadCount != oldValue { + postUnreadCountDidChangeNotification() + } + } + } + + // MARK: - Init + public init(accountID: String, url: String, feedID: String) { self.accountID = accountID @@ -43,19 +48,29 @@ public final class Feed: DisplayNameProvider, Hashable { self.hashValue = accountID.hashValue ^ url.hashValue ^ feedID.hashValue } -// public func updateUnreadCount() { -// -// unreadCount = articles.reduce(0) { (result, oneArticle) -> Int in -// if let read = oneArticle.status?.read, !read { -// return result + 1 -// } -// return result -// } -// } - public class func ==(lhs: Feed, rhs: Feed) -> Bool { return lhs === rhs } } +// MARK: - OPMLRepresentable + +extension Feed: OPMLRepresentable { + + public func OPMLString(indentLevel: Int) -> String { + + let escapedName = nameForDisplay.rs_stringByEscapingSpecialXMLCharacters() + var escapedHomePageURL = "" + if let homePageURL = homePageURL { + escapedHomePageURL = homePageURL.rs_stringByEscapingSpecialXMLCharacters() + } + let escapedFeedURL = url.rs_stringByEscapingSpecialXMLCharacters() + + var s = "\n" + s = s.rs_string(byPrependingNumberOfTabs: indentLevel) + + return s + } +} + diff --git a/Frameworks/Data/Folder.swift b/Frameworks/Data/Folder.swift deleted file mode 100644 index a7ee2effc..000000000 --- a/Frameworks/Data/Folder.swift +++ /dev/null @@ -1,98 +0,0 @@ -// -// Folder.swift -// DataModel -// -// Created by Brent Simmons on 7/1/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public final class Folder { - - public let accountID: String - public var nameForDisplay: String - var childObjects = [AnyObject]() - - init(accountID: String, nameForDisplay: String) { - - self.accountID = accountID - self.nameForDisplay = nameForDisplay - -// NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) - } - - // MARK: Notifications - -// @objc dynamic public func unreadCountDidChange(_ note: Notification) { -// -// guard let obj = note.object else { -// return -// } -// let potentialChild = obj as AnyObject -// if isChild(potentialChild) { -// updateUnreadCount() -// } -// } - -// public var unreadCount = 0 { -// didSet { -// if unreadCount != oldValue { -// postUnreadCountDidChangeNotification() -// } -// } -// } - -// public func updateUnreadCount() { -// -// unreadCount = calculateUnreadCount(childObjects) -// } -} - -extension Folder: Container { - - public func flattenedFeeds() -> Set { - - var feeds = Set() - for oneChild in childObjects { - if let oneFeed = oneChild as? Feed { - feeds.insert(oneFeed) - } - else if let oneContainer = oneChild as? Container { - feeds.formUnion(oneContainer.flattenedFeeds()) - } - } - return feeds - } - - public func isChild(_ obj: AnyObject) -> Bool { - - return childObjects.contains(where: { (oneObject) -> Bool in - return oneObject === obj - }) - } - - public func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool { - - for oneObject in childObjects { - - if let oneContainer = oneObject as? Container { - if visitBlock(oneObject) { - return true - } - if recurse && oneContainer.visitObjects(recurse, visitBlock) { - return true - } - } - else { - if visitBlock(oneObject) { - return true - } - } - } - return false - } - -} - - diff --git a/Frameworks/Data/Notifications.swift b/Frameworks/Data/Notifications.swift index 6f3d014de..53c20e503 100644 --- a/Frameworks/Data/Notifications.swift +++ b/Frameworks/Data/Notifications.swift @@ -11,9 +11,9 @@ import Foundation public extension Notification.Name { public static let ArticleStatusesDidChange = Notification.Name(rawValue: "ArticleStatusesDidChange") - public static let UnreadCountDidChange = Notification.Name(rawValue: "UnreadCountDidChangeNotification") - public static let DataModelDidPerformBatchUpdates = Notification.Name(rawValue: "DataModelDidPerformBatchUpdatesDidPerformBatchUpdatesNotification") - public static let AccountRefreshProgressDidChange = Notification.Name(rawValue: "AccountRefreshProgressDidChangeNotification") + public static let UnreadCountDidChange = Notification.Name(rawValue: "UnreadCountDidChange") + public static let DataModelDidPerformBatchUpdates = Notification.Name(rawValue: "DataModelDidPerformBatchUpdates") + public static let AccountRefreshProgressDidChange = Notification.Name(rawValue: "AccountRefreshProgressDidChange") } public let articlesKey = "articles" diff --git a/Frameworks/Data/OPML/Feed+OPMLRepresentable.swift b/Frameworks/Data/OPML/Feed+OPMLRepresentable.swift deleted file mode 100644 index c7108f36c..000000000 --- a/Frameworks/Data/OPML/Feed+OPMLRepresentable.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// Feed+OPMLRepresentable.swift -// DataModel -// -// Created by Brent Simmons on 7/2/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation -import RSCore - -extension Feed: OPMLRepresentable { - - public func OPMLString(indentLevel: Int) -> String { - - let escapedName = nameForDisplay.rs_stringByEscapingSpecialXMLCharacters() - var escapedHomePageURL = "" - if let homePageURL = homePageURL { - escapedHomePageURL = homePageURL.rs_stringByEscapingSpecialXMLCharacters() - } - let escapedFeedURL = url.rs_stringByEscapingSpecialXMLCharacters() - - var s = "\n" - s = s.rs_string(byPrependingNumberOfTabs: indentLevel) - - return s - } -} diff --git a/Frameworks/Data/OPML/Folder+OPMLRepresentable.swift b/Frameworks/Data/OPML/Folder+OPMLRepresentable.swift deleted file mode 100644 index dab4ae4bd..000000000 --- a/Frameworks/Data/OPML/Folder+OPMLRepresentable.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// Folder+OPMLRepresentable.swift -// DataModel -// -// Created by Brent Simmons on 7/2/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation -import RSCore - -extension Folder: OPMLRepresentable { - - public func OPMLString(indentLevel: Int) -> String { - - let escapedTitle = nameForDisplay.rs_stringByEscapingSpecialXMLCharacters() - var s = "\n" - s = s.rs_string(byPrependingNumberOfTabs: indentLevel) - - var hasAtLeastOneChild = false - - let _ = visitChildren { (oneChild) -> Bool in - - if let oneOPMLObject = oneChild as? OPMLRepresentable { - s += oneOPMLObject.OPMLString(indentLevel: indentLevel + 1) - hasAtLeastOneChild = true - } - return false - } - - if !hasAtLeastOneChild { - s = "\n" - s = s.rs_string(byPrependingNumberOfTabs: indentLevel) - return s - } - - s = s + NSString.rs_string(withNumberOfTabs: indentLevel) + "\n" - - return s - } -} diff --git a/Frameworks/Data/OPML/OPMLRepresentable.swift b/Frameworks/Data/OPMLRepresentable.swift similarity index 100% rename from Frameworks/Data/OPML/OPMLRepresentable.swift rename to Frameworks/Data/OPMLRepresentable.swift diff --git a/Frameworks/Data/Protocols/AccountDelegate.swift b/Frameworks/Data/Protocols/AccountDelegate.swift deleted file mode 100644 index 7798f218b..000000000 --- a/Frameworks/Data/Protocols/AccountDelegate.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// AccountDelegate.swift -// DataModel -// -// Created by Brent Simmons on 7/1/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public protocol AccountDelegate: class { - - func canAddItem(_ item: AnyObject, toContainer: Container) -> Bool - -} - diff --git a/Frameworks/Account/UnreadCountProvider.swift b/Frameworks/Data/UnreadCountProvider.swift similarity index 93% rename from Frameworks/Account/UnreadCountProvider.swift rename to Frameworks/Data/UnreadCountProvider.swift index 2bd2e1702..34d3d4070 100644 --- a/Frameworks/Account/UnreadCountProvider.swift +++ b/Frameworks/Data/UnreadCountProvider.swift @@ -10,9 +10,7 @@ import Foundation public protocol UnreadCountProvider { - var unreadCount: Int {get} - - func updateUnreadCount() + var unreadCount: Int { get } } public func calculateUnreadCount(_ children: T) -> Int { diff --git a/Frameworks/Database/Database.swift b/Frameworks/Database/Database.swift index 4850f110a..282b747bd 100644 --- a/Frameworks/Database/Database.swift +++ b/Frameworks/Database/Database.swift @@ -49,9 +49,9 @@ public final class Database { articlesTable.fetchArticlesAsync(feed, withLimits: true, resultBlock) } - public func fetchUnreadArticles(for folder: Folder) -> Set
{ + public func fetchUnreadArticles(for feeds: Set) -> Set
{ - return articlesTable.fetchUnreadArticles(for: folder.flattenedFeeds()) + return articlesTable.fetchUnreadArticles(for: feeds) } // MARK: - Unread Counts diff --git a/ToDo.opml b/ToDo.opml index ea6e67242..ae0be2bdb 100644 --- a/ToDo.opml +++ b/ToDo.opml @@ -6,12 +6,12 @@ --> ToDo Tue, 12 Sep 2017 20:15:17 GMT - 11,16,17,20,24,29,31,34,37,39,40,42,46,49,51,53,55,64 - 0 - 208 - 30 - 762 - 967 + 11,16,17,20,24,29,31,34,37,39,40,42,46,49,51,53,55,64,69 + 52 + 3298 + 544 + 1276 + 4057 @@ -103,6 +103,8 @@ + +