From b1303661b25bb3e707d2eae42b80dbf70c2b16d6 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 14 May 2019 18:24:19 -0500 Subject: [PATCH] Save article statuses to new sync database as they are created --- Frameworks/Account/Account.swift | 2 +- .../Feedbin/FeedbinAccountDelegate.swift | 15 +- Frameworks/SyncDatabase/Constants.swift | 25 ++ Frameworks/SyncDatabase/Info.plist | 24 ++ Frameworks/SyncDatabase/SyncDatabase.swift | 39 ++ .../SyncDatabase.xcodeproj/project.pbxproj | 386 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + Frameworks/SyncDatabase/SyncStatus.swift | 31 ++ Frameworks/SyncDatabase/SyncStatusTable.swift | 28 ++ .../xcconfig/SyncDatabase_project.xcconfig | 58 +++ .../SyncDatabase_project_debug.xcconfig | 15 + .../SyncDatabase_project_release.xcconfig | 9 + .../xcconfig/SyncDatabase_target.xcconfig | 16 + NetNewsWire.xcodeproj/project.pbxproj | 62 +++ 15 files changed, 723 insertions(+), 2 deletions(-) create mode 100644 Frameworks/SyncDatabase/Constants.swift create mode 100644 Frameworks/SyncDatabase/Info.plist create mode 100644 Frameworks/SyncDatabase/SyncDatabase.swift create mode 100644 Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.pbxproj create mode 100644 Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Frameworks/SyncDatabase/SyncStatus.swift create mode 100644 Frameworks/SyncDatabase/SyncStatusTable.swift create mode 100644 Frameworks/SyncDatabase/xcconfig/SyncDatabase_project.xcconfig create mode 100644 Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_debug.xcconfig create mode 100644 Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_release.xcconfig create mode 100644 Frameworks/SyncDatabase/xcconfig/SyncDatabase_target.xcconfig diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index cca1a58f1..29ce4694c 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -185,7 +185,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, case .onMyMac: self.delegate = LocalAccountDelegate() case .feedbin: - self.delegate = FeedbinAccountDelegate(transport: transport) + self.delegate = FeedbinAccountDelegate(dataFolder: dataFolder, transport: transport) default: fatalError("Only Local and Feedbin accounts are supported") } diff --git a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift index c4ebe0d3d..c3e788243 100644 --- a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift @@ -16,6 +16,7 @@ import Articles import RSCore import RSParser import RSWeb +import SyncDatabase import os.log public enum FeedbinAccountDelegateError: String, Error { @@ -24,6 +25,8 @@ public enum FeedbinAccountDelegateError: String, Error { final class FeedbinAccountDelegate: AccountDelegate { + private let database: SyncDatabase + private let caller: FeedbinAPICaller private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "Feedbin") @@ -42,7 +45,10 @@ final class FeedbinAccountDelegate: AccountDelegate { } } - init(transport: Transport?) { + init(dataFolder: String, transport: Transport?) { + + let databaseFilePath = (dataFolder as NSString).appendingPathComponent("Sync.sqlite3") + database = SyncDatabase(databaseFilePath: databaseFilePath) if transport != nil { @@ -403,7 +409,14 @@ final class FeedbinAccountDelegate: AccountDelegate { } func markArticles(for account: Account, articles: Set
, statusKey: ArticleStatus.Key, flag: Bool) -> Set
? { + + let syncStatuses = articles.map { article in + return SyncStatus(articleID: article.articleID, key: statusKey, flag: flag) + } + database.insertStatuses(syncStatuses) + return account.update(articles, statusKey: statusKey, flag: flag) + } func accountDidInitialize(_ account: Account) { diff --git a/Frameworks/SyncDatabase/Constants.swift b/Frameworks/SyncDatabase/Constants.swift new file mode 100644 index 000000000..86d01b923 --- /dev/null +++ b/Frameworks/SyncDatabase/Constants.swift @@ -0,0 +1,25 @@ +// +// Constants.swift +// SyncDatabase +// +// Created by Maurice Parker on 5/14/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import Foundation + +struct DatabaseTableName { + + static let syncStatus = "syncStatus" + +} + +struct DatabaseKey { + + // Sync Status + static let articleID = "articleID" + static let key = "key" + static let flag = "flag" + static let selected = "selected" + +} diff --git a/Frameworks/SyncDatabase/Info.plist b/Frameworks/SyncDatabase/Info.plist new file mode 100644 index 000000000..76da86ac6 --- /dev/null +++ b/Frameworks/SyncDatabase/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2019 Ranchero Software. All rights reserved. + + diff --git a/Frameworks/SyncDatabase/SyncDatabase.swift b/Frameworks/SyncDatabase/SyncDatabase.swift new file mode 100644 index 000000000..3afde1eae --- /dev/null +++ b/Frameworks/SyncDatabase/SyncDatabase.swift @@ -0,0 +1,39 @@ +// +// SyncDatabase.swift +// NetNewsWire +// +// Created by Maurice Parker on 5/14/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import Foundation +import RSDatabase + +public final class SyncDatabase { + + private let syncStatusTable: SyncStatusTable + + public init(databaseFilePath: String) { + + let queue = RSDatabaseQueue(filepath: databaseFilePath, excludeFromBackup: false) + self.syncStatusTable = SyncStatusTable(queue: queue) + + queue.createTables(usingStatements: SyncDatabase.tableCreationStatements) + queue.vacuumIfNeeded() + + } + + public func insertStatuses(_ statuses: [SyncStatus]) { + syncStatusTable.insertStatuses(statuses) + } + +} + +// MARK: - Private + +private extension SyncDatabase { + + static let tableCreationStatements = """ + CREATE TABLE if not EXISTS syncStatus (articleID TEXT NOT NULL, key TEXT NOT NULL, flag BOOL NOT NULL DEFAULT 0, selected BOOL NOT NULL DEFAULT 0, PRIMARY KEY (articleID, key)); + """ +} diff --git a/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.pbxproj b/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.pbxproj new file mode 100644 index 000000000..c2f2849ad --- /dev/null +++ b/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.pbxproj @@ -0,0 +1,386 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 51554C15228B6F0D0055115A /* SyncStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C12228B6F0D0055115A /* SyncStatus.swift */; }; + 51554C16228B6F0D0055115A /* SyncStatusTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C13228B6F0D0055115A /* SyncStatusTable.swift */; }; + 51554C17228B6F0D0055115A /* SyncDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C14228B6F0D0055115A /* SyncDatabase.swift */; }; + 51554C1E228B701F0055115A /* SyncDatabase_project.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C19228B701F0055115A /* SyncDatabase_project.xcconfig */; }; + 51554C1F228B701F0055115A /* SyncDatabase_project_debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */; }; + 51554C21228B701F0055115A /* SyncDatabase_project_release.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */; }; + 51554C22228B701F0055115A /* SyncDatabase_target.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */; }; + 51554C36228B72F40055115A /* RSDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C35228B72F40055115A /* RSDatabase.framework */; }; + 51554C38228B7DAC0055115A /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51554C37228B7DAC0055115A /* Constants.swift */; }; + 51554C3A228B83380055115A /* Articles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C39228B83380055115A /* Articles.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 51554BEB228B6E8F0055115A /* SyncDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SyncDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 51554BEF228B6E8F0055115A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 51554C12228B6F0D0055115A /* SyncStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncStatus.swift; sourceTree = ""; }; + 51554C13228B6F0D0055115A /* SyncStatusTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncStatusTable.swift; sourceTree = ""; }; + 51554C14228B6F0D0055115A /* SyncDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncDatabase.swift; sourceTree = ""; }; + 51554C19228B701F0055115A /* SyncDatabase_project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_project.xcconfig; sourceTree = ""; }; + 51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_project_debug.xcconfig; sourceTree = ""; }; + 51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_project_release.xcconfig; sourceTree = ""; }; + 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = SyncDatabase_target.xcconfig; sourceTree = ""; }; + 51554C35228B72F40055115A /* RSDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 51554C37228B7DAC0055115A /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + 51554C39228B83380055115A /* Articles.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Articles.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 51554BE8228B6E8F0055115A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 51554C3A228B83380055115A /* Articles.framework in Frameworks */, + 51554C36228B72F40055115A /* RSDatabase.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 51554BE1228B6E8F0055115A = { + isa = PBXGroup; + children = ( + 51554C37228B7DAC0055115A /* Constants.swift */, + 51554C14228B6F0D0055115A /* SyncDatabase.swift */, + 51554C12228B6F0D0055115A /* SyncStatus.swift */, + 51554C13228B6F0D0055115A /* SyncStatusTable.swift */, + 51554BEF228B6E8F0055115A /* Info.plist */, + 51554BEC228B6E8F0055115A /* Products */, + 51554C18228B6FBE0055115A /* xcconfig */, + 51554C34228B72F40055115A /* Frameworks */, + ); + sourceTree = ""; + }; + 51554BEC228B6E8F0055115A /* Products */ = { + isa = PBXGroup; + children = ( + 51554BEB228B6E8F0055115A /* SyncDatabase.framework */, + ); + name = Products; + sourceTree = ""; + }; + 51554C18228B6FBE0055115A /* xcconfig */ = { + isa = PBXGroup; + children = ( + 51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */, + 51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */, + 51554C19228B701F0055115A /* SyncDatabase_project.xcconfig */, + 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */, + ); + path = xcconfig; + sourceTree = ""; + }; + 51554C34228B72F40055115A /* Frameworks */ = { + isa = PBXGroup; + children = ( + 51554C39228B83380055115A /* Articles.framework */, + 51554C35228B72F40055115A /* RSDatabase.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 51554BE6228B6E8F0055115A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 51554BEA228B6E8F0055115A /* SyncDatabase */ = { + isa = PBXNativeTarget; + buildConfigurationList = 51554BF3228B6E8F0055115A /* Build configuration list for PBXNativeTarget "SyncDatabase" */; + buildPhases = ( + 51554BE6228B6E8F0055115A /* Headers */, + 51554BE7228B6E8F0055115A /* Sources */, + 51554BE8228B6E8F0055115A /* Frameworks */, + 51554BE9228B6E8F0055115A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SyncDatabase; + productName = SyncDatabase; + productReference = 51554BEB228B6E8F0055115A /* SyncDatabase.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 51554BE2228B6E8F0055115A /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "Ranchero Software"; + TargetAttributes = { + 51554BEA228B6E8F0055115A = { + CreatedOnToolsVersion = 10.2.1; + }; + }; + }; + buildConfigurationList = 51554BE5228B6E8F0055115A /* Build configuration list for PBXProject "SyncDatabase" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 51554BE1228B6E8F0055115A; + productRefGroup = 51554BEC228B6E8F0055115A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 51554BEA228B6E8F0055115A /* SyncDatabase */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 51554BE9228B6E8F0055115A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 51554C21228B701F0055115A /* SyncDatabase_project_release.xcconfig in Resources */, + 51554C22228B701F0055115A /* SyncDatabase_target.xcconfig in Resources */, + 51554C1F228B701F0055115A /* SyncDatabase_project_debug.xcconfig in Resources */, + 51554C1E228B701F0055115A /* SyncDatabase_project.xcconfig in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 51554BE7228B6E8F0055115A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 51554C15228B6F0D0055115A /* SyncStatus.swift in Sources */, + 51554C16228B6F0D0055115A /* SyncStatusTable.swift in Sources */, + 51554C17228B6F0D0055115A /* SyncDatabase.swift in Sources */, + 51554C38228B7DAC0055115A /* Constants.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 51554BF1228B6E8F0055115A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51554C1A228B701F0055115A /* SyncDatabase_project_debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "Mac Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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.14; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 51554BF2228B6E8F0055115A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51554C1C228B701F0055115A /* SyncDatabase_project_release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "Mac Developer"; + 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 = gnu11; + 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.14; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 51554BF4228B6E8F0055115A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = SHJK2V3AJG; + 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.SyncDatabase; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 51554BF5228B6E8F0055115A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 51554C1D228B701F0055115A /* SyncDatabase_target.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = SHJK2V3AJG; + 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.SyncDatabase; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 51554BE5228B6E8F0055115A /* Build configuration list for PBXProject "SyncDatabase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 51554BF1228B6E8F0055115A /* Debug */, + 51554BF2228B6E8F0055115A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 51554BF3228B6E8F0055115A /* Build configuration list for PBXNativeTarget "SyncDatabase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 51554BF4228B6E8F0055115A /* Debug */, + 51554BF5228B6E8F0055115A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 51554BE2228B6E8F0055115A /* Project object */; +} diff --git a/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..f93b01eb8 --- /dev/null +++ b/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/Frameworks/SyncDatabase/SyncDatabase.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Frameworks/SyncDatabase/SyncStatus.swift b/Frameworks/SyncDatabase/SyncStatus.swift new file mode 100644 index 000000000..1e024f1f9 --- /dev/null +++ b/Frameworks/SyncDatabase/SyncStatus.swift @@ -0,0 +1,31 @@ +// +// SyncStatus.swift +// NetNewsWire +// +// Created by Maurice Parker on 5/14/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import Foundation +import Articles +import RSDatabase + +public struct SyncStatus { + + public let articleID: String + public let key: ArticleStatus.Key + public let flag: Bool + public let selected: Bool + + public init(articleID: String, key: ArticleStatus.Key, flag: Bool, selected: Bool = false) { + self.articleID = articleID + self.key = key + self.flag = flag + self.selected = selected + } + + public func databaseDictionary() -> DatabaseDictionary? { + return [DatabaseKey.articleID: articleID, DatabaseKey.key: key.rawValue, DatabaseKey.flag: flag, DatabaseKey.selected: selected] + } + +} diff --git a/Frameworks/SyncDatabase/SyncStatusTable.swift b/Frameworks/SyncDatabase/SyncStatusTable.swift new file mode 100644 index 000000000..ad0eca26f --- /dev/null +++ b/Frameworks/SyncDatabase/SyncStatusTable.swift @@ -0,0 +1,28 @@ +// +// SyncStatusTable.swift +// NetNewsWire +// +// Created by Maurice Parker on 5/14/19. +// Copyright © 2019 Ranchero Software. All rights reserved. +// + +import Foundation +import RSDatabase + +final class SyncStatusTable: DatabaseTable { + + let name = DatabaseTableName.syncStatus + private let queue: RSDatabaseQueue + + init(queue: RSDatabaseQueue) { + self.queue = queue + } + + func insertStatuses(_ statuses: [SyncStatus]) { + self.queue.update { database in + let statusArray = statuses.map { $0.databaseDictionary()! } + self.insertRows(statusArray, insertType: .orReplace, in: database) + } + } + +} diff --git a/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project.xcconfig b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project.xcconfig new file mode 100644 index 000000000..9a1875f59 --- /dev/null +++ b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project.xcconfig @@ -0,0 +1,58 @@ +CODE_SIGN_IDENTITY = Mac Developer +CODE_SIGN_STYLE = Automatic +DEVELOPMENT_TEAM = 9C84TZ7Q6Z + +// See the notes in NetNewsWire_target.xcconfig on why the +// DeveloperSettings.xcconfig is #included here + +#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig" + +SDKROOT = macosx +MACOSX_DEPLOYMENT_TARGET = 10.14 +CLANG_ENABLE_OBJC_WEAK = YES +SWIFT_VERSION = 5.0 +COMBINE_HIDPI_IMAGES = YES + +COPY_PHASE_STRIP = NO +MACOSX_DEPLOYMENT_TARGET = 10.14 +ALWAYS_SEARCH_USER_PATHS = NO +CURRENT_PROJECT_VERSION = 1 +VERSION_INFO_PREFIX = +VERSIONING_SYSTEM = apple-generic +GCC_NO_COMMON_BLOCKS = YES +GCC_C_LANGUAGE_STANDARD = gnu99 +CLANG_CXX_LANGUAGE_STANDARD = gnu++0x +CLANG_CXX_LIBRARY = libc++ +CLANG_ENABLE_MODULES = YES +CLANG_ENABLE_OBJC_ARC = YES +ENABLE_STRICT_OBJC_MSGSEND = YES +CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES +CLANG_WARN_DOCUMENTATION_COMMENTS = YES +CLANG_WARN_EMPTY_BODY = YES +CLANG_WARN_BOOL_CONVERSION = YES +CLANG_WARN_CONSTANT_CONVERSION = YES +GCC_WARN_64_TO_32_BIT_CONVERSION = YES +CLANG_WARN_ENUM_CONVERSION = YES +CLANG_WARN_INT_CONVERSION = YES +CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES +CLANG_WARN_INFINITE_RECURSION = YES +GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE +CLANG_WARN_UNREACHABLE_CODE = YES +GCC_WARN_UNUSED_FUNCTION = YES +GCC_WARN_UNUSED_VARIABLE = YES +CLANG_WARN_RANGE_LOOP_ANALYSIS = YES +CLANG_WARN_SUSPICIOUS_MOVE = YES +CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_OBJC_LITERAL_CONVERSION = YES +CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +CLANG_ANALYZER_NONNULL = YES +CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE +SWIFT_SWIFT3_OBJC_INFERENCE = Off diff --git a/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_debug.xcconfig b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_debug.xcconfig new file mode 100644 index 000000000..d8e140d98 --- /dev/null +++ b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_debug.xcconfig @@ -0,0 +1,15 @@ +#include "./SyncDatabase_project.xcconfig" + +DEBUG_INFORMATION_FORMAT = dwarf +ENABLE_TESTABILITY = YES +GCC_DYNAMIC_NO_PIC = NO +GCC_OPTIMIZATION_LEVEL = 0 +GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited) + +MTL_ENABLE_DEBUG_INFO = YES +SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG +SWIFT_COMPILATION_MODE = singlefile +SWIFT_OPTIMIZATION_LEVEL = -Onone +ONLY_ACTIVE_ARCH = YES + + diff --git a/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_release.xcconfig b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_release.xcconfig new file mode 100644 index 000000000..d7d26dd1c --- /dev/null +++ b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_project_release.xcconfig @@ -0,0 +1,9 @@ +#include "./SyncDatabase_project.xcconfig" + +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym +ENABLE_NS_ASSERTIONS = NO + +MTL_ENABLE_DEBUG_INFO = NO +SWIFT_OPTIMIZATION_LEVEL = -O + +SWIFT_COMPILATION_MODE = wholemodule diff --git a/Frameworks/SyncDatabase/xcconfig/SyncDatabase_target.xcconfig b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_target.xcconfig new file mode 100644 index 000000000..3fbeffac5 --- /dev/null +++ b/Frameworks/SyncDatabase/xcconfig/SyncDatabase_target.xcconfig @@ -0,0 +1,16 @@ +CODE_SIGN_IDENTITY = +// DEVELOPMENT_TEAM = 9C84TZ7Q6Z + +INSTALL_PATH = $(LOCAL_LIBRARY_DIR)/Frameworks +SKIP_INSTALL = YES +DYLIB_COMPATIBILITY_VERSION = 1 +DYLIB_CURRENT_VERSION = 1 +DYLIB_INSTALL_NAME_BASE = @rpath +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/Frameworks +DEFINES_MODULE = YES +FRAMEWORK_VERSION = A +INFOPLIST_FILE = Info.plist +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.SyncDatabase +PRODUCT_NAME = $(TARGET_NAME) +CLANG_ENABLE_MODULES = YES + diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 82dd181b4..a241e01a5 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -26,6 +26,10 @@ 5144EA43227A380F00D19003 /* ExportOPMLWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA42227A380F00D19003 /* ExportOPMLWindowController.swift */; }; 5144EA51227B8E4500D19003 /* AccountsFeedbinWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */; }; 5144EA52227B8E4500D19003 /* AccountsFeedbin.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */; }; + 51554C24228B71910055115A /* SyncDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; }; + 51554C25228B71910055115A /* SyncDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 51554C30228B71A10055115A /* SyncDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; }; + 51554C31228B71A10055115A /* SyncDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 51554C01228B6EB50055115A /* SyncDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5183CCD0226E1E880010922C /* NonIntrinsicLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */; }; 5183CCDA226E31A50010922C /* NonIntrinsicImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */; }; 5183CCDD226F1F5C0010922C /* NavigationProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5183CCDC226F1F5C0010922C /* NavigationProgressView.swift */; }; @@ -305,6 +309,27 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 51554C00228B6EB50055115A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 51554BEB228B6E8F0055115A; + remoteInfo = SyncDatabase; + }; + 51554C26228B71910055115A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 51554BEA228B6E8F0055115A; + remoteInfo = SyncDatabase; + }; + 51554C32228B71A10055115A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 51554BEA228B6E8F0055115A; + remoteInfo = SyncDatabase; + }; 51C451AB226377C300C03939 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 841D4D5E2106B3E100DD04E6 /* ArticlesDatabase.xcodeproj */; @@ -579,6 +604,7 @@ 51C451F12264C83100C03939 /* ArticlesDatabase.framework in Embed Frameworks */, 51C451F52264C83900C03939 /* Articles.framework in Embed Frameworks */, 51C451E92264C81000C03939 /* RSDatabase.framework in Embed Frameworks */, + 51554C31228B71A10055115A /* SyncDatabase.framework in Embed Frameworks */, 51C451ED2264C81B00C03939 /* RSCore.framework in Embed Frameworks */, 51C451E52264C80600C03939 /* RSParser.framework in Embed Frameworks */, ); @@ -610,6 +636,7 @@ 51C451BE226377D000C03939 /* Account.framework in Embed Frameworks */, 51C451BA226377C900C03939 /* Articles.framework in Embed Frameworks */, 84C37FB620DD8DBB00CA8CF5 /* RSParser.framework in Embed Frameworks */, + 51554C25228B71910055115A /* SyncDatabase.framework in Embed Frameworks */, 84C37FA620DD8D8400CA8CF5 /* RSCore.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -644,6 +671,7 @@ 5144EA42227A380F00D19003 /* ExportOPMLWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExportOPMLWindowController.swift; sourceTree = ""; }; 5144EA4F227B8E4500D19003 /* AccountsFeedbinWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsFeedbinWindowController.swift; sourceTree = ""; }; 5144EA50227B8E4500D19003 /* AccountsFeedbin.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsFeedbin.xib; sourceTree = ""; }; + 51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SyncDatabase.xcodeproj; path = Frameworks/SyncDatabase/SyncDatabase.xcodeproj; sourceTree = SOURCE_ROOT; }; 5183CCCF226E1E880010922C /* NonIntrinsicLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicLabel.swift; sourceTree = ""; }; 5183CCD9226E31A50010922C /* NonIntrinsicImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonIntrinsicImageView.swift; sourceTree = ""; }; 5183CCDC226F1F5C0010922C /* NavigationProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationProgressView.swift; sourceTree = ""; }; @@ -902,6 +930,7 @@ 51C451F42264C83900C03939 /* Articles.framework in Frameworks */, 51C451E82264C81000C03939 /* RSDatabase.framework in Frameworks */, 51C451EC2264C81B00C03939 /* RSCore.framework in Frameworks */, + 51554C30228B71A10055115A /* SyncDatabase.framework in Frameworks */, 51C451E42264C80600C03939 /* RSParser.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -925,6 +954,7 @@ 51C451BD226377D000C03939 /* Account.framework in Frameworks */, 51C451B9226377C900C03939 /* Articles.framework in Frameworks */, 84C37FA520DD8D8400CA8CF5 /* RSCore.framework in Frameworks */, + 51554C24228B71910055115A /* SyncDatabase.framework in Frameworks */, 84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -968,6 +998,14 @@ path = OPML; sourceTree = ""; }; + 51554BFD228B6EB50055115A /* Products */ = { + isa = PBXGroup; + children = ( + 51554C01228B6EB50055115A /* SyncDatabase.framework */, + ); + name = Products; + sourceTree = ""; + }; 5183CCDB226F1EEB0010922C /* Progress */ = { isa = PBXGroup; children = ( @@ -1515,6 +1553,7 @@ 846E77301F6EF5D600A165E2 /* Account.xcodeproj */, 841D4D542106B3D500DD04E6 /* Articles.xcodeproj */, 841D4D5E2106B3E100DD04E6 /* ArticlesDatabase.xcodeproj */, + 51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */, 842E45CD1ED8C308000A8B52 /* AppNotifications.swift */, 51C452AD2265102800C03939 /* Timeline */, 84702AB31FA27AE8006B8943 /* Commands */, @@ -1797,6 +1836,7 @@ 51C451F32264C83100C03939 /* PBXTargetDependency */, 51C451F72264C83900C03939 /* PBXTargetDependency */, 51C451FB2264C83E00C03939 /* PBXTargetDependency */, + 51554C33228B71A10055115A /* PBXTargetDependency */, ); name = "NetNewsWire-iOS"; productName = "NetNewsWire-iOS"; @@ -1844,6 +1884,7 @@ 51C451AC226377C300C03939 /* PBXTargetDependency */, 51C451BC226377C900C03939 /* PBXTargetDependency */, 51C451C0226377D000C03939 /* PBXTargetDependency */, + 51554C27228B71910055115A /* PBXTargetDependency */, ); name = NetNewsWire; productName = NetNewsWire; @@ -1962,6 +2003,10 @@ ProductGroup = 84C37F9920DD8D0400CA8CF5 /* Products */; ProjectRef = 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */; }, + { + ProductGroup = 51554BFD228B6EB50055115A /* Products */; + ProjectRef = 51554BFC228B6EB50055115A /* SyncDatabase.xcodeproj */; + }, ); projectRoot = ""; targets = ( @@ -1975,6 +2020,13 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ + 51554C01228B6EB50055115A /* SyncDatabase.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SyncDatabase.framework; + remoteRef = 51554C00228B6EB50055115A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 8407166A2262A60D00344432 /* Account.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -2479,6 +2531,16 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 51554C27228B71910055115A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SyncDatabase; + targetProxy = 51554C26228B71910055115A /* PBXContainerItemProxy */; + }; + 51554C33228B71A10055115A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SyncDatabase; + targetProxy = 51554C32228B71A10055115A /* PBXContainerItemProxy */; + }; 51C451AC226377C300C03939 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = ArticlesDatabase;