From d9cfab7d68ef3946f8ee78de84417f663b4f5eb1 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Mon, 3 Jul 2017 10:29:44 -0700 Subject: [PATCH] Continue major surgery. Everything is wildly broken. --- Frameworks/Data/Account.swift | 114 ++++ Frameworks/{DataModel => Data}/Article.swift | 13 +- Frameworks/Data/ArticleStatus.swift | 72 +++ .../{DataModel => Data}/Attachment.swift | 4 +- Frameworks/{DataModel => Data}/Author.swift | 11 +- .../{DataModel => Data}/BatchUpdates.swift | 0 .../Data/Data.xcodeproj/project.pbxproj | 573 ++++++++++++++++++ .../contents.xcworkspacedata | 2 +- Frameworks/Data/DataTests/DataTests.swift | 36 ++ Frameworks/Data/DataTests/Info.plist | 22 + Frameworks/{DataModel => Data}/Feed.swift | 47 +- Frameworks/Data/Folder.swift | 100 +++ Frameworks/{DataModel => Data}/Info.plist | 2 +- .../{DataModel => Data}/Notifications.swift | 0 .../Data/OPML/Account+OPMLRepresentable.swift | 23 + .../Data/OPML/Feed+OPMLRepresentable.swift | 28 + .../Data/OPML/Folder+OPMLRepresentable.swift | 41 ++ .../OPML}/OPMLRepresentable.swift | 0 .../Protocols}/AccountDelegate.swift | 2 +- Frameworks/Data/Protocols/Container.swift | 150 +++++ .../Protocols/DisplayNameProvider.swift} | 0 .../Protocols/UnreadCountProvider.swift} | 7 +- Frameworks/DataModel/Account.swift | 35 -- Frameworks/DataModel/AccountProtocol.swift | 44 -- .../DataModel/ArticleStatusProtocol.swift | 43 -- Frameworks/DataModel/Container.swift | 168 ----- .../DataModel.xcodeproj/project.pbxproj | 366 ----------- Frameworks/DataModel/Folder.swift | 14 - .../Database.xcodeproj/project.pbxproj | 420 +++++++++++++ .../contents.xcworkspacedata | 7 + Frameworks/Database/Database/Database.h | 19 + Frameworks/Database/Database/Info.plist | 26 + .../DatabaseTests/DatabaseTests.swift | 36 ++ Frameworks/Database/DatabaseTests/Info.plist | 22 + .../RSCore/RSCore/PlistProviderProtocol.swift | 2 +- 35 files changed, 1732 insertions(+), 717 deletions(-) create mode 100644 Frameworks/Data/Account.swift rename Frameworks/{DataModel => Data}/Article.swift (88%) create mode 100644 Frameworks/Data/ArticleStatus.swift rename Frameworks/{DataModel => Data}/Attachment.swift (77%) rename Frameworks/{DataModel => Data}/Author.swift (85%) rename Frameworks/{DataModel => Data}/BatchUpdates.swift (100%) create mode 100644 Frameworks/Data/Data.xcodeproj/project.pbxproj rename Frameworks/{DataModel/DataModel.xcodeproj => Data/Data.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (70%) create mode 100644 Frameworks/Data/DataTests/DataTests.swift create mode 100644 Frameworks/Data/DataTests/Info.plist rename Frameworks/{DataModel => Data}/Feed.swift (53%) create mode 100644 Frameworks/Data/Folder.swift rename Frameworks/{DataModel => Data}/Info.plist (90%) rename Frameworks/{DataModel => Data}/Notifications.swift (100%) create mode 100644 Frameworks/Data/OPML/Account+OPMLRepresentable.swift create mode 100644 Frameworks/Data/OPML/Feed+OPMLRepresentable.swift create mode 100644 Frameworks/Data/OPML/Folder+OPMLRepresentable.swift rename Frameworks/{DataModel => Data/OPML}/OPMLRepresentable.swift (100%) rename Frameworks/{DataModel => Data/Protocols}/AccountDelegate.swift (75%) create mode 100644 Frameworks/Data/Protocols/Container.swift rename Frameworks/{DataModel/DisplayNameProviderProtocol.swift => Data/Protocols/DisplayNameProvider.swift} (100%) rename Frameworks/{DataModel/UnreadCountProviderProtocol.swift => Data/Protocols/UnreadCountProvider.swift} (82%) delete mode 100644 Frameworks/DataModel/Account.swift delete mode 100644 Frameworks/DataModel/AccountProtocol.swift delete mode 100644 Frameworks/DataModel/ArticleStatusProtocol.swift delete mode 100644 Frameworks/DataModel/Container.swift delete mode 100644 Frameworks/DataModel/DataModel.xcodeproj/project.pbxproj delete mode 100644 Frameworks/DataModel/Folder.swift create mode 100644 Frameworks/Database/Database.xcodeproj/project.pbxproj create mode 100644 Frameworks/Database/Database.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Frameworks/Database/Database/Database.h create mode 100644 Frameworks/Database/Database/Info.plist create mode 100644 Frameworks/Database/DatabaseTests/DatabaseTests.swift create mode 100644 Frameworks/Database/DatabaseTests/Info.plist diff --git a/Frameworks/Data/Account.swift b/Frameworks/Data/Account.swift new file mode 100644 index 000000000..e899f45ab --- /dev/null +++ b/Frameworks/Data/Account.swift @@ -0,0 +1,114 @@ +// +// Account.swift +// DataModel +// +// Created by Brent Simmons on 7/1/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import Foundation +import RSCore + +// Various model objects include an accountInfo property that Accounts can use to store extra data. +public typealias AccountInfo = [String: Any] + +public enum AccountType: Int { + + // Raw values should not change since they’re stored on disk. + case onMyMac = 1 + case feedly = 16 + case feedbin = 17 + case feedWrangler = 18 + case newsBlur = 19 + // TODO: more +} + +public final class Account: Hashable { + + public let identifier: String + public let type: AccountType + public var nameForDisplay: String? + public let delegate: AccountDelegate + public let hashValue: Int + let settingsFile: String + let dataFolder: String + var topLevelObjects = [AnyObject]() + var feedIDDictionary = [String: Feed]() + var username: String? + var accountInfo = AccountInfo() + + init(settingsFile: String, type: AccountType, dataFolder: String, identifier: String, delegate: AccountDelegate) { + + self.identifier = identifier + self.type = type + self.settingsFile = settingsFile + self.dataFolder = dataFolder + self.delegate = delegate + self.hashValue = identifier.hashValue + } + + public class func ==(lhs: Account, rhs: Account) -> Bool { + + return lhs === rhs + } +} + +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 { + + public func plist() -> AnyObject? { + return nil // TODO + } +} + diff --git a/Frameworks/DataModel/Article.swift b/Frameworks/Data/Article.swift similarity index 88% rename from Frameworks/DataModel/Article.swift rename to Frameworks/Data/Article.swift index f93002923..7999b905f 100644 --- a/Frameworks/DataModel/Article.swift +++ b/Frameworks/Data/Article.swift @@ -25,11 +25,12 @@ public final class Article: Hashable { var bannerImageURL: String? var datePublished: Date? var dateModified: Date? - var authors: [Authors]? + var authors: [Author]? var tags: [String]? var attachments: [Attachment]? var status: ArticleStatus? - + public let hashValue: Int + public var accountInfo: [String: Any]? //If account needs to store more data var feed: Feed? { @@ -38,7 +39,7 @@ public final class Article: Hashable { } } - init(account: Account, feedID: String, uniqueID: String, title: String?, contentHTML: String?, contentText: String?, url: String?, externalURL: String?, summary: String?, imageURL: String?, bannerImageURL: String?, datePublished: Date?, dateModified: Date?, authors: [Authors]?, tags: [String]?, attachments: [Attachment]?) { + init(account: Account, feedID: String, uniqueID: String, title: String?, contentHTML: String?, contentText: String?, url: String?, externalURL: String?, summary: String?, imageURL: String?, bannerImageURL: String?, datePublished: Date?, dateModified: Date?, authors: [Author]?, tags: [String]?, attachments: [Attachment]?) { self.account = account self.feedID = feedID @@ -53,11 +54,11 @@ public final class Article: Hashable { self.bannerImageURL = bannerImageURL self.datePublished = datePublished self.dateModified = dateModified - self.dateArrived = dateArrived self.authors = authors self.tags = tags self.attachments = attachments - + + self.articleID = "\(feedID) \(uniqueID)" self.hashValue = account.hashValue + feedID.hashValue + uniqueID.hashValue } @@ -71,7 +72,7 @@ public extension Article { public var logicalDatePublished: Date? { get { - return (datePublished ?? dateModified) && status?.dateArrived + return (datePublished ?? dateModified) ?? status?.dateArrived } } } diff --git a/Frameworks/Data/ArticleStatus.swift b/Frameworks/Data/ArticleStatus.swift new file mode 100644 index 000000000..7471866df --- /dev/null +++ b/Frameworks/Data/ArticleStatus.swift @@ -0,0 +1,72 @@ +// +// ArticleStatus.swift +// DataModel +// +// Created by Brent Simmons on 7/1/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +public enum ArticleStatusKey: String { + + case read = "read" + case starred = "starred" + case userDeleted = "userDeleted" +} + +public final class ArticleStatus { + + public var read = false + public var starred = false + public var userDeleted = false + public var dateArrived: Date + var accountInfo: AccountInfo? + + init(read: Bool, starred: Bool, userDeleted: Bool, dateArrived: Date, accountInfo: AccountInfo?) { + + self.read = read + self.starred = starred + self.userDeleted = userDeleted + self.dateArrived = dateArrived + self.accountInfo = accountInfo + } + + func boolStatusForKey(_ key: String) -> Bool { + + if let articleStatusKey = ArticleStatusKey(rawValue: key) { + switch articleStatusKey { + case .read: + return read + case .starred: + return starred + case .userDeleted: + return userDeleted + } + } + else if let flag = accountInfo?[key] as? Bool { + return flag + } + return false + } + + func setBoolStatusForKey(_ status: Bool, key: String) { + + if let articleStatusKey = ArticleStatusKey(rawValue: key) { + switch articleStatusKey { + case .read: + read = status + case .starred: + starred = status + case .userDeleted: + userDeleted = status + } + } + else { + if accountInfo == nil { + accountInfo = AccountInfo() + } + accountInfo![key] = status + } + } +} diff --git a/Frameworks/DataModel/Attachment.swift b/Frameworks/Data/Attachment.swift similarity index 77% rename from Frameworks/DataModel/Attachment.swift rename to Frameworks/Data/Attachment.swift index ced3cd743..97ee24f4f 100644 --- a/Frameworks/DataModel/Attachment.swift +++ b/Frameworks/Data/Attachment.swift @@ -25,8 +25,8 @@ public struct Attachment: Equatable { self.durationInSeconds = durationInSeconds } - public class func ==(lhs: Attachment, rhs: Attachment) -> Bool { + public static func ==(lhs: Attachment, rhs: Attachment) -> Bool { - return lhs.url == rhs.url && lhs.mimeType == rhs.mimeType && lhs.title == rhs.title && lhs.sizeInBytes == rhs.sizeInBytes && lhs.durationInSeconds == rhs.durationInSeconds + return lhs.sizeInBytes == rhs.sizeInBytes && lhs.url == rhs.url && lhs.mimeType == rhs.mimeType && lhs.title == rhs.title && lhs.durationInSeconds == rhs.durationInSeconds } } diff --git a/Frameworks/DataModel/Author.swift b/Frameworks/Data/Author.swift similarity index 85% rename from Frameworks/DataModel/Author.swift rename to Frameworks/Data/Author.swift index 2d2ff288f..75442fc5a 100644 --- a/Frameworks/DataModel/Author.swift +++ b/Frameworks/Data/Author.swift @@ -14,7 +14,8 @@ public struct Author: Hashable { public let url: String? public let avatarURL: String? public let emailAddress: String? - + public let hashValue: Int + public init?(name: String?, url: String?, avatarURL: String?, emailAddress: String?) { if name == nil && url == nil && emailAddress == nil { @@ -25,14 +26,14 @@ public struct Author: Hashable { self.avatarURL = avatarURL self.emailAddress = emailAddress - let s = name ?? "" + var s = name ?? "" s += url ?? "" s += avatarURL ?? "" - s += emailAddres ?? "" + s += emailAddress ?? "" self.hashValue = s.hashValue } - - public class func ==(lhs: Author, rhs: Author) { + + public static func ==(lhs: Author, rhs: Author) -> Bool { return lhs.hashValue == rhs.hashValue && lhs.name == rhs.name && lhs.url == rhs.url && lhs.avatarURL == rhs.avatarURL && lhs.emailAddress == rhs.emailAddress } diff --git a/Frameworks/DataModel/BatchUpdates.swift b/Frameworks/Data/BatchUpdates.swift similarity index 100% rename from Frameworks/DataModel/BatchUpdates.swift rename to Frameworks/Data/BatchUpdates.swift diff --git a/Frameworks/Data/Data.xcodeproj/project.pbxproj b/Frameworks/Data/Data.xcodeproj/project.pbxproj new file mode 100644 index 000000000..33f7c4305 --- /dev/null +++ b/Frameworks/Data/Data.xcodeproj/project.pbxproj @@ -0,0 +1,573 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 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 */; }; + 844BEE791F0AB4B8004AB7CD /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE781F0AB4B8004AB7CD /* Account.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 */; }; + 844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE821F0AB4D6004AB7CD /* Attachment.swift */; }; + 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 */; }; + 844BEE8F1F0AB4EF004AB7CD /* Account+OPMLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE8B1F0AB4EF004AB7CD /* Account+OPMLRepresentable.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 */; }; + 844BEE9B1F0AB4F8004AB7CD /* UnreadCountProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE971F0AB4F8004AB7CD /* UnreadCountProvider.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 844BEE661F0AB3C9004AB7CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 844BEE521F0AB3C8004AB7CD /* Project object */; + proxyType = 1; + remoteGlobalIDString = 844BEE5A1F0AB3C8004AB7CD; + remoteInfo = Data; + }; + 844BEEA21F0AB512004AB7CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84CFF4F41AC3C69700CEA6C8; + remoteInfo = RSCore; + }; + 844BEEA41F0AB512004AB7CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84CFF4FF1AC3C69700CEA6C8; + remoteInfo = RSCoreTests; + }; + 844BEEA61F0AB512004AB7CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 842DD7BC1E14993900E061EB; + remoteInfo = RSCoreiOS; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 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 = ""; }; + 844BEE781F0AB4B8004AB7CD /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; 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 = ""; }; + 844BEE821F0AB4D6004AB7CD /* Attachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = ""; }; + 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 = ""; }; + 844BEE8B1F0AB4EF004AB7CD /* Account+OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Account+OPMLRepresentable.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 = ""; }; + 844BEE971F0AB4F8004AB7CD /* UnreadCountProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnreadCountProvider.swift; sourceTree = ""; }; + 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 844BEE571F0AB3C8004AB7CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 843079FA1F0AB57F00B4B7F7 /* RSCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 844BEE611F0AB3C9004AB7CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 844BEE651F0AB3C9004AB7CD /* Data.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 844BEE511F0AB3C8004AB7CD = { + isa = PBXGroup; + children = ( + 844BEE781F0AB4B8004AB7CD /* Account.swift */, + 844BEE7A1F0AB4BE004AB7CD /* Folder.swift */, + 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */, + 844BEE7E1F0AB4CA004AB7CD /* Article.swift */, + 844BEE801F0AB4D0004AB7CD /* Author.swift */, + 844BEE821F0AB4D6004AB7CD /* Attachment.swift */, + 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */, + 844BEE861F0AB4E3004AB7CD /* BatchUpdates.swift */, + 844BEE881F0AB4E7004AB7CD /* Notifications.swift */, + 844BEE8A1F0AB4EF004AB7CD /* OPML */, + 844BEE931F0AB4F8004AB7CD /* Protocols */, + 844BEE761F0AB444004AB7CD /* Info.plist */, + 844BEE681F0AB3C9004AB7CD /* DataTests */, + 844BEE5C1F0AB3C8004AB7CD /* Products */, + 844BEEA81F0AB520004AB7CD /* Frameworks */, + ); + sourceTree = ""; + }; + 844BEE5C1F0AB3C8004AB7CD /* Products */ = { + isa = PBXGroup; + children = ( + 844BEE5B1F0AB3C8004AB7CD /* Data.framework */, + 844BEE641F0AB3C9004AB7CD /* DataTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 844BEE681F0AB3C9004AB7CD /* DataTests */ = { + isa = PBXGroup; + children = ( + 844BEE691F0AB3C9004AB7CD /* DataTests.swift */, + 844BEE6B1F0AB3C9004AB7CD /* Info.plist */, + ); + path = DataTests; + sourceTree = ""; + }; + 844BEE8A1F0AB4EF004AB7CD /* OPML */ = { + isa = PBXGroup; + children = ( + 844BEE8B1F0AB4EF004AB7CD /* Account+OPMLRepresentable.swift */, + 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 */, + 844BEE971F0AB4F8004AB7CD /* UnreadCountProvider.swift */, + ); + path = Protocols; + sourceTree = ""; + }; + 844BEE9D1F0AB512004AB7CD /* Products */ = { + isa = PBXGroup; + children = ( + 844BEEA31F0AB512004AB7CD /* RSCore.framework */, + 844BEEA51F0AB512004AB7CD /* RSCoreTests.xctest */, + 844BEEA71F0AB512004AB7CD /* RSCore.framework */, + ); + name = Products; + sourceTree = ""; + }; + 844BEEA81F0AB520004AB7CD /* Frameworks */ = { + isa = PBXGroup; + children = ( + 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 844BEE581F0AB3C8004AB7CD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 844BEE5A1F0AB3C8004AB7CD /* Data */ = { + isa = PBXNativeTarget; + buildConfigurationList = 844BEE6F1F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "Data" */; + buildPhases = ( + 844BEE561F0AB3C8004AB7CD /* Sources */, + 844BEE571F0AB3C8004AB7CD /* Frameworks */, + 844BEE581F0AB3C8004AB7CD /* Headers */, + 844BEE591F0AB3C8004AB7CD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Data; + productName = Data; + productReference = 844BEE5B1F0AB3C8004AB7CD /* Data.framework */; + productType = "com.apple.product-type.framework"; + }; + 844BEE631F0AB3C9004AB7CD /* DataTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 844BEE721F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "DataTests" */; + buildPhases = ( + 844BEE601F0AB3C9004AB7CD /* Sources */, + 844BEE611F0AB3C9004AB7CD /* Frameworks */, + 844BEE621F0AB3C9004AB7CD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 844BEE671F0AB3C9004AB7CD /* PBXTargetDependency */, + ); + name = DataTests; + productName = DataTests; + productReference = 844BEE641F0AB3C9004AB7CD /* DataTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 844BEE521F0AB3C8004AB7CD /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "Ranchero Software"; + TargetAttributes = { + 844BEE5A1F0AB3C8004AB7CD = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = 9C84TZ7Q6Z; + LastSwiftMigration = 0830; + ProvisioningStyle = Automatic; + }; + 844BEE631F0AB3C9004AB7CD = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = 9C84TZ7Q6Z; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 844BEE551F0AB3C8004AB7CD /* Build configuration list for PBXProject "Data" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 844BEE511F0AB3C8004AB7CD; + productRefGroup = 844BEE5C1F0AB3C8004AB7CD /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 844BEE9D1F0AB512004AB7CD /* Products */; + ProjectRef = 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 844BEE5A1F0AB3C8004AB7CD /* Data */, + 844BEE631F0AB3C9004AB7CD /* DataTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 844BEEA31F0AB512004AB7CD /* RSCore.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSCore.framework; + remoteRef = 844BEEA21F0AB512004AB7CD /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 844BEEA51F0AB512004AB7CD /* RSCoreTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSCoreTests.xctest; + remoteRef = 844BEEA41F0AB512004AB7CD /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 844BEEA71F0AB512004AB7CD /* RSCore.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSCore.framework; + remoteRef = 844BEEA61F0AB512004AB7CD /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 844BEE591F0AB3C8004AB7CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 844BEE621F0AB3C9004AB7CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 844BEE561F0AB3C8004AB7CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 844BEE911F0AB4EF004AB7CD /* Folder+OPMLRepresentable.swift in Sources */, + 844BEE901F0AB4EF004AB7CD /* Feed+OPMLRepresentable.swift in Sources */, + 844BEE7F1F0AB4CA004AB7CD /* Article.swift in Sources */, + 844BEE791F0AB4B8004AB7CD /* Account.swift in Sources */, + 844BEE7D1F0AB4C4004AB7CD /* Feed.swift in Sources */, + 844BEE891F0AB4E7004AB7CD /* Notifications.swift in Sources */, + 844BEE9A1F0AB4F8004AB7CD /* DisplayNameProvider.swift in Sources */, + 844BEE8F1F0AB4EF004AB7CD /* Account+OPMLRepresentable.swift in Sources */, + 844BEE991F0AB4F8004AB7CD /* Container.swift in Sources */, + 844BEE7B1F0AB4BE004AB7CD /* Folder.swift in Sources */, + 844BEE981F0AB4F8004AB7CD /* AccountDelegate.swift in Sources */, + 844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */, + 844BEE871F0AB4E3004AB7CD /* BatchUpdates.swift in Sources */, + 844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */, + 844BEE921F0AB4EF004AB7CD /* OPMLRepresentable.swift in Sources */, + 844BEE9B1F0AB4F8004AB7CD /* UnreadCountProvider.swift in Sources */, + 844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 844BEE601F0AB3C9004AB7CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 844BEE6A1F0AB3C9004AB7CD /* DataTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 844BEE671F0AB3C9004AB7CD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 844BEE5A1F0AB3C8004AB7CD /* Data */; + targetProxy = 844BEE661F0AB3C9004AB7CD /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 844BEE6D1F0AB3C9004AB7CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 844BEE6E1F0AB3C9004AB7CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 844BEE701F0AB3C9004AB7CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + 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.Data; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 844BEE711F0AB3C9004AB7CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + 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.Data; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 844BEE731F0AB3C9004AB7CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + INFOPLIST_FILE = DataTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DataTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 844BEE741F0AB3C9004AB7CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + INFOPLIST_FILE = DataTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DataTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 844BEE551F0AB3C8004AB7CD /* Build configuration list for PBXProject "Data" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 844BEE6D1F0AB3C9004AB7CD /* Debug */, + 844BEE6E1F0AB3C9004AB7CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 844BEE6F1F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "Data" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 844BEE701F0AB3C9004AB7CD /* Debug */, + 844BEE711F0AB3C9004AB7CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 844BEE721F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "DataTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 844BEE731F0AB3C9004AB7CD /* Debug */, + 844BEE741F0AB3C9004AB7CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 844BEE521F0AB3C8004AB7CD /* Project object */; +} diff --git a/Frameworks/DataModel/DataModel.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/Data/Data.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 70% rename from Frameworks/DataModel/DataModel.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Frameworks/Data/Data.xcodeproj/project.xcworkspace/contents.xcworkspacedata index a7300f614..958714b4f 100644 --- a/Frameworks/DataModel/DataModel.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/Frameworks/Data/Data.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:Data.xcodeproj"> diff --git a/Frameworks/Data/DataTests/DataTests.swift b/Frameworks/Data/DataTests/DataTests.swift new file mode 100644 index 000000000..3560bfcb7 --- /dev/null +++ b/Frameworks/Data/DataTests/DataTests.swift @@ -0,0 +1,36 @@ +// +// DataTests.swift +// DataTests +// +// Created by Brent Simmons on 7/3/17. +// Copyright © 2017 Ranchero Software. All rights reserved. +// + +import XCTest +@testable import Data + +class DataTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Frameworks/Data/DataTests/Info.plist b/Frameworks/Data/DataTests/Info.plist new file mode 100644 index 000000000..6c6c23c43 --- /dev/null +++ b/Frameworks/Data/DataTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Frameworks/DataModel/Feed.swift b/Frameworks/Data/Feed.swift similarity index 53% rename from Frameworks/DataModel/Feed.swift rename to Frameworks/Data/Feed.swift index 65f0f4330..dc0c89a9b 100644 --- a/Frameworks/DataModel/Feed.swift +++ b/Frameworks/Data/Feed.swift @@ -14,31 +14,43 @@ public final class Feed: UnreadCountProvider, DisplayNameProvider, Hashable { public let account: Account public let url: String public let feedID: String - public var homePageURL: String? public var name: String? public var editedName: String? + public var articles = Set
() + public var accountInfo: [String: Any]? //If account needs to store more data + public let hashValue: Int + public var nameForDisplay: String { get { return (editedName ?? name) ?? NSLocalizedString("Untitled", comment: "Feed name") } } - public var articles = Set
() - public var accountInfo: [String: Any]? //If account needs to store more data - + public var unreadCount = 0 { + didSet { + if unreadCount != oldValue { + postUnreadCountDidChangeNotification() + } + } + } + public init(account: Account, url: String, feedID: String) { self.account = account self.url = url self.feedID = feedID - self.hashValue = account.hashValue + url.hashValue + feedID.hashValue + self.hashValue = account.hashValue ^ url.hashValue ^ feedID.hashValue } - public fetchArticles() -> Set
{ - - articles = account.fetchArticles(self) - return articles + 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 { @@ -47,20 +59,3 @@ public final class Feed: UnreadCountProvider, DisplayNameProvider, Hashable { } } -public extension Feed: OPMLRepresentable { - - 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 new file mode 100644 index 000000000..be310d4b7 --- /dev/null +++ b/Frameworks/Data/Folder.swift @@ -0,0 +1,100 @@ +// +// 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: UnreadCountProvider { + + public let account: Account + public var nameForDisplay: String + var childObjects = [AnyObject]() + + init(account: Account, nameForDisplay: String) { + + self.account = account + self.nameForDisplay = nameForDisplay + + NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) + } + + // MARK: Notifications + + dynamic public func unreadCountDidChange(_ note: Notification) { + + guard let obj = note.object else { + return + } + let potentialChild = obj as AnyObject + if isChild(potentialChild) { + updateUnreadCount() + } + } + + // MARK: UnreadCountProvider + + 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/DataModel/Info.plist b/Frameworks/Data/Info.plist similarity index 90% rename from Frameworks/DataModel/Info.plist rename to Frameworks/Data/Info.plist index c5ede6b01..478d89397 100644 --- a/Frameworks/DataModel/Info.plist +++ b/Frameworks/Data/Info.plist @@ -19,7 +19,7 @@ CFBundleVersion $(CURRENT_PROJECT_VERSION) NSHumanReadableCopyright - Copyright © 2016 Ranchero Software, LLC. All rights reserved. + Copyright © 2017 Ranchero Software. All rights reserved. NSPrincipalClass diff --git a/Frameworks/DataModel/Notifications.swift b/Frameworks/Data/Notifications.swift similarity index 100% rename from Frameworks/DataModel/Notifications.swift rename to Frameworks/Data/Notifications.swift diff --git a/Frameworks/Data/OPML/Account+OPMLRepresentable.swift b/Frameworks/Data/OPML/Account+OPMLRepresentable.swift new file mode 100644 index 000000000..e021058bc --- /dev/null +++ b/Frameworks/Data/OPML/Account+OPMLRepresentable.swift @@ -0,0 +1,23 @@ +// +// 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/Data/OPML/Feed+OPMLRepresentable.swift b/Frameworks/Data/OPML/Feed+OPMLRepresentable.swift new file mode 100644 index 000000000..c7108f36c --- /dev/null +++ b/Frameworks/Data/OPML/Feed+OPMLRepresentable.swift @@ -0,0 +1,28 @@ +// +// 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 new file mode 100644 index 000000000..dab4ae4bd --- /dev/null +++ b/Frameworks/Data/OPML/Folder+OPMLRepresentable.swift @@ -0,0 +1,41 @@ +// +// 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/DataModel/OPMLRepresentable.swift b/Frameworks/Data/OPML/OPMLRepresentable.swift similarity index 100% rename from Frameworks/DataModel/OPMLRepresentable.swift rename to Frameworks/Data/OPML/OPMLRepresentable.swift diff --git a/Frameworks/DataModel/AccountDelegate.swift b/Frameworks/Data/Protocols/AccountDelegate.swift similarity index 75% rename from Frameworks/DataModel/AccountDelegate.swift rename to Frameworks/Data/Protocols/AccountDelegate.swift index d141ebe27..a2ae5f98c 100644 --- a/Frameworks/DataModel/AccountDelegate.swift +++ b/Frameworks/Data/Protocols/AccountDelegate.swift @@ -10,7 +10,7 @@ import Foundation public protocol AccountDelegate { - + func canAddItem(_ item: AnyObject, toContainer: Container) -> Bool } diff --git a/Frameworks/Data/Protocols/Container.swift b/Frameworks/Data/Protocols/Container.swift new file mode 100644 index 000000000..979187553 --- /dev/null +++ b/Frameworks/Data/Protocols/Container.swift @@ -0,0 +1,150 @@ +// +// Container.swift +// Evergreen +// +// Created by Brent Simmons on 4/17/16. +// Copyright © 2016 Ranchero Software, LLC. All rights reserved. +// + +import Foundation +import RSCore + +public typealias VisitBlock = (_ obj: AnyObject) -> Bool // Return true to stop + +extension NSNotification.Name { + + public static let ChildrenDidChange = Notification.Name("ChildrenDidChangeNotification") +} + +public protocol Container: class { + + //Recursive + func hasAtLeastOneFeed() -> Bool + func flattenedFeeds() -> Set + func existingFeed(with feedID: String) -> Feed? + func existingFeed(withURL url: String) -> Feed? + + func isChild(_ obj: AnyObject) -> Bool + + // visitBlock should return true to stop visiting. + // visitObjects returns true if a visitBlock returned true. + func visitObjects(_ recurse: Bool, _ visitBlock: VisitBlock) -> Bool + +// +//// func objectIsChild(_ obj: AnyObject) -> Bool +//// func objectIsDescendant(_ obj: AnyObject) -> Bool +//// +//// func fetchArticles() -> [Article] +// +// // visitBlock should return true to stop visiting. +// // visitObjects returns true if a visitBlock returned true. +//// func visitObjects(_ recurse: Bool, visitBlock: VisitBlock) -> Bool +//// func visitChildren(visitBlock: VisitBlock) -> Bool // Above with recurse = false +//// +//// func findObject(_ recurse: Bool, visitBlock: VisitBlock) -> AnyObject? +// +// func canAddItem(_ item: AnyObject) -> Bool +// func addItem(_ item: AnyObject) -> Bool // Return true even if item already exists. +// func addItems(_ items: [AnyObject]) -> Bool // Return true even if some items already exist. +// +// func canAddFolderWithName(_ folderName: String) -> Bool // Special case: folder with name exists. Return true in that case. +// func ensureFolderWithName(_ folderName: String) -> Folder? // Return folder even if item already exists. +// +// // Does not recurse. +// func existingFolderWithName(_ name: String) -> Folder? +// +// // Doesn't add feed. Just creates instance. +// func createFeedWithName(_ name: String?, editedName: String?, urlString: String) -> Feed? +// +// func deleteItems(_ items: [AnyObject]) +} + +public extension Container { + + func hasAtLeastOneFeed() -> Bool { + + let foundObject = findObject(true, visitBlock: { (oneDescendant) -> Bool in + return oneDescendant is Feed + }) + return foundObject != nil + } + + func existingFeed(with feedID: String) -> Feed? { + + let foundObject = findObject(true) { (oneDescendant) -> Bool in + if let oneFeed = oneDescendant as? Feed, oneFeed.feedID == feedID { + return true + } + return false + } + return foundObject as! Feed? + } + + func existingFeed(withURL url: String) -> Feed? { + + let foundObject = findObject(true) { (oneDescendant) -> Bool in + if let oneFeed = oneDescendant as? Feed, oneFeed.url == url { + return true + } + return false + } + return foundObject as! Feed? + } + + func visitChildren(visitBlock: VisitBlock) -> Bool { + + return visitObjects(false, visitBlock) + } + + func findObject(_ recurse: Bool, visitBlock: @escaping VisitBlock) -> AnyObject? { + + var foundObject: AnyObject? + + let _ = visitObjects(recurse) { (oneObject) in + + if let _ = foundObject { + return true + } + + if visitBlock(oneObject) { + foundObject = oneObject + return true + } + + return false + } + + return foundObject + } + + func objectIsChild(_ obj: AnyObject) -> Bool { + + return visitObjects(false) { (oneObject) in + return obj === oneObject + } + } + + func objectIsDescendant(_ obj: AnyObject) -> Bool { + + return visitObjects(true) { (oneObject) in + return obj === oneObject + } + } + + func existingFolderWithName(_ name: String) -> Folder? { + + let foundObject = findObject(false) { (oneObject) in + if let oneFolder = oneObject as? Folder, oneFolder.nameForDisplay == name { + return true + } + return false + } + return foundObject as! Folder? + } + + public func postChildrenDidChangeNotification() { + + NotificationCenter.default.post(name: .ChildrenDidChange, object: self) + } +} + diff --git a/Frameworks/DataModel/DisplayNameProviderProtocol.swift b/Frameworks/Data/Protocols/DisplayNameProvider.swift similarity index 100% rename from Frameworks/DataModel/DisplayNameProviderProtocol.swift rename to Frameworks/Data/Protocols/DisplayNameProvider.swift diff --git a/Frameworks/DataModel/UnreadCountProviderProtocol.swift b/Frameworks/Data/Protocols/UnreadCountProvider.swift similarity index 82% rename from Frameworks/DataModel/UnreadCountProviderProtocol.swift rename to Frameworks/Data/Protocols/UnreadCountProvider.swift index 43d1dccd2..2bd2e1702 100644 --- a/Frameworks/DataModel/UnreadCountProviderProtocol.swift +++ b/Frameworks/Data/Protocols/UnreadCountProvider.swift @@ -17,12 +17,11 @@ public protocol UnreadCountProvider { public func calculateUnreadCount(_ children: T) -> Int { - var updatedUnreadCount = 0 - - children.forEach { (oneChild) in + let updatedUnreadCount = children.reduce(0) { (result, oneChild) -> Int in if let oneUnreadCountProvider = oneChild as? UnreadCountProvider { - updatedUnreadCount += oneUnreadCountProvider.unreadCount + return result + oneUnreadCountProvider.unreadCount } + return result } return updatedUnreadCount diff --git a/Frameworks/DataModel/Account.swift b/Frameworks/DataModel/Account.swift deleted file mode 100644 index 95e74a9fb..000000000 --- a/Frameworks/DataModel/Account.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// Account.swift -// DataModel -// -// Created by Brent Simmons on 7/1/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public enum AccountType: Int { - - case onMyMac = 1 - case feedly = 16 - case feedbin - case feedWrangler - case newsBlur -} - -public final class Account: Container, PlistProvider { - - public let identifier: String - public let type: AccountType - public var nameForDisplay: String - public weak var delegate: AccountDelegate - - init(settingsFile: String, type: AccountType, dataFolder: String, identifier: String, delegate: AccountDelegate) { - - self.identifier = identifier - self.type = type - self.settingsFile = settingsFile - self.dataFolder = dataFolder - self.delegate = delegate - } -} diff --git a/Frameworks/DataModel/AccountProtocol.swift b/Frameworks/DataModel/AccountProtocol.swift deleted file mode 100644 index b457a928a..000000000 --- a/Frameworks/DataModel/AccountProtocol.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// AccountProtocol.swift -// Evergreen -// -// Created by Brent Simmons on 4/17/16. -// Copyright © 2016 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public protocol Account: class, Folder { - - var identifier: String {get} - var type: String {get} - var refreshInProgress: Bool {get} - - init(settingsFile: String, dataFolder: String, identifier: String) - - func refreshAll() - - func markArticles(_ articles: NSSet, statusKey: ArticleStatusKey, flag: Bool) - - func hasFeedWithURLString(_: String) -> Bool - - func importOPML(_: Any) - - func fetchArticles(for: [AnyObject]) -> [Article] -} - -public extension Account { - - func hasFeedWithURLString(_ urlString: String) -> Bool { - - if let _ = existingFeedWithURL(urlString) { - return true - } - return false - } - - public func postArticleStatusesDidChangeNotification(_ articles: NSSet) { - - NotificationCenter.default.post(name: .ArticleStatusesDidChange, object: self, userInfo: [articlesKey: articles]) - } -} diff --git a/Frameworks/DataModel/ArticleStatusProtocol.swift b/Frameworks/DataModel/ArticleStatusProtocol.swift deleted file mode 100644 index 7dd1b62a3..000000000 --- a/Frameworks/DataModel/ArticleStatusProtocol.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// ArticleStatusProtocol.swift -// Evergreen -// -// Created by Brent Simmons on 4/23/16. -// Copyright © 2016 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public enum ArticleStatusKey: String { - - case read = "read" - case starred = "starred" - case userDeleted = "userDeleted" -} - -public protocol ArticleStatus { - - var read: Bool {get set} - var starred: Bool {get set} - var userDeleted: Bool {get set} - var dateArrived: Date {get} - - func boolStatusForKey(_ articleStatusKey: ArticleStatusKey) -> Bool - func setBoolStatusForKey(_ status: Bool, articleStatusKey: ArticleStatusKey) -} - -public extension ArticleStatus { - - func boolStatusForKey(_ articleStatusKey: ArticleStatusKey) -> Bool { - - switch articleStatusKey { - - case .read: - return read - case .starred: - return starred - case .userDeleted: - return userDeleted - } - } -} diff --git a/Frameworks/DataModel/Container.swift b/Frameworks/DataModel/Container.swift deleted file mode 100644 index 78a9a0f9d..000000000 --- a/Frameworks/DataModel/Container.swift +++ /dev/null @@ -1,168 +0,0 @@ -// -// FolderProtocol.swift -// Evergreen -// -// Created by Brent Simmons on 4/17/16. -// Copyright © 2016 Ranchero Software, LLC. All rights reserved. -// - -import Foundation -import RSCore - -public typealias FolderVisitBlock = (_ obj: AnyObject) -> Bool - -public let FolderChildrenDidChangeNotification = "FolderChildNodesDidChangeNotification" - -public func FolderPostChildrenDidChangeNotification(_ folder: Folder) { - - NotificationCenter.default.post(name: NSNotification.Name(rawValue: FolderChildrenDidChangeNotification), object: folder) -} - -public protocol Container: class { - - var account: Account? {get} - - var hasAtLeastOneFeed: Bool {get} //Recursive - var flattenedFeeds: NSSet {get} - - func objectIsChild(_ obj: AnyObject) -> Bool - func objectIsDescendant(_ obj: AnyObject) -> Bool - - func fetchArticles() -> [Article] - - // visitBlock should return true to stop visiting. - // visitObjects returns true if a visitBlock returned true. - func visitObjects(_ recurse: Bool, visitBlock: FolderVisitBlock) -> Bool - func visitChildren(visitBlock: FolderVisitBlock) -> Bool // Above with recurse = false - - func findObject(_ recurse: Bool, visitBlock: FolderVisitBlock) -> AnyObject? - - func canAddItem(_ item: AnyObject) -> Bool - func addItem(_ item: AnyObject) -> Bool // Return true even if item already exists. - func addItems(_ items: [AnyObject]) -> Bool // Return true even if some items already exist. - - func canAddFolderWithName(_ folderName: String) -> Bool // Special case: folder with name exists. Return true in that case. - func ensureFolderWithName(_ folderName: String) -> Folder? // Return folder even if item already exists. - - // Recurses - func existingFeedWithID(_ feedID: String) -> Feed? - func existingFeedWithURL(_ urlString: String) -> Feed? - - // Does not recurse. - func existingFolderWithName(_ name: String) -> Folder? - - // Doesn't add feed. Just creates instance. - func createFeedWithName(_ name: String?, editedName: String?, urlString: String) -> Feed? - - func deleteItems(_ items: [AnyObject]) - - // Exporting OPML. - func opmlString(indentLevel: Int) -> String -} - -public extension Folder { - - var hasAtLeastOneFeed: Bool { - get { - return visitObjects(true) { (oneObject) in - - return oneObject is Feed - } - } - } - - func visitChildren(visitBlock: FolderVisitBlock) -> Bool { - - return visitObjects(false, visitBlock: visitBlock) - } - - func findObject(_ recurse: Bool, visitBlock: FolderVisitBlock) -> AnyObject? { - - var foundObject: AnyObject? - - let _ = visitObjects(recurse) { (oneObject) in - - if let _ = foundObject { - return true - } - - if visitBlock(oneObject) { - foundObject = oneObject - return true - } - - return false - } - - return foundObject - } - - func objectIsChild(_ obj: AnyObject) -> Bool { - - return visitObjects(false) { (oneObject) in - return obj === oneObject - } - } - - func objectIsDescendant(_ obj: AnyObject) -> Bool { - - return visitObjects(true) { (oneObject) in - return obj === oneObject - } - } - - func existingFolderWithName(_ name: String) -> Folder? { - - let foundObject = findObject(false) { (oneObject) in - if let oneFolder = oneObject as? Folder, oneFolder.nameForDisplay == name { - return true - } - return false - } - return foundObject as! Folder? - } - - func addItems(_ items: [AnyObject]) -> Bool { - - var atLeastOneItemAdded = false - items.forEach { (oneItem) in - if addItem(oneItem) { - atLeastOneItemAdded = true - } - } - return atLeastOneItemAdded - } - - 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 - - hasAtLeastOneChild = true - if let oneFolder = oneChild as? Folder { - s = s + oneFolder.opmlString(indentLevel: indentLevel + 1) - } - else if let oneFeed = oneChild as? Feed { - s = s + oneFeed.opmlString(indentLevel: indentLevel + 1) - } - - 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/DataModel/DataModel.xcodeproj/project.pbxproj b/Frameworks/DataModel/DataModel.xcodeproj/project.pbxproj deleted file mode 100644 index 49a932bf7..000000000 --- a/Frameworks/DataModel/DataModel.xcodeproj/project.pbxproj +++ /dev/null @@ -1,366 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 8439773E1DA07F2400F0FCBD /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8439773D1DA07F2400F0FCBD /* RSCore.framework */; }; - 8471A2CC1ED4CEEE008F099E /* AccountProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2C81ED4CEEE008F099E /* AccountProtocol.swift */; }; - 8471A2CE1ED4CEEE008F099E /* ArticleStatusProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2CA1ED4CEEE008F099E /* ArticleStatusProtocol.swift */; }; - 8471A2CF1ED4CEEE008F099E /* BatchUpdates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2CB1ED4CEEE008F099E /* BatchUpdates.swift */; }; - 8471A2D51ED4CEFA008F099E /* DisplayNameProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D01ED4CEFA008F099E /* DisplayNameProviderProtocol.swift */; }; - 8471A2D71ED4CEFA008F099E /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D21ED4CEFA008F099E /* Container.swift */; }; - 8471A2D81ED4CEFA008F099E /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D31ED4CEFA008F099E /* Notifications.swift */; }; - 8471A2D91ED4CEFA008F099E /* UnreadCountProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D41ED4CEFA008F099E /* UnreadCountProviderProtocol.swift */; }; - 84F466A61F08389400225386 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466A51F08389400225386 /* Account.swift */; }; - 84F466A81F083A2A00225386 /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466A71F083A2A00225386 /* Feed.swift */; }; - 84F466AA1F083B7A00225386 /* OPMLRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466A91F083B7A00225386 /* OPMLRepresentable.swift */; }; - 84F466AC1F083F2600225386 /* Article.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466AB1F083F2600225386 /* Article.swift */; }; - 84F466AE1F08435800225386 /* Author.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466AD1F08435800225386 /* Author.swift */; }; - 84F466B01F0862AF00225386 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466AF1F0862AF00225386 /* Attachment.swift */; }; - 84F466B21F0863D700225386 /* AccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466B11F0863D700225386 /* AccountDelegate.swift */; }; - 84F466B41F08725700225386 /* Folder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F466B31F08725700225386 /* Folder.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 8439773D1DA07F2400F0FCBD /* RSCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSCore.framework; path = "../../../../../Library/Developer/Xcode/DerivedData/Rainier-cidsoqwawkdqqphkdtrqrojskege/Build/Products/Debug/RSCore.framework"; sourceTree = ""; }; - 8471A2C81ED4CEEE008F099E /* AccountProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountProtocol.swift; sourceTree = ""; }; - 8471A2CA1ED4CEEE008F099E /* ArticleStatusProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleStatusProtocol.swift; sourceTree = ""; }; - 8471A2CB1ED4CEEE008F099E /* BatchUpdates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatchUpdates.swift; sourceTree = ""; }; - 8471A2D01ED4CEFA008F099E /* DisplayNameProviderProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayNameProviderProtocol.swift; sourceTree = ""; }; - 8471A2D21ED4CEFA008F099E /* Container.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; - 8471A2D31ED4CEFA008F099E /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; - 8471A2D41ED4CEFA008F099E /* UnreadCountProviderProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnreadCountProviderProtocol.swift; sourceTree = ""; }; - 8471A2DA1ED4CF01008F099E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 84C7AE921D68C558009FB883 /* DataModel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataModel.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 84F466A51F08389400225386 /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; - 84F466A71F083A2A00225386 /* Feed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = ""; }; - 84F466A91F083B7A00225386 /* OPMLRepresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OPMLRepresentable.swift; sourceTree = ""; }; - 84F466AB1F083F2600225386 /* Article.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Article.swift; sourceTree = ""; }; - 84F466AD1F08435800225386 /* Author.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Author.swift; sourceTree = ""; }; - 84F466AF1F0862AF00225386 /* Attachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = ""; }; - 84F466B11F0863D700225386 /* AccountDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountDelegate.swift; sourceTree = ""; }; - 84F466B31F08725700225386 /* Folder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 84C7AE8E1D68C558009FB883 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8439773E1DA07F2400F0FCBD /* RSCore.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 8439773C1DA07F2400F0FCBD /* Frameworks */ = { - isa = PBXGroup; - children = ( - 8439773D1DA07F2400F0FCBD /* RSCore.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 84C7AE881D68C558009FB883 = { - isa = PBXGroup; - children = ( - 84F466A51F08389400225386 /* Account.swift */, - 84F466B11F0863D700225386 /* AccountDelegate.swift */, - 84F466B31F08725700225386 /* Folder.swift */, - 84F466A71F083A2A00225386 /* Feed.swift */, - 84F466AB1F083F2600225386 /* Article.swift */, - 84F466AD1F08435800225386 /* Author.swift */, - 84F466AF1F0862AF00225386 /* Attachment.swift */, - 8471A2C81ED4CEEE008F099E /* AccountProtocol.swift */, - 8471A2CA1ED4CEEE008F099E /* ArticleStatusProtocol.swift */, - 8471A2CB1ED4CEEE008F099E /* BatchUpdates.swift */, - 8471A2D01ED4CEFA008F099E /* DisplayNameProviderProtocol.swift */, - 84F466A91F083B7A00225386 /* OPMLRepresentable.swift */, - 8471A2D21ED4CEFA008F099E /* Container.swift */, - 8471A2D31ED4CEFA008F099E /* Notifications.swift */, - 8471A2D41ED4CEFA008F099E /* UnreadCountProviderProtocol.swift */, - 8471A2DA1ED4CF01008F099E /* Info.plist */, - 84C7AE931D68C558009FB883 /* Products */, - 8439773C1DA07F2400F0FCBD /* Frameworks */, - ); - sourceTree = ""; - }; - 84C7AE931D68C558009FB883 /* Products */ = { - isa = PBXGroup; - children = ( - 84C7AE921D68C558009FB883 /* DataModel.framework */, - ); - name = Products; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 84C7AE8F1D68C558009FB883 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 84C7AE911D68C558009FB883 /* DataModel */ = { - isa = PBXNativeTarget; - buildConfigurationList = 84C7AE9A1D68C558009FB883 /* Build configuration list for PBXNativeTarget "DataModel" */; - buildPhases = ( - 84C7AE8D1D68C558009FB883 /* Sources */, - 84C7AE8E1D68C558009FB883 /* Frameworks */, - 84C7AE8F1D68C558009FB883 /* Headers */, - 84C7AE901D68C558009FB883 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = DataModel; - productName = DataModel; - productReference = 84C7AE921D68C558009FB883 /* DataModel.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 84C7AE891D68C558009FB883 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0830; - ORGANIZATIONNAME = "Ranchero Software, LLC"; - TargetAttributes = { - 84C7AE911D68C558009FB883 = { - CreatedOnToolsVersion = 8.0; - LastSwiftMigration = 0800; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 84C7AE8C1D68C558009FB883 /* Build configuration list for PBXProject "DataModel" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 84C7AE881D68C558009FB883; - productRefGroup = 84C7AE931D68C558009FB883 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 84C7AE911D68C558009FB883 /* DataModel */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 84C7AE901D68C558009FB883 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 84C7AE8D1D68C558009FB883 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 84F466AC1F083F2600225386 /* Article.swift in Sources */, - 8471A2CC1ED4CEEE008F099E /* AccountProtocol.swift in Sources */, - 84F466A81F083A2A00225386 /* Feed.swift in Sources */, - 84F466A61F08389400225386 /* Account.swift in Sources */, - 8471A2CF1ED4CEEE008F099E /* BatchUpdates.swift in Sources */, - 8471A2CE1ED4CEEE008F099E /* ArticleStatusProtocol.swift in Sources */, - 84F466B01F0862AF00225386 /* Attachment.swift in Sources */, - 8471A2D91ED4CEFA008F099E /* UnreadCountProviderProtocol.swift in Sources */, - 84F466B21F0863D700225386 /* AccountDelegate.swift in Sources */, - 8471A2D51ED4CEFA008F099E /* DisplayNameProviderProtocol.swift in Sources */, - 84F466AE1F08435800225386 /* Author.swift in Sources */, - 84F466B41F08725700225386 /* Folder.swift in Sources */, - 8471A2D81ED4CEFA008F099E /* Notifications.swift in Sources */, - 84F466AA1F083B7A00225386 /* OPMLRepresentable.swift in Sources */, - 8471A2D71ED4CEFA008F099E /* Container.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 84C7AE981D68C558009FB883 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 84C7AE991D68C558009FB883 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 84C7AE9B1D68C558009FB883 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - COMBINE_HIDPI_IMAGES = YES; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - 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.DataModel; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - }; - name = Debug; - }; - 84C7AE9C1D68C558009FB883 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - COMBINE_HIDPI_IMAGES = YES; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - 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.DataModel; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 84C7AE8C1D68C558009FB883 /* Build configuration list for PBXProject "DataModel" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84C7AE981D68C558009FB883 /* Debug */, - 84C7AE991D68C558009FB883 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 84C7AE9A1D68C558009FB883 /* Build configuration list for PBXNativeTarget "DataModel" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84C7AE9B1D68C558009FB883 /* Debug */, - 84C7AE9C1D68C558009FB883 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 84C7AE891D68C558009FB883 /* Project object */; -} diff --git a/Frameworks/DataModel/Folder.swift b/Frameworks/DataModel/Folder.swift deleted file mode 100644 index 3a85778a8..000000000 --- a/Frameworks/DataModel/Folder.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// Folder.swift -// DataModel -// -// Created by Brent Simmons on 7/1/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import Foundation - -public class Folder: Container { - - -} diff --git a/Frameworks/Database/Database.xcodeproj/project.pbxproj b/Frameworks/Database/Database.xcodeproj/project.pbxproj new file mode 100644 index 000000000..ecadcbd18 --- /dev/null +++ b/Frameworks/Database/Database.xcodeproj/project.pbxproj @@ -0,0 +1,420 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 844BEE411F0AB3AB004AB7CD /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE371F0AB3AA004AB7CD /* Database.framework */; }; + 844BEE461F0AB3AB004AB7CD /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */; }; + 844BEE481F0AB3AB004AB7CD /* Database.h in Headers */ = {isa = PBXBuildFile; fileRef = 844BEE3A1F0AB3AA004AB7CD /* Database.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 844BEE421F0AB3AB004AB7CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 844BEE2E1F0AB3AA004AB7CD /* Project object */; + proxyType = 1; + remoteGlobalIDString = 844BEE361F0AB3AA004AB7CD; + remoteInfo = Database; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 844BEE371F0AB3AA004AB7CD /* Database.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Database.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 844BEE3A1F0AB3AA004AB7CD /* Database.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Database.h; sourceTree = ""; }; + 844BEE3B1F0AB3AA004AB7CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatabaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseTests.swift; sourceTree = ""; }; + 844BEE471F0AB3AB004AB7CD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 844BEE331F0AB3AA004AB7CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 844BEE3D1F0AB3AB004AB7CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 844BEE411F0AB3AB004AB7CD /* Database.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 844BEE2D1F0AB3AA004AB7CD = { + isa = PBXGroup; + children = ( + 844BEE391F0AB3AA004AB7CD /* Database */, + 844BEE441F0AB3AB004AB7CD /* DatabaseTests */, + 844BEE381F0AB3AA004AB7CD /* Products */, + ); + sourceTree = ""; + }; + 844BEE381F0AB3AA004AB7CD /* Products */ = { + isa = PBXGroup; + children = ( + 844BEE371F0AB3AA004AB7CD /* Database.framework */, + 844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 844BEE391F0AB3AA004AB7CD /* Database */ = { + isa = PBXGroup; + children = ( + 844BEE3A1F0AB3AA004AB7CD /* Database.h */, + 844BEE3B1F0AB3AA004AB7CD /* Info.plist */, + ); + path = Database; + sourceTree = ""; + }; + 844BEE441F0AB3AB004AB7CD /* DatabaseTests */ = { + isa = PBXGroup; + children = ( + 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */, + 844BEE471F0AB3AB004AB7CD /* Info.plist */, + ); + path = DatabaseTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 844BEE341F0AB3AA004AB7CD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 844BEE481F0AB3AB004AB7CD /* Database.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 844BEE361F0AB3AA004AB7CD /* Database */ = { + isa = PBXNativeTarget; + buildConfigurationList = 844BEE4B1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "Database" */; + buildPhases = ( + 844BEE321F0AB3AA004AB7CD /* Sources */, + 844BEE331F0AB3AA004AB7CD /* Frameworks */, + 844BEE341F0AB3AA004AB7CD /* Headers */, + 844BEE351F0AB3AA004AB7CD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Database; + productName = Database; + productReference = 844BEE371F0AB3AA004AB7CD /* Database.framework */; + productType = "com.apple.product-type.framework"; + }; + 844BEE3F1F0AB3AB004AB7CD /* DatabaseTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 844BEE4E1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "DatabaseTests" */; + buildPhases = ( + 844BEE3C1F0AB3AB004AB7CD /* Sources */, + 844BEE3D1F0AB3AB004AB7CD /* Frameworks */, + 844BEE3E1F0AB3AB004AB7CD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 844BEE431F0AB3AB004AB7CD /* PBXTargetDependency */, + ); + name = DatabaseTests; + productName = DatabaseTests; + productReference = 844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 844BEE2E1F0AB3AA004AB7CD /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "Ranchero Software"; + TargetAttributes = { + 844BEE361F0AB3AA004AB7CD = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = 9C84TZ7Q6Z; + ProvisioningStyle = Automatic; + }; + 844BEE3F1F0AB3AB004AB7CD = { + CreatedOnToolsVersion = 8.3.2; + DevelopmentTeam = 9C84TZ7Q6Z; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 844BEE311F0AB3AA004AB7CD /* Build configuration list for PBXProject "Database" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 844BEE2D1F0AB3AA004AB7CD; + productRefGroup = 844BEE381F0AB3AA004AB7CD /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 844BEE361F0AB3AA004AB7CD /* Database */, + 844BEE3F1F0AB3AB004AB7CD /* DatabaseTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 844BEE351F0AB3AA004AB7CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 844BEE3E1F0AB3AB004AB7CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 844BEE321F0AB3AA004AB7CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 844BEE3C1F0AB3AB004AB7CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 844BEE461F0AB3AB004AB7CD /* DatabaseTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 844BEE431F0AB3AB004AB7CD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 844BEE361F0AB3AA004AB7CD /* Database */; + targetProxy = 844BEE421F0AB3AB004AB7CD /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 844BEE491F0AB3AB004AB7CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 844BEE4A1F0AB3AB004AB7CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 844BEE4C1F0AB3AB004AB7CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Database/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Database; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 844BEE4D1F0AB3AB004AB7CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + INFOPLIST_FILE = Database/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Database; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; + 844BEE4F1F0AB3AB004AB7CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + INFOPLIST_FILE = DatabaseTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DatabaseTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 844BEE501F0AB3AB004AB7CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = 9C84TZ7Q6Z; + INFOPLIST_FILE = DatabaseTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DatabaseTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 844BEE311F0AB3AA004AB7CD /* Build configuration list for PBXProject "Database" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 844BEE491F0AB3AB004AB7CD /* Debug */, + 844BEE4A1F0AB3AB004AB7CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 844BEE4B1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "Database" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 844BEE4C1F0AB3AB004AB7CD /* Debug */, + 844BEE4D1F0AB3AB004AB7CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + 844BEE4E1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "DatabaseTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 844BEE4F1F0AB3AB004AB7CD /* Debug */, + 844BEE501F0AB3AB004AB7CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 844BEE2E1F0AB3AA004AB7CD /* Project object */; +} diff --git a/Frameworks/Database/Database.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/Database/Database.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..54e5cff2d --- /dev/null +++ b/Frameworks/Database/Database.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Frameworks/Database/Database/Database.h b/Frameworks/Database/Database/Database.h new file mode 100644 index 000000000..feabeea49 --- /dev/null +++ b/Frameworks/Database/Database/Database.h @@ -0,0 +1,19 @@ +// +// Database.h +// Database +// +// Created by Brent Simmons on 7/3/17. +// Copyright © 2017 Ranchero Software. All rights reserved. +// + +#import + +//! Project version number for Database. +FOUNDATION_EXPORT double DatabaseVersionNumber; + +//! Project version string for Database. +FOUNDATION_EXPORT const unsigned char DatabaseVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Frameworks/Database/Database/Info.plist b/Frameworks/Database/Database/Info.plist new file mode 100644 index 000000000..478d89397 --- /dev/null +++ b/Frameworks/Database/Database/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2017 Ranchero Software. All rights reserved. + NSPrincipalClass + + + diff --git a/Frameworks/Database/DatabaseTests/DatabaseTests.swift b/Frameworks/Database/DatabaseTests/DatabaseTests.swift new file mode 100644 index 000000000..036317c2b --- /dev/null +++ b/Frameworks/Database/DatabaseTests/DatabaseTests.swift @@ -0,0 +1,36 @@ +// +// DatabaseTests.swift +// DatabaseTests +// +// Created by Brent Simmons on 7/3/17. +// Copyright © 2017 Ranchero Software. All rights reserved. +// + +import XCTest +@testable import Database + +class DatabaseTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Frameworks/Database/DatabaseTests/Info.plist b/Frameworks/Database/DatabaseTests/Info.plist new file mode 100644 index 000000000..6c6c23c43 --- /dev/null +++ b/Frameworks/Database/DatabaseTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Frameworks/RSCore/RSCore/PlistProviderProtocol.swift b/Frameworks/RSCore/RSCore/PlistProviderProtocol.swift index 040ffca61..ca38aafd1 100755 --- a/Frameworks/RSCore/RSCore/PlistProviderProtocol.swift +++ b/Frameworks/RSCore/RSCore/PlistProviderProtocol.swift @@ -15,5 +15,5 @@ import Foundation public protocol PlistProvider: class { - var plist: AnyObject? {get} + func plist() -> AnyObject? }