Add DataModel framework.
This commit is contained in:
parent
dec10ad0a1
commit
91d81831e9
@ -7,6 +7,8 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
8471A2C41ED4CEBF008F099E /* DataModel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8471A2B71ED4CEAD008F099E /* DataModel.framework */; };
|
||||||
|
8471A2C51ED4CEBF008F099E /* DataModel.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8471A2B71ED4CEAD008F099E /* DataModel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
849C64641ED37A5D003D8FC0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C64631ED37A5D003D8FC0 /* AppDelegate.swift */; };
|
849C64641ED37A5D003D8FC0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C64631ED37A5D003D8FC0 /* AppDelegate.swift */; };
|
||||||
849C64661ED37A5D003D8FC0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C64651ED37A5D003D8FC0 /* ViewController.swift */; };
|
849C64661ED37A5D003D8FC0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849C64651ED37A5D003D8FC0 /* ViewController.swift */; };
|
||||||
849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849C64671ED37A5D003D8FC0 /* Assets.xcassets */; };
|
849C64681ED37A5D003D8FC0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849C64671ED37A5D003D8FC0 /* Assets.xcassets */; };
|
||||||
@ -31,6 +33,20 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
8471A2B61ED4CEAD008F099E /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 8471A2B21ED4CEAD008F099E /* DataModel.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 84C7AE921D68C558009FB883;
|
||||||
|
remoteInfo = DataModel;
|
||||||
|
};
|
||||||
|
8471A2C61ED4CEBF008F099E /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 8471A2B21ED4CEAD008F099E /* DataModel.xcodeproj */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 84C7AE911D68C558009FB883;
|
||||||
|
remoteInfo = DataModel;
|
||||||
|
};
|
||||||
849C64721ED37A5D003D8FC0 /* PBXContainerItemProxy */ = {
|
849C64721ED37A5D003D8FC0 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 849C64581ED37A5D003D8FC0 /* Project object */;
|
containerPortal = 849C64581ED37A5D003D8FC0 /* Project object */;
|
||||||
@ -249,6 +265,7 @@
|
|||||||
84B06FFE1ED3818D00F0B54B /* RSTree.framework in Embed Frameworks */,
|
84B06FFE1ED3818D00F0B54B /* RSTree.framework in Embed Frameworks */,
|
||||||
84B06FAF1ED37DBD00F0B54B /* RSCore.framework in Embed Frameworks */,
|
84B06FAF1ED37DBD00F0B54B /* RSCore.framework in Embed Frameworks */,
|
||||||
84B06FD01ED37F7D00F0B54B /* DB5.framework in Embed Frameworks */,
|
84B06FD01ED37F7D00F0B54B /* DB5.framework in Embed Frameworks */,
|
||||||
|
8471A2C51ED4CEBF008F099E /* DataModel.framework in Embed Frameworks */,
|
||||||
84B06FC31ED37E9600F0B54B /* RSWeb.framework in Embed Frameworks */,
|
84B06FC31ED37E9600F0B54B /* RSWeb.framework in Embed Frameworks */,
|
||||||
84B06F831ED37BDD00F0B54B /* RSXML.framework in Embed Frameworks */,
|
84B06F831ED37BDD00F0B54B /* RSXML.framework in Embed Frameworks */,
|
||||||
);
|
);
|
||||||
@ -258,6 +275,7 @@
|
|||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
8471A2B21ED4CEAD008F099E /* DataModel.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = DataModel.xcodeproj; path = Frameworks/DataModel/DataModel.xcodeproj; sourceTree = "<group>"; };
|
||||||
849C64601ED37A5D003D8FC0 /* Evergreen.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Evergreen.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
849C64601ED37A5D003D8FC0 /* Evergreen.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Evergreen.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
849C64631ED37A5D003D8FC0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = Evergreen/AppDelegate.swift; sourceTree = "<group>"; };
|
849C64631ED37A5D003D8FC0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = Evergreen/AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
849C64651ED37A5D003D8FC0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = Evergreen/ViewController.swift; sourceTree = "<group>"; };
|
849C64651ED37A5D003D8FC0 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = Evergreen/ViewController.swift; sourceTree = "<group>"; };
|
||||||
@ -288,6 +306,7 @@
|
|||||||
84B06FFD1ED3818D00F0B54B /* RSTree.framework in Frameworks */,
|
84B06FFD1ED3818D00F0B54B /* RSTree.framework in Frameworks */,
|
||||||
84B06FAE1ED37DBD00F0B54B /* RSCore.framework in Frameworks */,
|
84B06FAE1ED37DBD00F0B54B /* RSCore.framework in Frameworks */,
|
||||||
84B06FCF1ED37F7D00F0B54B /* DB5.framework in Frameworks */,
|
84B06FCF1ED37F7D00F0B54B /* DB5.framework in Frameworks */,
|
||||||
|
8471A2C41ED4CEBF008F099E /* DataModel.framework in Frameworks */,
|
||||||
84B06FC21ED37E9600F0B54B /* RSWeb.framework in Frameworks */,
|
84B06FC21ED37E9600F0B54B /* RSWeb.framework in Frameworks */,
|
||||||
84B06F821ED37BDD00F0B54B /* RSXML.framework in Frameworks */,
|
84B06F821ED37BDD00F0B54B /* RSXML.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
@ -303,6 +322,14 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
8471A2B31ED4CEAD008F099E /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8471A2B71ED4CEAD008F099E /* DataModel.framework */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
849C64571ED37A5D003D8FC0 = {
|
849C64571ED37A5D003D8FC0 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -313,6 +340,7 @@
|
|||||||
849C646C1ED37A5D003D8FC0 /* Info.plist */,
|
849C646C1ED37A5D003D8FC0 /* Info.plist */,
|
||||||
849C64741ED37A5D003D8FC0 /* EvergreenTests */,
|
849C64741ED37A5D003D8FC0 /* EvergreenTests */,
|
||||||
849C64611ED37A5D003D8FC0 /* Products */,
|
849C64611ED37A5D003D8FC0 /* Products */,
|
||||||
|
8471A2B21ED4CEAD008F099E /* DataModel.xcodeproj */,
|
||||||
84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */,
|
84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */,
|
||||||
84B06FA21ED37DAC00F0B54B /* RSCore.xcodeproj */,
|
84B06FA21ED37DAC00F0B54B /* RSCore.xcodeproj */,
|
||||||
84B06F961ED37DA000F0B54B /* RSDatabase.xcodeproj */,
|
84B06F961ED37DA000F0B54B /* RSDatabase.xcodeproj */,
|
||||||
@ -441,6 +469,7 @@
|
|||||||
84B06FEC1ED3803A00F0B54B /* PBXTargetDependency */,
|
84B06FEC1ED3803A00F0B54B /* PBXTargetDependency */,
|
||||||
84B070001ED3818D00F0B54B /* PBXTargetDependency */,
|
84B070001ED3818D00F0B54B /* PBXTargetDependency */,
|
||||||
84B0700D1ED3822600F0B54B /* PBXTargetDependency */,
|
84B0700D1ED3822600F0B54B /* PBXTargetDependency */,
|
||||||
|
8471A2C71ED4CEBF008F099E /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = Evergreen;
|
name = Evergreen;
|
||||||
productName = Evergreen;
|
productName = Evergreen;
|
||||||
@ -500,6 +529,10 @@
|
|||||||
productRefGroup = 849C64611ED37A5D003D8FC0 /* Products */;
|
productRefGroup = 849C64611ED37A5D003D8FC0 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectReferences = (
|
projectReferences = (
|
||||||
|
{
|
||||||
|
ProductGroup = 8471A2B31ED4CEAD008F099E /* Products */;
|
||||||
|
ProjectRef = 8471A2B21ED4CEAD008F099E /* DataModel.xcodeproj */;
|
||||||
|
},
|
||||||
{
|
{
|
||||||
ProductGroup = 84B06FC71ED37F7200F0B54B /* Products */;
|
ProductGroup = 84B06FC71ED37F7200F0B54B /* Products */;
|
||||||
ProjectRef = 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */;
|
ProjectRef = 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */;
|
||||||
@ -542,6 +575,13 @@
|
|||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXReferenceProxy section */
|
/* Begin PBXReferenceProxy section */
|
||||||
|
8471A2B71ED4CEAD008F099E /* DataModel.framework */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = wrapper.framework;
|
||||||
|
path = DataModel.framework;
|
||||||
|
remoteRef = 8471A2B61ED4CEAD008F099E /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
84B06F7D1ED37BCA00F0B54B /* RSXML.framework */ = {
|
84B06F7D1ED37BCA00F0B54B /* RSXML.framework */ = {
|
||||||
isa = PBXReferenceProxy;
|
isa = PBXReferenceProxy;
|
||||||
fileType = wrapper.framework;
|
fileType = wrapper.framework;
|
||||||
@ -724,6 +764,11 @@
|
|||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
|
8471A2C71ED4CEBF008F099E /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
name = DataModel;
|
||||||
|
targetProxy = 8471A2C61ED4CEBF008F099E /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
849C64731ED37A5D003D8FC0 /* PBXTargetDependency */ = {
|
849C64731ED37A5D003D8FC0 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = 849C645F1ED37A5D003D8FC0 /* Evergreen */;
|
target = 849C645F1ED37A5D003D8FC0 /* Evergreen */;
|
||||||
|
44
Frameworks/DataModel/AccountProtocol.swift
Normal file
44
Frameworks/DataModel/AccountProtocol.swift
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// AccountProtocol.swift
|
||||||
|
// Rainier
|
||||||
|
//
|
||||||
|
// 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])
|
||||||
|
}
|
||||||
|
}
|
68
Frameworks/DataModel/ArticleProtocol.swift
Normal file
68
Frameworks/DataModel/ArticleProtocol.swift
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// ArticleProtocol.swift
|
||||||
|
// Rainier
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 4/23/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol Article: class {
|
||||||
|
|
||||||
|
var account: Account? {get}
|
||||||
|
var feedID: String {get}
|
||||||
|
var feed: Feed? {get}
|
||||||
|
var articleID: String {get}
|
||||||
|
var status: ArticleStatus! {get}
|
||||||
|
|
||||||
|
var guid: String? {get}
|
||||||
|
var title: String? {get}
|
||||||
|
var body: String? {get}
|
||||||
|
var link: String? {get}
|
||||||
|
var permalink: String? {get}
|
||||||
|
var author: String? {get}
|
||||||
|
|
||||||
|
var datePublished: Date? {get}
|
||||||
|
var logicalDatePublished: Date {get} //datePublished or something reasonable.
|
||||||
|
var dateModified: Date? {get}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension Article {
|
||||||
|
|
||||||
|
var feed: Feed? {
|
||||||
|
get {
|
||||||
|
return account?.existingFeedWithID(feedID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var logicalDatePublished: Date {
|
||||||
|
get {
|
||||||
|
if let d = datePublished {
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
if let d = dateModified {
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
return status.dateArrived as Date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func articleArraysAreIdentical(array1: [Article], array2: [Article]) -> Bool {
|
||||||
|
|
||||||
|
if array1.count != array2.count {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = 0
|
||||||
|
for oneItem in array1 {
|
||||||
|
if oneItem !== array2[index] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
index = index + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
43
Frameworks/DataModel/ArticleStatusProtocol.swift
Normal file
43
Frameworks/DataModel/ArticleStatusProtocol.swift
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// ArticleStatusProtocol.swift
|
||||||
|
// Rainier
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
Frameworks/DataModel/BatchUpdates.swift
Normal file
76
Frameworks/DataModel/BatchUpdates.swift
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// BatchUpdates.swift
|
||||||
|
// DataModel
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 9/12/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
private final class BatchUpdatesTracker {
|
||||||
|
|
||||||
|
private var batchUpdatesCount = 0
|
||||||
|
|
||||||
|
var isPerformingBatchUpdates: Bool {
|
||||||
|
get {
|
||||||
|
return batchUpdatesCount > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func incrementBatchUpdatesCount() {
|
||||||
|
|
||||||
|
batchUpdatesCount = batchUpdatesCount + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func decrementBatchUpdatesCount() {
|
||||||
|
|
||||||
|
batchUpdatesCount = batchUpdatesCount - 1
|
||||||
|
|
||||||
|
if batchUpdatesCount < 1 {
|
||||||
|
|
||||||
|
if batchUpdatesCount < 0 {
|
||||||
|
assertionFailure("Batch updates count should never be below 0.")
|
||||||
|
batchUpdatesCount = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
batchUpdatesCount = 0
|
||||||
|
postDataModelDidPerformBatchUpdates()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func postDataModelDidPerformBatchUpdates() {
|
||||||
|
|
||||||
|
NotificationCenter.default.post(name: .DataModelDidPerformBatchUpdates, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate let batchUpdatesTracker = BatchUpdatesTracker()
|
||||||
|
|
||||||
|
public func dataModelIsPerformingBatchUpdates() -> Bool {
|
||||||
|
|
||||||
|
return batchUpdatesTracker.isPerformingBatchUpdates
|
||||||
|
}
|
||||||
|
|
||||||
|
public typealias BatchUpdatesBlock = () -> Void
|
||||||
|
|
||||||
|
public func performDataModelBatchUpdates(_ batchUpdatesBlock: BatchUpdatesBlock) {
|
||||||
|
|
||||||
|
startDataModelBatchUpdates()
|
||||||
|
|
||||||
|
batchUpdatesBlock()
|
||||||
|
|
||||||
|
endDataModelBatchUpdates()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func startDataModelBatchUpdates() {
|
||||||
|
|
||||||
|
batchUpdatesTracker.incrementBatchUpdatesCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func endDataModelBatchUpdates() {
|
||||||
|
|
||||||
|
batchUpdatesTracker.decrementBatchUpdatesCount()
|
||||||
|
}
|
||||||
|
|
340
Frameworks/DataModel/DataModel.xcodeproj/project.pbxproj
Normal file
340
Frameworks/DataModel/DataModel.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
// !$*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 */; };
|
||||||
|
8471A2CD1ED4CEEE008F099E /* ArticleProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2C91ED4CEEE008F099E /* ArticleProtocol.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 */; };
|
||||||
|
8471A2D61ED4CEFA008F099E /* FeedProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D11ED4CEFA008F099E /* FeedProtocol.swift */; };
|
||||||
|
8471A2D71ED4CEFA008F099E /* FolderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D21ED4CEFA008F099E /* FolderProtocol.swift */; };
|
||||||
|
8471A2D81ED4CEFA008F099E /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D31ED4CEFA008F099E /* Notifications.swift */; };
|
||||||
|
8471A2D91ED4CEFA008F099E /* UnreadCountProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8471A2D41ED4CEFA008F099E /* UnreadCountProviderProtocol.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 = "<group>"; };
|
||||||
|
8471A2C81ED4CEEE008F099E /* AccountProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2C91ED4CEEE008F099E /* ArticleProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2CA1ED4CEEE008F099E /* ArticleStatusProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleStatusProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2CB1ED4CEEE008F099E /* BatchUpdates.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatchUpdates.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2D01ED4CEFA008F099E /* DisplayNameProviderProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplayNameProviderProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2D11ED4CEFA008F099E /* FeedProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2D21ED4CEFA008F099E /* FolderProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolderProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2D31ED4CEFA008F099E /* Notifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2D41ED4CEFA008F099E /* UnreadCountProviderProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnreadCountProviderProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
8471A2DA1ED4CF01008F099E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
84C7AE921D68C558009FB883 /* DataModel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataModel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
/* 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 = "<group>";
|
||||||
|
};
|
||||||
|
84C7AE881D68C558009FB883 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8471A2C81ED4CEEE008F099E /* AccountProtocol.swift */,
|
||||||
|
8471A2C91ED4CEEE008F099E /* ArticleProtocol.swift */,
|
||||||
|
8471A2CA1ED4CEEE008F099E /* ArticleStatusProtocol.swift */,
|
||||||
|
8471A2CB1ED4CEEE008F099E /* BatchUpdates.swift */,
|
||||||
|
8471A2D01ED4CEFA008F099E /* DisplayNameProviderProtocol.swift */,
|
||||||
|
8471A2D11ED4CEFA008F099E /* FeedProtocol.swift */,
|
||||||
|
8471A2D21ED4CEFA008F099E /* FolderProtocol.swift */,
|
||||||
|
8471A2D31ED4CEFA008F099E /* Notifications.swift */,
|
||||||
|
8471A2D41ED4CEFA008F099E /* UnreadCountProviderProtocol.swift */,
|
||||||
|
8471A2DA1ED4CF01008F099E /* Info.plist */,
|
||||||
|
84C7AE931D68C558009FB883 /* Products */,
|
||||||
|
8439773C1DA07F2400F0FCBD /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
84C7AE931D68C558009FB883 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
84C7AE921D68C558009FB883 /* DataModel.framework */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* 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 = 0800;
|
||||||
|
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 = (
|
||||||
|
8471A2CC1ED4CEEE008F099E /* AccountProtocol.swift in Sources */,
|
||||||
|
8471A2D61ED4CEFA008F099E /* FeedProtocol.swift in Sources */,
|
||||||
|
8471A2CF1ED4CEEE008F099E /* BatchUpdates.swift in Sources */,
|
||||||
|
8471A2CE1ED4CEEE008F099E /* ArticleStatusProtocol.swift in Sources */,
|
||||||
|
8471A2D91ED4CEFA008F099E /* UnreadCountProviderProtocol.swift in Sources */,
|
||||||
|
8471A2CD1ED4CEEE008F099E /* ArticleProtocol.swift in Sources */,
|
||||||
|
8471A2D51ED4CEFA008F099E /* DisplayNameProviderProtocol.swift in Sources */,
|
||||||
|
8471A2D81ED4CEFA008F099E /* Notifications.swift in Sources */,
|
||||||
|
8471A2D71ED4CEFA008F099E /* FolderProtocol.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_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_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 */;
|
||||||
|
}
|
7
Frameworks/DataModel/DataModel.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
Frameworks/DataModel/DataModel.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:DataModel.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
15
Frameworks/DataModel/DisplayNameProviderProtocol.swift
Normal file
15
Frameworks/DataModel/DisplayNameProviderProtocol.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// DisplayNameProviderProtocol.swift
|
||||||
|
// DataModel
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 7/28/16.
|
||||||
|
// Copyright © 2016 Ranchero Software. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol DisplayNameProvider {
|
||||||
|
|
||||||
|
var nameForDisplay: String {get}
|
||||||
|
}
|
||||||
|
|
45
Frameworks/DataModel/FeedProtocol.swift
Normal file
45
Frameworks/DataModel/FeedProtocol.swift
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// FeedProtocol.swift
|
||||||
|
// Rainier
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 4/23/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import RSCore
|
||||||
|
|
||||||
|
public protocol Feed: class, UnreadCountProvider, DisplayNameProvider {
|
||||||
|
|
||||||
|
var account: Account {get}
|
||||||
|
var url: String {get}
|
||||||
|
var feedID: String {get}
|
||||||
|
var homePageURL: String? {get}
|
||||||
|
var name: String? {get}
|
||||||
|
var editedName: String? {get}
|
||||||
|
var nameForDisplay: String {get}
|
||||||
|
// var articles: NSSet {get}
|
||||||
|
|
||||||
|
init(account: Account, url: String, feedID: String)
|
||||||
|
|
||||||
|
// Exporting OPML.
|
||||||
|
func opmlString(indentLevel: Int) -> String
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension Feed {
|
||||||
|
|
||||||
|
func opmlString(indentLevel: Int) -> String {
|
||||||
|
|
||||||
|
let escapedName = nameForDisplay.rs_stringByEscapingSpecialXMLCharacters()
|
||||||
|
var escapedHomePageURL = ""
|
||||||
|
if let homePageURL = homePageURL {
|
||||||
|
escapedHomePageURL = homePageURL.rs_stringByEscapingSpecialXMLCharacters()
|
||||||
|
}
|
||||||
|
let escapedFeedURL = url.rs_stringByEscapingSpecialXMLCharacters()
|
||||||
|
|
||||||
|
var s = "<outline text=\"\(escapedName)\" title=\"\(escapedName)\" description=\"\" type=\"rss\" version=\"RSS\" htmlUrl=\"\(escapedHomePageURL)\" xmlUrl=\"\(escapedFeedURL)\"/>\n"
|
||||||
|
s = s.rs_string(byPrependingNumberOfTabs: indentLevel)
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
171
Frameworks/DataModel/FolderProtocol.swift
Normal file
171
Frameworks/DataModel/FolderProtocol.swift
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
//
|
||||||
|
// FolderProtocol.swift
|
||||||
|
// Rainier
|
||||||
|
//
|
||||||
|
// 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 Folder: class, UnreadCountProvider, DisplayNameProvider {
|
||||||
|
|
||||||
|
// TODO: get rid of children, flattenedFeeds, and some default implementations in favor of faster, specific ones.
|
||||||
|
|
||||||
|
// var children: NSSet {get}
|
||||||
|
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 = "<outline text=\"\(escapedTitle)\" title=\"\(escapedTitle)\">\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 = "<outline text=\"\(escapedTitle)\" title=\"\(escapedTitle)\"/>\n"
|
||||||
|
s = s.rs_string(byPrependingNumberOfTabs: indentLevel)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s + NSString.rs_string(withNumberOfTabs: indentLevel) + "</outline>\n"
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
26
Frameworks/DataModel/Info.plist
Normal file
26
Frameworks/DataModel/Info.plist
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>FMWK</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>Copyright © 2016 Ranchero Software, LLC. All rights reserved.</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
21
Frameworks/DataModel/Notifications.swift
Normal file
21
Frameworks/DataModel/Notifications.swift
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Notifications.swift
|
||||||
|
// DataModel
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 9/10/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public extension Notification.Name {
|
||||||
|
|
||||||
|
public static let ArticleStatusesDidChange = Notification.Name(rawValue: "ArticleStatusesDidChange")
|
||||||
|
public static let UnreadCountDidChange = Notification.Name(rawValue: "UnreadCountDidChangeNotification")
|
||||||
|
public static let DataModelDidPerformBatchUpdates = Notification.Name(rawValue: "DataModelDidPerformBatchUpdatesDidPerformBatchUpdatesNotification")
|
||||||
|
public static let AccountRefreshProgressDidChange = Notification.Name(rawValue: "AccountRefreshProgressDidChangeNotification")
|
||||||
|
}
|
||||||
|
|
||||||
|
public let articlesKey = "articles"
|
||||||
|
public let unreadCountKey = "unreadCount"
|
||||||
|
public let progressKey = "progress" //RSProgress
|
38
Frameworks/DataModel/UnreadCountProviderProtocol.swift
Normal file
38
Frameworks/DataModel/UnreadCountProviderProtocol.swift
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// UnreadCountProtocol.swift
|
||||||
|
// Rainier
|
||||||
|
//
|
||||||
|
// Created by Brent Simmons on 4/8/16.
|
||||||
|
// Copyright © 2016 Ranchero Software, LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol UnreadCountProvider {
|
||||||
|
|
||||||
|
var unreadCount: Int {get}
|
||||||
|
|
||||||
|
func updateUnreadCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func calculateUnreadCount<T: Collection>(_ children: T) -> Int {
|
||||||
|
|
||||||
|
var updatedUnreadCount = 0
|
||||||
|
|
||||||
|
children.forEach { (oneChild) in
|
||||||
|
if let oneUnreadCountProvider = oneChild as? UnreadCountProvider {
|
||||||
|
updatedUnreadCount += oneUnreadCountProvider.unreadCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedUnreadCount
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension UnreadCountProvider {
|
||||||
|
|
||||||
|
public func postUnreadCountDidChangeNotification() {
|
||||||
|
|
||||||
|
NotificationCenter.default.post(name: .UnreadCountDidChange, object: self, userInfo: [unreadCountKey: unreadCount])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user