Move Folder and Container from Data to Account.
This commit is contained in:
parent
e7794530e5
commit
5715d2f221
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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<Feed> {
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 = "<group>"; };
|
||||
841973DF1F6DD194006346C4 /* Data.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Data.xcodeproj; path = ../Data/Data.xcodeproj; sourceTree = "<group>"; };
|
||||
841973E81F6DD19E006346C4 /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = "<group>"; };
|
||||
841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = ../RSParser/RSParser.xcodeproj; sourceTree = "<group>"; };
|
||||
841974001F6DD1EC006346C4 /* Folder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = "<group>"; };
|
||||
8419740D1F6DD25F006346C4 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
|
||||
841974171F6DD535006346C4 /* Folder+Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Container.swift"; sourceTree = "<group>"; };
|
||||
841974191F6DD583006346C4 /* Account+Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Container.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; };
|
||||
848935041F62485000CEBD24 /* AccountTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTests.swift; sourceTree = "<group>"; };
|
||||
848935061F62485000CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
848935101F62486800CEBD24 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
|
||||
848935201F62498B00CEBD24 /* Account+OPMLRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+OPMLRepresentable.swift"; sourceTree = "<group>"; };
|
||||
/* 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 = "<group>";
|
||||
};
|
||||
841973E01F6DD194006346C4 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
841973E51F6DD195006346C4 /* Data.framework */,
|
||||
841973E71F6DD195006346C4 /* DataTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
841973E91F6DD19E006346C4 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
841973EF1F6DD19E006346C4 /* RSCore.framework */,
|
||||
841973F11F6DD19E006346C4 /* RSCoreTests.xctest */,
|
||||
841973F31F6DD19E006346C4 /* RSCore.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
841973F51F6DD1AC006346C4 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
841973FA1F6DD1AC006346C4 /* RSParser.framework */,
|
||||
841973FC1F6DD1AC006346C4 /* RSParserTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
841974141F6DD4FF006346C4 /* Container */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8419740D1F6DD25F006346C4 /* Container.swift */,
|
||||
841974191F6DD583006346C4 /* Account+Container.swift */,
|
||||
841974171F6DD535006346C4 /* Folder+Container.swift */,
|
||||
);
|
||||
path = Container;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8469F80F1F6DC3C10084783E /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8401A1721F6DC387002B1BE2 /* Database.xcodeproj */,
|
||||
841973DF1F6DD194006346C4 /* Data.xcodeproj */,
|
||||
841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */,
|
||||
841973E81F6DD19E006346C4 /* RSCore.xcodeproj */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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;
|
||||
|
|
|
@ -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<Feed> {
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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<Feed> {
|
||||
|
||||
var feeds = Set<Feed>()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -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 = "<outline text=\"\(escapedTitle)\" title=\"\(escapedTitle)\">\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 = "<outline text=\"\(escapedTitle)\" title=\"\(escapedTitle)\"/>\n"
|
||||
s = s.rs_string(byPrependingNumberOfTabs: indentLevel)
|
||||
return s
|
||||
}
|
||||
|
||||
s = s + NSString.rs_string(withNumberOfTabs: indentLevel) + "</outline>\n"
|
||||
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
|
@ -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 = "<group>"; };
|
||||
8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadCountProvider.swift; sourceTree = "<group>"; };
|
||||
8419741F1F6DD672006346C4 /* DisplayNameProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameProvider.swift; sourceTree = "<group>"; };
|
||||
841974221F6DD804006346C4 /* OPMLRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OPMLRepresentable.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
844BEE6B1F0AB3C9004AB7CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
844BEE761F0AB444004AB7CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
844BEE7A1F0AB4BE004AB7CD /* Folder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = "<group>"; };
|
||||
844BEE7C1F0AB4C4004AB7CD /* Feed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = "<group>"; };
|
||||
844BEE7E1F0AB4CA004AB7CD /* Article.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Article.swift; sourceTree = "<group>"; };
|
||||
844BEE801F0AB4D0004AB7CD /* Author.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Author.swift; sourceTree = "<group>"; };
|
||||
|
@ -74,12 +72,6 @@
|
|||
844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleStatus.swift; sourceTree = "<group>"; };
|
||||
844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatchUpdates.swift; sourceTree = "<group>"; };
|
||||
844BEE881F0AB4E7004AB7CD /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
|
||||
844BEE8C1F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Feed+OPMLRepresentable.swift"; sourceTree = "<group>"; };
|
||||
844BEE8D1F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Folder+OPMLRepresentable.swift"; sourceTree = "<group>"; };
|
||||
844BEE8E1F0AB4EF004AB7CD /* OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OPMLRepresentable.swift; sourceTree = "<group>"; };
|
||||
844BEE941F0AB4F8004AB7CD /* AccountDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountDelegate.swift; sourceTree = "<group>"; };
|
||||
844BEE951F0AB4F8004AB7CD /* Container.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
|
||||
844BEE961F0AB4F8004AB7CD /* DisplayNameProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayNameProvider.swift; sourceTree = "<group>"; };
|
||||
844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = "<group>"; };
|
||||
848935211F6249AC00CEBD24 /* AccountInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountInfo.swift; sourceTree = "<group>"; };
|
||||
/* 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 = "<group>";
|
||||
};
|
||||
844BEE8A1F0AB4EF004AB7CD /* OPML */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
844BEE8C1F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift */,
|
||||
844BEE8D1F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift */,
|
||||
844BEE8E1F0AB4EF004AB7CD /* OPMLRepresentable.swift */,
|
||||
);
|
||||
path = OPML;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
844BEE931F0AB4F8004AB7CD /* Protocols */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
844BEE941F0AB4F8004AB7CD /* AccountDelegate.swift */,
|
||||
844BEE951F0AB4F8004AB7CD /* Container.swift */,
|
||||
844BEE961F0AB4F8004AB7CD /* DisplayNameProvider.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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 */,
|
||||
);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<Article>()
|
||||
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 = "<outline text=\"\(escapedName)\" title=\"\(escapedName)\" description=\"\" type=\"rss\" version=\"RSS\" htmlUrl=\"\(escapedHomePageURL)\" xmlUrl=\"\(escapedFeedURL)\"/>\n"
|
||||
s = s.rs_string(byPrependingNumberOfTabs: indentLevel)
|
||||
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Feed> {
|
||||
|
||||
var feeds = Set<Feed>()
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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"
|
||||
|
|
|
@ -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 = "<outline text=\"\(escapedName)\" title=\"\(escapedName)\" description=\"\" type=\"rss\" version=\"RSS\" htmlUrl=\"\(escapedHomePageURL)\" xmlUrl=\"\(escapedFeedURL)\"/>\n"
|
||||
s = s.rs_string(byPrependingNumberOfTabs: indentLevel)
|
||||
|
||||
return s
|
||||
}
|
||||
}
|
|
@ -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 = "<outline text=\"\(escapedTitle)\" title=\"\(escapedTitle)\">\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 = "<outline text=\"\(escapedTitle)\" title=\"\(escapedTitle)\"/>\n"
|
||||
s = s.rs_string(byPrependingNumberOfTabs: indentLevel)
|
||||
return s
|
||||
}
|
||||
|
||||
s = s + NSString.rs_string(withNumberOfTabs: indentLevel) + "</outline>\n"
|
||||
|
||||
return s
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
@ -10,9 +10,7 @@ import Foundation
|
|||
|
||||
public protocol UnreadCountProvider {
|
||||
|
||||
var unreadCount: Int {get}
|
||||
|
||||
func updateUnreadCount()
|
||||
var unreadCount: Int { get }
|
||||
}
|
||||
|
||||
public func calculateUnreadCount<T: Collection>(_ children: T) -> Int {
|
|
@ -49,9 +49,9 @@ public final class Database {
|
|||
articlesTable.fetchArticlesAsync(feed, withLimits: true, resultBlock)
|
||||
}
|
||||
|
||||
public func fetchUnreadArticles(for folder: Folder) -> Set<Article> {
|
||||
public func fetchUnreadArticles(for feeds: Set<Feed>) -> Set<Article> {
|
||||
|
||||
return articlesTable.fetchUnreadArticles(for: folder.flattenedFeeds())
|
||||
return articlesTable.fetchUnreadArticles(for: feeds)
|
||||
}
|
||||
|
||||
// MARK: - Unread Counts
|
||||
|
|
14
ToDo.opml
14
ToDo.opml
|
@ -6,12 +6,12 @@
|
|||
</editor> -->
|
||||
<title>ToDo</title>
|
||||
<dateCreated>Tue, 12 Sep 2017 20:15:17 GMT</dateCreated>
|
||||
<expansionState>11,16,17,20,24,29,31,34,37,39,40,42,46,49,51,53,55,64</expansionState>
|
||||
<vertScrollState>0</vertScrollState>
|
||||
<windowTop>208</windowTop>
|
||||
<windowLeft>30</windowLeft>
|
||||
<windowRight>762</windowRight>
|
||||
<windowBottom>967</windowBottom>
|
||||
<expansionState>11,16,17,20,24,29,31,34,37,39,40,42,46,49,51,53,55,64,69</expansionState>
|
||||
<vertScrollState>52</vertScrollState>
|
||||
<windowTop>3298</windowTop>
|
||||
<windowLeft>544</windowLeft>
|
||||
<windowRight>1276</windowRight>
|
||||
<windowBottom>4057</windowBottom>
|
||||
</head>
|
||||
<body>
|
||||
<outline text="App">
|
||||
|
@ -103,6 +103,8 @@
|
|||
</outline>
|
||||
<outline text="Data">
|
||||
<outline text="Make model classes quicklookable"/>
|
||||
<outline text="Move BatchUpdates.swift somewhere"/>
|
||||
<outline text="Move Notifications.swift somewhere"/>
|
||||
</outline>
|
||||
<outline text="RSParser">
|
||||
<outline text="ParsedItem == should compare all properties"/>
|
||||
|
|
Loading…
Reference in New Issue