From fdda92e4c2ae41e6d195c7446bd8c3fb073142d7 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Thu, 21 Jun 2018 13:04:26 -0700 Subject: [PATCH 01/40] Break build. Remove local copy of DB5.framework. --- Evergreen.xcodeproj/project.pbxproj | 60 --- Frameworks/DB5/DB5.xcodeproj/project.pbxproj | 321 --------------- .../contents.xcworkspacedata | 7 - Frameworks/DB5/DB5/DB5.h | 21 - Frameworks/DB5/DB5/Info.plist | 28 -- Frameworks/DB5/DB5/VSTheme.h | 92 ----- Frameworks/DB5/DB5/VSTheme.m | 367 ------------------ Frameworks/DB5/DB5/VSThemeLoader.h | 24 -- Frameworks/DB5/DB5/VSThemeLoader.m | 71 ---- Frameworks/DB5/DB5Tests/DB5Tests.m | 39 -- Frameworks/DB5/DB5Tests/Info.plist | 24 -- .../DB5/xcconfig/DB5Tests_target.xcconfig | 15 - Frameworks/DB5/xcconfig/DB5_project.xcconfig | 54 --- .../DB5/xcconfig/DB5_project_debug.xcconfig | 11 - .../DB5/xcconfig/DB5_project_release.xcconfig | 7 - Frameworks/DB5/xcconfig/DB5_target.xcconfig | 16 - 16 files changed, 1157 deletions(-) delete mode 100644 Frameworks/DB5/DB5.xcodeproj/project.pbxproj delete mode 100644 Frameworks/DB5/DB5.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 Frameworks/DB5/DB5/DB5.h delete mode 100644 Frameworks/DB5/DB5/Info.plist delete mode 100644 Frameworks/DB5/DB5/VSTheme.h delete mode 100644 Frameworks/DB5/DB5/VSTheme.m delete mode 100644 Frameworks/DB5/DB5/VSThemeLoader.h delete mode 100644 Frameworks/DB5/DB5/VSThemeLoader.m delete mode 100644 Frameworks/DB5/DB5Tests/DB5Tests.m delete mode 100644 Frameworks/DB5/DB5Tests/Info.plist delete mode 100644 Frameworks/DB5/xcconfig/DB5Tests_target.xcconfig delete mode 100644 Frameworks/DB5/xcconfig/DB5_project.xcconfig delete mode 100644 Frameworks/DB5/xcconfig/DB5_project_debug.xcconfig delete mode 100644 Frameworks/DB5/xcconfig/DB5_project_release.xcconfig delete mode 100644 Frameworks/DB5/xcconfig/DB5_target.xcconfig diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 0b5f5d43a..d020f9242 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -109,8 +109,6 @@ 84AD1EAA2031617300BC20B7 /* FolderPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EA92031617300BC20B7 /* FolderPasteboardWriter.swift */; }; 84AD1EBA2031649C00BC20B7 /* SmartFeedPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EB92031649C00BC20B7 /* SmartFeedPasteboardWriter.swift */; }; 84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EBB2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift */; }; - 84B06FCF1ED37F7D00F0B54B /* DB5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FCC1ED37F7200F0B54B /* DB5.framework */; }; - 84B06FD01ED37F7D00F0B54B /* DB5.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FCC1ED37F7200F0B54B /* DB5.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84B06FE91ED3803A00F0B54B /* RSFeedFinder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */; }; 84B06FEA1ED3803A00F0B54B /* RSFeedFinder.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84B7178C201E66580091657D /* SidebarViewController+ContextualMenus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7178B201E66580091657D /* SidebarViewController+ContextualMenus.swift */; }; @@ -256,27 +254,6 @@ remoteGlobalIDString = 849C645F1ED37A5D003D8FC0; remoteInfo = Evergreen; }; - 84B06FCB1ED37F7200F0B54B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 84F22BD11B52DC2E000060CE; - remoteInfo = DB5; - }; - 84B06FCD1ED37F7200F0B54B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 84F22BDB1B52DC2E000060CE; - remoteInfo = DB5Tests; - }; - 84B06FD11ED37F7D00F0B54B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 84F22BD01B52DC2E000060CE; - remoteInfo = DB5; - }; 84B06FE51ED3803200F0B54B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */; @@ -333,7 +310,6 @@ 846E77421F6EF6A100A165E2 /* Database.framework in Embed Frameworks */, 84B06FEA1ED3803A00F0B54B /* RSFeedFinder.framework in Embed Frameworks */, 846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */, - 84B06FD01ED37F7D00F0B54B /* DB5.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -481,7 +457,6 @@ 84AD1EA92031617300BC20B7 /* FolderPasteboardWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderPasteboardWriter.swift; sourceTree = ""; }; 84AD1EB92031649C00BC20B7 /* SmartFeedPasteboardWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartFeedPasteboardWriter.swift; sourceTree = ""; }; 84AD1EBB2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarOutlineDataSource.swift; sourceTree = ""; }; - 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = DB5.xcodeproj; path = Frameworks/DB5/DB5.xcodeproj; sourceTree = ""; }; 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSFeedFinder.xcodeproj; path = Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj; sourceTree = ""; }; 84B7178B201E66580091657D /* SidebarViewController+ContextualMenus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SidebarViewController+ContextualMenus.swift"; sourceTree = ""; }; 84B99C661FAE35E600ECDEDB /* FeedListTreeControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListTreeControllerDelegate.swift; sourceTree = ""; }; @@ -582,7 +557,6 @@ 84BB4B771F11753300858766 /* Data.framework in Frameworks */, 846E77411F6EF6A100A165E2 /* Database.framework in Frameworks */, 84B06FE91ED3803A00F0B54B /* RSFeedFinder.framework in Frameworks */, - 84B06FCF1ED37F7D00F0B54B /* DB5.framework in Frameworks */, 846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */, 84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */, ); @@ -967,7 +941,6 @@ 846E77301F6EF5D600A165E2 /* Account.xcodeproj */, 846E77161F6EF5D000A165E2 /* Database.xcodeproj */, 84BB4B611F1174D400858766 /* Data.xcodeproj */, - 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */, 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */, ); sourceTree = ""; @@ -1013,15 +986,6 @@ path = Evergreen/Dinosaurs; sourceTree = ""; }; - 84B06FC71ED37F7200F0B54B /* Products */ = { - isa = PBXGroup; - children = ( - 84B06FCC1ED37F7200F0B54B /* DB5.framework */, - 84B06FCE1ED37F7200F0B54B /* DB5Tests.xctest */, - ); - name = Products; - sourceTree = ""; - }; 84B06FE11ED3803200F0B54B /* Products */ = { isa = PBXGroup; children = ( @@ -1249,7 +1213,6 @@ buildRules = ( ); dependencies = ( - 84B06FD21ED37F7D00F0B54B /* PBXTargetDependency */, 84B06FEC1ED3803A00F0B54B /* PBXTargetDependency */, 84BB4B7A1F11753300858766 /* PBXTargetDependency */, 846E77401F6EF67A00A165E2 /* PBXTargetDependency */, @@ -1343,10 +1306,6 @@ ProductGroup = 846E77171F6EF5D000A165E2 /* Products */; ProjectRef = 846E77161F6EF5D000A165E2 /* Database.xcodeproj */; }, - { - ProductGroup = 84B06FC71ED37F7200F0B54B /* Products */; - ProjectRef = 84B06FC61ED37F7200F0B54B /* DB5.xcodeproj */; - }, { ProductGroup = 84B06FE11ED3803200F0B54B /* Products */; ProjectRef = 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */; @@ -1392,20 +1351,6 @@ remoteRef = 846E773B1F6EF5D700A165E2 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 84B06FCC1ED37F7200F0B54B /* DB5.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = DB5.framework; - remoteRef = 84B06FCB1ED37F7200F0B54B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 84B06FCE1ED37F7200F0B54B /* DB5Tests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = DB5Tests.xctest; - remoteRef = 84B06FCD1ED37F7200F0B54B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -1710,11 +1655,6 @@ target = 849C645F1ED37A5D003D8FC0 /* Evergreen */; targetProxy = 849C64721ED37A5D003D8FC0 /* PBXContainerItemProxy */; }; - 84B06FD21ED37F7D00F0B54B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = DB5; - targetProxy = 84B06FD11ED37F7D00F0B54B /* PBXContainerItemProxy */; - }; 84B06FEC1ED3803A00F0B54B /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = RSFeedFinder; diff --git a/Frameworks/DB5/DB5.xcodeproj/project.pbxproj b/Frameworks/DB5/DB5.xcodeproj/project.pbxproj deleted file mode 100644 index a6341fc8a..000000000 --- a/Frameworks/DB5/DB5.xcodeproj/project.pbxproj +++ /dev/null @@ -1,321 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 84F22BD51B52DC2E000060CE /* DB5.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F22BD41B52DC2E000060CE /* DB5.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 84F22BDC1B52DC2E000060CE /* DB5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F22BD11B52DC2E000060CE /* DB5.framework */; }; - 84F22BE11B52DC2E000060CE /* DB5Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 84F22BE01B52DC2E000060CE /* DB5Tests.m */; }; - 84F22BEF1B52DC48000060CE /* VSTheme.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F22BEB1B52DC48000060CE /* VSTheme.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 84F22BF01B52DC48000060CE /* VSTheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 84F22BEC1B52DC48000060CE /* VSTheme.m */; }; - 84F22BF11B52DC48000060CE /* VSThemeLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F22BED1B52DC48000060CE /* VSThemeLoader.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 84F22BF21B52DC48000060CE /* VSThemeLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 84F22BEE1B52DC48000060CE /* VSThemeLoader.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 84F22BDD1B52DC2E000060CE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84F22BC81B52DC2E000060CE /* Project object */; - proxyType = 1; - remoteGlobalIDString = 84F22BD01B52DC2E000060CE; - remoteInfo = DB5; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 84F22BD11B52DC2E000060CE /* DB5.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DB5.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 84F22BD41B52DC2E000060CE /* DB5.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DB5.h; path = DB5/DB5.h; sourceTree = ""; }; - 84F22BD61B52DC2E000060CE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = DB5/Info.plist; sourceTree = ""; }; - 84F22BDB1B52DC2E000060CE /* DB5Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DB5Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 84F22BE01B52DC2E000060CE /* DB5Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DB5Tests.m; sourceTree = ""; }; - 84F22BE21B52DC2E000060CE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 84F22BEB1B52DC48000060CE /* VSTheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VSTheme.h; path = DB5/VSTheme.h; sourceTree = ""; }; - 84F22BEC1B52DC48000060CE /* VSTheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VSTheme.m; path = DB5/VSTheme.m; sourceTree = ""; }; - 84F22BED1B52DC48000060CE /* VSThemeLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VSThemeLoader.h; path = DB5/VSThemeLoader.h; sourceTree = ""; }; - 84F22BEE1B52DC48000060CE /* VSThemeLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VSThemeLoader.m; path = DB5/VSThemeLoader.m; sourceTree = ""; }; - D511EEF720242E3E00712EC3 /* DB5_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DB5_project_debug.xcconfig; sourceTree = ""; }; - D511EEF820242E3E00712EC3 /* DB5Tests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DB5Tests_target.xcconfig; sourceTree = ""; }; - D511EEF920242E3E00712EC3 /* DB5_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DB5_project.xcconfig; sourceTree = ""; }; - D511EEFA20242E3E00712EC3 /* DB5_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DB5_target.xcconfig; sourceTree = ""; }; - D511EEFB20242E3E00712EC3 /* DB5_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DB5_project_release.xcconfig; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 84F22BCD1B52DC2E000060CE /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 84F22BD81B52DC2E000060CE /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 84F22BDC1B52DC2E000060CE /* DB5.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 84F22BC71B52DC2E000060CE = { - isa = PBXGroup; - children = ( - 84F22BD41B52DC2E000060CE /* DB5.h */, - 84F22BEB1B52DC48000060CE /* VSTheme.h */, - 84F22BEC1B52DC48000060CE /* VSTheme.m */, - 84F22BED1B52DC48000060CE /* VSThemeLoader.h */, - 84F22BEE1B52DC48000060CE /* VSThemeLoader.m */, - 84F22BD61B52DC2E000060CE /* Info.plist */, - 84F22BDF1B52DC2E000060CE /* DB5Tests */, - 84F22BD21B52DC2E000060CE /* Products */, - D511EEF620242E3E00712EC3 /* xcconfig */, - ); - sourceTree = ""; - }; - 84F22BD21B52DC2E000060CE /* Products */ = { - isa = PBXGroup; - children = ( - 84F22BD11B52DC2E000060CE /* DB5.framework */, - 84F22BDB1B52DC2E000060CE /* DB5Tests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 84F22BDF1B52DC2E000060CE /* DB5Tests */ = { - isa = PBXGroup; - children = ( - 84F22BE01B52DC2E000060CE /* DB5Tests.m */, - 84F22BE21B52DC2E000060CE /* Info.plist */, - ); - path = DB5Tests; - sourceTree = ""; - }; - D511EEF620242E3E00712EC3 /* xcconfig */ = { - isa = PBXGroup; - children = ( - D511EEF720242E3E00712EC3 /* DB5_project_debug.xcconfig */, - D511EEF820242E3E00712EC3 /* DB5Tests_target.xcconfig */, - D511EEF920242E3E00712EC3 /* DB5_project.xcconfig */, - D511EEFA20242E3E00712EC3 /* DB5_target.xcconfig */, - D511EEFB20242E3E00712EC3 /* DB5_project_release.xcconfig */, - ); - path = xcconfig; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 84F22BCE1B52DC2E000060CE /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 84F22BD51B52DC2E000060CE /* DB5.h in Headers */, - 84F22BEF1B52DC48000060CE /* VSTheme.h in Headers */, - 84F22BF11B52DC48000060CE /* VSThemeLoader.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 84F22BD01B52DC2E000060CE /* DB5 */ = { - isa = PBXNativeTarget; - buildConfigurationList = 84F22BE51B52DC2E000060CE /* Build configuration list for PBXNativeTarget "DB5" */; - buildPhases = ( - 84F22BCC1B52DC2E000060CE /* Sources */, - 84F22BCD1B52DC2E000060CE /* Frameworks */, - 84F22BCE1B52DC2E000060CE /* Headers */, - 84F22BCF1B52DC2E000060CE /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = DB5; - productName = DB5; - productReference = 84F22BD11B52DC2E000060CE /* DB5.framework */; - productType = "com.apple.product-type.framework"; - }; - 84F22BDA1B52DC2E000060CE /* DB5Tests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 84F22BE81B52DC2E000060CE /* Build configuration list for PBXNativeTarget "DB5Tests" */; - buildPhases = ( - 84F22BD71B52DC2E000060CE /* Sources */, - 84F22BD81B52DC2E000060CE /* Frameworks */, - 84F22BD91B52DC2E000060CE /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 84F22BDE1B52DC2E000060CE /* PBXTargetDependency */, - ); - name = DB5Tests; - productName = DB5Tests; - productReference = 84F22BDB1B52DC2E000060CE /* DB5Tests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 84F22BC81B52DC2E000060CE /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Ranchero Software, LLC"; - TargetAttributes = { - 84F22BD01B52DC2E000060CE = { - CreatedOnToolsVersion = 7.0; - LastSwiftMigration = 0800; - }; - 84F22BDA1B52DC2E000060CE = { - CreatedOnToolsVersion = 7.0; - LastSwiftMigration = 0800; - }; - }; - }; - buildConfigurationList = 84F22BCB1B52DC2E000060CE /* Build configuration list for PBXProject "DB5" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 84F22BC71B52DC2E000060CE; - productRefGroup = 84F22BD21B52DC2E000060CE /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 84F22BD01B52DC2E000060CE /* DB5 */, - 84F22BDA1B52DC2E000060CE /* DB5Tests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 84F22BCF1B52DC2E000060CE /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 84F22BD91B52DC2E000060CE /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 84F22BCC1B52DC2E000060CE /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 84F22BF01B52DC48000060CE /* VSTheme.m in Sources */, - 84F22BF21B52DC48000060CE /* VSThemeLoader.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 84F22BD71B52DC2E000060CE /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 84F22BE11B52DC2E000060CE /* DB5Tests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 84F22BDE1B52DC2E000060CE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 84F22BD01B52DC2E000060CE /* DB5 */; - targetProxy = 84F22BDD1B52DC2E000060CE /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 84F22BE31B52DC2E000060CE /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EEF720242E3E00712EC3 /* DB5_project_debug.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 84F22BE41B52DC2E000060CE /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EEFB20242E3E00712EC3 /* DB5_project_release.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 84F22BE61B52DC2E000060CE /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EEFA20242E3E00712EC3 /* DB5_target.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 84F22BE71B52DC2E000060CE /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EEFA20242E3E00712EC3 /* DB5_target.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 84F22BE91B52DC2E000060CE /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EEF820242E3E00712EC3 /* DB5Tests_target.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 84F22BEA1B52DC2E000060CE /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EEF820242E3E00712EC3 /* DB5Tests_target.xcconfig */; - buildSettings = { - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 84F22BCB1B52DC2E000060CE /* Build configuration list for PBXProject "DB5" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84F22BE31B52DC2E000060CE /* Debug */, - 84F22BE41B52DC2E000060CE /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 84F22BE51B52DC2E000060CE /* Build configuration list for PBXNativeTarget "DB5" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84F22BE61B52DC2E000060CE /* Debug */, - 84F22BE71B52DC2E000060CE /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 84F22BE81B52DC2E000060CE /* Build configuration list for PBXNativeTarget "DB5Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84F22BE91B52DC2E000060CE /* Debug */, - 84F22BEA1B52DC2E000060CE /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 84F22BC81B52DC2E000060CE /* Project object */; -} diff --git a/Frameworks/DB5/DB5.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/DB5/DB5.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index d13abd02f..000000000 --- a/Frameworks/DB5/DB5.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Frameworks/DB5/DB5/DB5.h b/Frameworks/DB5/DB5/DB5.h deleted file mode 100644 index 15243eb88..000000000 --- a/Frameworks/DB5/DB5/DB5.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// DB5.h -// DB5 -// -// Created by Brent Simmons on 7/12/15. -// Copyright © 2015 Ranchero Software, LLC. All rights reserved. -// - -@import AppKit; - -//! Project version number for DB5. -FOUNDATION_EXPORT double DB5VersionNumber; - -//! Project version string for DB5. -FOUNDATION_EXPORT const unsigned char DB5VersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - -#import -#import - diff --git a/Frameworks/DB5/DB5/Info.plist b/Frameworks/DB5/DB5/Info.plist deleted file mode 100644 index 87b01750b..000000000 --- a/Frameworks/DB5/DB5/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2015 Ranchero Software, LLC. All rights reserved. - NSPrincipalClass - - - diff --git a/Frameworks/DB5/DB5/VSTheme.h b/Frameworks/DB5/DB5/VSTheme.h deleted file mode 100644 index 89347021f..000000000 --- a/Frameworks/DB5/DB5/VSTheme.h +++ /dev/null @@ -1,92 +0,0 @@ -// -// VSTheme.h -// Q Branch LLC -// -// Created by Brent Simmons on 6/26/13. -// Copyright (c) 2012 Q Branch LLC. All rights reserved. -// - -@import AppKit; - -NS_ASSUME_NONNULL_BEGIN - -typedef NS_ENUM(NSUInteger, VSTextCaseTransform) { - VSTextCaseTransformNone, - VSTextCaseTransformUpper, - VSTextCaseTransformLower -}; - - -@class VSAnimationSpecifier; - -@interface VSTheme : NSObject - -- (id)initWithDictionary:(NSDictionary *)themeDictionary; - -@property (nonatomic, strong) NSString *name; -@property (nonatomic, weak) VSTheme *parentTheme; /*can inherit*/ - -- (nullable id)objectForKey:(NSString *)key; -- (BOOL)boolForKey:(NSString *)key; -- (nullable NSString *)stringForKey:(NSString *)key; -- (NSInteger)integerForKey:(NSString *)key; -- (CGFloat)floatForKey:(NSString *)key; - -#if TARGET_OS_IPHONE - -- (nullable UIImage *)imageForKey:(NSString *)key; /*Via UIImage imageNamed:*/ -- (UIColor *)colorForKey:(NSString *)key; /*123ABC or #123ABC: 6 digits, leading # allowed but not required*/ -- (UIEdgeInsets)edgeInsetsForKey:(NSString *)key; /*xTop, xLeft, xRight, xBottom keys*/ -- (UIFont *)fontForKey:(NSString *)key; /*x and xSize keys*/ - -#else /*Mac*/ - -- (nullable NSImage *)imageForKey:(NSString *)key; /*Via NSImage imageNamed:*/ -- (NSColor *)colorForKey:(NSString *)key; /*123ABC or #123ABC: 6 digits, leading # allowed but not required*/ -- (NSColor *)colorWithAlphaForKey:(NSString *)key; /*key and keyAlpha*/ -- (NSEdgeInsets)edgeInsetsForKey:(NSString *)key; /*xTop, xLeft, xRight, xBottom keys*/ -- (NSFont *)fontForKey:(NSString *)key; /*x and xSize keys*/ - -#endif - - -- (CGPoint)pointForKey:(NSString *)key; /*xX and xY keys*/ -- (CGSize)sizeForKey:(NSString *)key; /*xWidth and xHeight keys*/ -- (NSTimeInterval)timeIntervalForKey:(NSString *)key; - -#if TARGET_OS_IPHONE - -- (UIViewAnimationOptions)curveForKey:(NSString *)key; /*Possible values: easeinout, easeout, easein, linear*/ -- (VSAnimationSpecifier *)animationSpecifierForKey:(NSString *)key; /*xDuration, xDelay, xCurve*/ -#endif - -- (VSTextCaseTransform)textCaseTransformForKey:(NSString *)key; /*lowercase or uppercase -- returns VSTextCaseTransformNone*/ -- (NSString *)string:(NSString *)s transformedWithTextCaseTransformKey:(NSString *)key; - -@end - - -NSString *VSThemeSpecifierPlusKey(NSString *specifier, NSString *key); /*specifier + . + key*/ - - - -#if TARGET_OS_IPHONE - -@interface VSTheme (Animations) - -- (void)animateWithAnimationSpecifierKey:(NSString *)animationSpecifierKey animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion; - -@end - - -@interface VSAnimationSpecifier : NSObject - -@property (nonatomic, assign) NSTimeInterval delay; -@property (nonatomic, assign) NSTimeInterval duration; -@property (nonatomic, assign) UIViewAnimationOptions curve; - -@end - -#endif - -NS_ASSUME_NONNULL_END diff --git a/Frameworks/DB5/DB5/VSTheme.m b/Frameworks/DB5/DB5/VSTheme.m deleted file mode 100644 index dd072d875..000000000 --- a/Frameworks/DB5/DB5/VSTheme.m +++ /dev/null @@ -1,367 +0,0 @@ -// -// VSTheme.m -// Q Branch LLC -// -// Created by Brent Simmons on 6/26/13. -// Copyright (c) 2012 Q Branch LLC. All rights reserved. -// - -#import "VSTheme.h" - - -#if TARGET_OS_IPHONE - -#define VS_COLOR UIColor -#define VS_IMAGE UIImage -#define VS_FONT UIFont -#define VS_EDGE_INSETS UIEdgeInsets -#define VSEdgeInsetsMake UIEdgeInsetsMake - -#else /*Mac*/ - -#define VS_COLOR NSColor -#define VS_IMAGE NSImage -#define VS_FONT NSFont -#define VS_EDGE_INSETS NSEdgeInsets -#define VSEdgeInsetsMake NSEdgeInsetsMake - -#endif - - -static BOOL stringIsEmpty(NSString *s); -static VS_COLOR *colorWithHexString(NSString *hexString); - - -@interface VSTheme () - -@property (nonatomic, strong) NSDictionary *themeDictionary; -@property (nonatomic, strong) NSMutableDictionary *colorCache; -@property (nonatomic, strong) NSMutableDictionary *colorWithAlphaCache; -@property (nonatomic, strong) NSMutableDictionary *fontCache; - -@end - - -@implementation VSTheme - - -#pragma mark Init - -- (id)initWithDictionary:(NSDictionary *)themeDictionary { - - self = [super init]; - if (self == nil) - return nil; - - _themeDictionary = themeDictionary; - - _colorCache = [NSMutableDictionary new]; - _fontCache = [NSMutableDictionary new]; - - return self; -} - - -- (id)objectForKey:(NSString *)key { - - id obj = [self.themeDictionary valueForKeyPath:key]; - if (obj == nil && self.parentTheme != nil) - obj = [self.parentTheme objectForKey:key]; - return obj; -} - - -- (BOOL)boolForKey:(NSString *)key { - - id obj = [self objectForKey:key]; - if (obj == nil) - return NO; - return [obj boolValue]; -} - - -- (NSString *)stringForKey:(NSString *)key { - - id obj = [self objectForKey:key]; - if (obj == nil) - return nil; - if ([obj isKindOfClass:[NSString class]]) - return obj; - if ([obj isKindOfClass:[NSNumber class]]) - return [obj stringValue]; - return nil; -} - - -- (NSInteger)integerForKey:(NSString *)key { - - id obj = [self objectForKey:key]; - if (obj == nil) - return 0; - return [obj integerValue]; -} - - -- (CGFloat)floatForKey:(NSString *)key { - - id obj = [self objectForKey:key]; - if (obj == nil) - return 0.0f; - return [obj floatValue]; -} - - -- (NSTimeInterval)timeIntervalForKey:(NSString *)key { - - id obj = [self objectForKey:key]; - if (obj == nil) - return 0.0; - return [obj doubleValue]; -} - - -- (VS_IMAGE *)imageForKey:(NSString *)key { - - NSString *imageName = [self stringForKey:key]; - if (stringIsEmpty(imageName)) - return nil; - - return [VS_IMAGE imageNamed:imageName]; -} - - -- (VS_COLOR *)colorForKey:(NSString *)key { - - VS_COLOR *cachedColor = self.colorCache[key]; - if (cachedColor != nil) - return cachedColor; - - NSString *colorString = [self stringForKey:key]; - VS_COLOR *color = nil; - if ([colorString isEqualToString:@"clear"]) - color = [VS_COLOR clearColor]; - else - color = colorWithHexString(colorString); - if (color == nil) - color = [VS_COLOR blackColor]; - - self.colorCache[key] = color; - - return color; -} - - -- (VS_COLOR *)colorWithAlphaForKey:(NSString *)key { - - VS_COLOR *cachedColor = self.colorWithAlphaCache[key]; - if (cachedColor != nil) { - return cachedColor; - } - - VS_COLOR *color = [self colorForKey:key]; - CGFloat alpha = [self floatForKey:[key stringByAppendingString:@"Alpha"]]; - color = [color colorWithAlphaComponent:alpha]; - - self.colorWithAlphaCache[key] = color; - - return color; -} - - -- (VS_EDGE_INSETS)edgeInsetsForKey:(NSString *)key { - - CGFloat left = [self floatForKey:[key stringByAppendingString:@"Left"]]; - CGFloat top = [self floatForKey:[key stringByAppendingString:@"Top"]]; - CGFloat right = [self floatForKey:[key stringByAppendingString:@"Right"]]; - CGFloat bottom = [self floatForKey:[key stringByAppendingString:@"Bottom"]]; - - VS_EDGE_INSETS edgeInsets = VSEdgeInsetsMake(top, left, bottom, right); - return edgeInsets; -} - - -- (VS_FONT *)fontForKey:(NSString *)key { - - VS_FONT *cachedFont = self.fontCache[key]; - if (cachedFont != nil) - return cachedFont; - - NSString *fontName = [self stringForKey:key]; - CGFloat fontSize = [self floatForKey:[key stringByAppendingString:@"Size"]]; - - if (fontSize < 1.0f) - fontSize = 15.0f; - - VS_FONT *font = nil; - - if (stringIsEmpty(fontName)) - font = [VS_FONT systemFontOfSize:fontSize]; - else - font = [VS_FONT fontWithName:fontName size:fontSize]; - - if (font == nil) - font = [VS_FONT systemFontOfSize:fontSize]; - - self.fontCache[key] = font; - - return font; -} - - -- (CGPoint)pointForKey:(NSString *)key { - - CGFloat pointX = [self floatForKey:[key stringByAppendingString:@"X"]]; - CGFloat pointY = [self floatForKey:[key stringByAppendingString:@"Y"]]; - - CGPoint point = CGPointMake(pointX, pointY); - return point; -} - - -- (CGSize)sizeForKey:(NSString *)key { - - CGFloat width = [self floatForKey:[key stringByAppendingString:@"Width"]]; - CGFloat height = [self floatForKey:[key stringByAppendingString:@"Height"]]; - - CGSize size = CGSizeMake(width, height); - return size; -} - - -#if TARGET_OS_IPHONE - -- (UIViewAnimationOptions)curveForKey:(NSString *)key { - - NSString *curveString = [self stringForKey:key]; - if (stringIsEmpty(curveString)) - return UIViewAnimationOptionCurveEaseInOut; - - curveString = [curveString lowercaseString]; - if ([curveString isEqualToString:@"easeinout"]) - return UIViewAnimationOptionCurveEaseInOut; - else if ([curveString isEqualToString:@"easeout"]) - return UIViewAnimationOptionCurveEaseOut; - else if ([curveString isEqualToString:@"easein"]) - return UIViewAnimationOptionCurveEaseIn; - else if ([curveString isEqualToString:@"linear"]) - return UIViewAnimationOptionCurveLinear; - - return UIViewAnimationOptionCurveEaseInOut; -} - - -- (VSAnimationSpecifier *)animationSpecifierForKey:(NSString *)key { - - VSAnimationSpecifier *animationSpecifier = [VSAnimationSpecifier new]; - - animationSpecifier.duration = [self timeIntervalForKey:[key stringByAppendingString:@"Duration"]]; - animationSpecifier.delay = [self timeIntervalForKey:[key stringByAppendingString:@"Delay"]]; - animationSpecifier.curve = [self curveForKey:[key stringByAppendingString:@"Curve"]]; - - return animationSpecifier; -} - -#endif - - -- (VSTextCaseTransform)textCaseTransformForKey:(NSString *)key { - - NSString *s = [self stringForKey:key]; - if (s == nil) - return VSTextCaseTransformNone; - - if ([s caseInsensitiveCompare:@"lowercase"] == NSOrderedSame) - return VSTextCaseTransformLower; - else if ([s caseInsensitiveCompare:@"uppercase"] == NSOrderedSame) - return VSTextCaseTransformUpper; - - return VSTextCaseTransformNone; -} - - -- (NSString *)string:(NSString *)s transformedWithTextCaseTransformKey:(NSString *)key { - - VSTextCaseTransform textCaseTransform = [self textCaseTransformForKey:key]; - NSString *transformedString = nil; - - switch (textCaseTransform) { - - case VSTextCaseTransformNone: - transformedString = s; - break; - - case VSTextCaseTransformLower: - transformedString = [s lowercaseString]; - break; - - case VSTextCaseTransformUpper: - transformedString = [s uppercaseString]; - break; - - default: - break; - } - - return transformedString; -} - -@end - - -NSString *VSThemeSpecifierPlusKey(NSString *specifier, NSString *key) { - - return [NSString stringWithFormat:@"%@.%@", specifier, key]; -} - - -#if TARGET_OS_IPHONE - -@implementation VSTheme (Animations) - - -- (void)animateWithAnimationSpecifierKey:(NSString *)animationSpecifierKey animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion { - - VSAnimationSpecifier *animationSpecifier = [self animationSpecifierForKey:animationSpecifierKey]; - - [UIView animateWithDuration:animationSpecifier.duration delay:animationSpecifier.delay options:animationSpecifier.curve animations:animations completion:completion]; -} - -@end - - -#pragma mark - - -@implementation VSAnimationSpecifier - -@end - -#endif - - -static BOOL stringIsEmpty(NSString *s) { - return s == nil || [s length] == 0; -} - - -static VS_COLOR *colorWithHexString(NSString *hexString) { - - /*Picky. Crashes by design.*/ - - if (stringIsEmpty(hexString)) - return [VS_COLOR blackColor]; - - NSMutableString *s = [hexString mutableCopy]; - [s replaceOccurrencesOfString:@"#" withString:@"" options:0 range:NSMakeRange(0, [hexString length])]; - CFStringTrimWhitespace((__bridge CFMutableStringRef)s); - - NSString *redString = [s substringToIndex:2]; - NSString *greenString = [s substringWithRange:NSMakeRange(2, 2)]; - NSString *blueString = [s substringWithRange:NSMakeRange(4, 2)]; - - unsigned int red = 0, green = 0, blue = 0; - [[NSScanner scannerWithString:redString] scanHexInt:&red]; - [[NSScanner scannerWithString:greenString] scanHexInt:&green]; - [[NSScanner scannerWithString:blueString] scanHexInt:&blue]; - - return [VS_COLOR colorWithRed:(CGFloat)red/255.0f green:(CGFloat)green/255.0f blue:(CGFloat)blue/255.0f alpha:1.0f]; -} diff --git a/Frameworks/DB5/DB5/VSThemeLoader.h b/Frameworks/DB5/DB5/VSThemeLoader.h deleted file mode 100644 index cc958d282..000000000 --- a/Frameworks/DB5/DB5/VSThemeLoader.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// VSThemeLoader.h -// Q Branch LLC -// -// Created by Brent Simmons on 6/26/13. -// Copyright (c) 2012 Q Branch LLC. All rights reserved. -// - -#import - - -@class VSTheme; - -@interface VSThemeLoader : NSObject - -// Just use -init if you want the default DB5.plist in the normal place. -- (instancetype)initWithFilepath:(NSString *)f; - -@property (nonatomic, strong, readonly) VSTheme *defaultTheme; -@property (nonatomic, strong, readonly) NSArray *themes; - -- (VSTheme *)themeNamed:(NSString *)themeName; - -@end diff --git a/Frameworks/DB5/DB5/VSThemeLoader.m b/Frameworks/DB5/DB5/VSThemeLoader.m deleted file mode 100644 index 2e758d1a4..000000000 --- a/Frameworks/DB5/DB5/VSThemeLoader.m +++ /dev/null @@ -1,71 +0,0 @@ -// -// VSThemeLoader.h -// Q Branch LLC -// -// Created by Brent Simmons on 6/26/13. -// Copyright (c) 2012 Q Branch LLC. All rights reserved. -// - - -#import "VSThemeLoader.h" -#import "VSTheme.h" - - -@interface VSThemeLoader () - -@property (nonatomic, strong, readwrite) VSTheme *defaultTheme; -@property (nonatomic, strong, readwrite) NSArray *themes; -@end - - -@implementation VSThemeLoader - - -- (instancetype)init { - - NSString *themesFilePath = [[NSBundle mainBundle] pathForResource:@"DB5" ofType:@"plist"]; - return [self initWithFilepath:themesFilePath]; -} - - -- (instancetype)initWithFilepath:(NSString *)f { - - self = [super init]; - if (!self) { - return nil; - } - - NSDictionary *themesDictionary = [NSDictionary dictionaryWithContentsOfFile:f]; - - NSMutableArray *themes = [NSMutableArray array]; - for (NSString *oneKey in themesDictionary) { - - VSTheme *theme = [[VSTheme alloc] initWithDictionary:themesDictionary[oneKey]]; - if ([[oneKey lowercaseString] isEqualToString:@"default"]) - _defaultTheme = theme; - theme.name = oneKey; - [themes addObject:theme]; - } - - for (VSTheme *oneTheme in themes) { /*All themes inherit from the default theme.*/ - if (oneTheme != _defaultTheme) - oneTheme.parentTheme = _defaultTheme; - } - - _themes = themes; - - return self; -} - - -- (VSTheme *)themeNamed:(NSString *)themeName { - - for (VSTheme *oneTheme in self.themes) { - if ([themeName isEqualToString:oneTheme.name]) - return oneTheme; - } - - return nil; -} - -@end diff --git a/Frameworks/DB5/DB5Tests/DB5Tests.m b/Frameworks/DB5/DB5Tests/DB5Tests.m deleted file mode 100644 index 613bc71bc..000000000 --- a/Frameworks/DB5/DB5Tests/DB5Tests.m +++ /dev/null @@ -1,39 +0,0 @@ -// -// DB5Tests.m -// DB5Tests -// -// Created by Brent Simmons on 7/12/15. -// Copyright © 2015 Ranchero Software, LLC. All rights reserved. -// - -#import - -@interface DB5Tests : XCTestCase - -@end - -@implementation DB5Tests - -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testExample { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. -} - -- (void)testPerformanceExample { - // This is an example of a performance test case. - [self measureBlock:^{ - // Put the code you want to measure the time of here. - }]; -} - -@end diff --git a/Frameworks/DB5/DB5Tests/Info.plist b/Frameworks/DB5/DB5Tests/Info.plist deleted file mode 100644 index ba72822e8..000000000 --- a/Frameworks/DB5/DB5Tests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/Frameworks/DB5/xcconfig/DB5Tests_target.xcconfig b/Frameworks/DB5/xcconfig/DB5Tests_target.xcconfig deleted file mode 100644 index 8bb78cf79..000000000 --- a/Frameworks/DB5/xcconfig/DB5Tests_target.xcconfig +++ /dev/null @@ -1,15 +0,0 @@ - -LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks -INFOPLIST_FILE = DB5Tests/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DB5Tests -PRODUCT_NAME = $(TARGET_NAME) - - - - - - - - - - diff --git a/Frameworks/DB5/xcconfig/DB5_project.xcconfig b/Frameworks/DB5/xcconfig/DB5_project.xcconfig deleted file mode 100644 index 77e3c069b..000000000 --- a/Frameworks/DB5/xcconfig/DB5_project.xcconfig +++ /dev/null @@ -1,54 +0,0 @@ -// CODE_SIGN_IDENTITY = -// CODE_SIGN_STYLE = Automatic -// DEVELOPMENT_TEAM = M8L2WTLA8W - -// See the notes in Evergreen_target.xcconfig on why the -// DeveloperSettings.xcconfig is #included here - -#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig" - -SDKROOT = macosx -MACOSX_DEPLOYMENT_TARGET = 10.13 -CLANG_ENABLE_OBJC_WEAK = YES -SWIFT_VERSION = 3.0 -COMBINE_HIDPI_IMAGES = YES - -COPY_PHASE_STRIP = NO -MACOSX_DEPLOYMENT_TARGET = 10.13 -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_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 diff --git a/Frameworks/DB5/xcconfig/DB5_project_debug.xcconfig b/Frameworks/DB5/xcconfig/DB5_project_debug.xcconfig deleted file mode 100644 index 83134fa20..000000000 --- a/Frameworks/DB5/xcconfig/DB5_project_debug.xcconfig +++ /dev/null @@ -1,11 +0,0 @@ -#include "./DB5_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 -ONLY_ACTIVE_ARCH = YES - diff --git a/Frameworks/DB5/xcconfig/DB5_project_release.xcconfig b/Frameworks/DB5/xcconfig/DB5_project_release.xcconfig deleted file mode 100644 index b9ed4398c..000000000 --- a/Frameworks/DB5/xcconfig/DB5_project_release.xcconfig +++ /dev/null @@ -1,7 +0,0 @@ -#include "./DB5_project.xcconfig" - -DEBUG_INFORMATION_FORMAT = dwarf-with-dsym -ENABLE_NS_ASSERTIONS = NO - -MTL_ENABLE_DEBUG_INFO = NO - diff --git a/Frameworks/DB5/xcconfig/DB5_target.xcconfig b/Frameworks/DB5/xcconfig/DB5_target.xcconfig deleted file mode 100644 index b5494e7dc..000000000 --- a/Frameworks/DB5/xcconfig/DB5_target.xcconfig +++ /dev/null @@ -1,16 +0,0 @@ - -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 = DB5/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DB5 -PRODUCT_NAME = $(TARGET_NAME:c99extidentifier) -CLANG_ENABLE_MODULES = YES -CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES - - From 375bef6d44f5684fee3fab85f7fb24949dbc9086 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Thu, 21 Jun 2018 13:06:13 -0700 Subject: [PATCH 02/40] Break build. Rename RSFeedFinder on disk to FeedFinder. --- .../FeedFinder.xcodeproj}/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 .../RSFeedFinder => FeedFinder/FeedFinder}/FeedFinder.swift | 0 .../RSFeedFinder => FeedFinder/FeedFinder}/FeedSpecifier.swift | 0 .../RSFeedFinder => FeedFinder/FeedFinder}/HTMLFeedFinder.swift | 0 .../RSFeedFinder => FeedFinder/FeedFinder}/Info.plist | 0 .../RSFeedFinder => FeedFinder/FeedFinder}/RSFeedFinder.h | 0 .../FeedFinderTests}/HTMLFeedFinderTests.swift | 0 .../RSFeedFinderTests => FeedFinder/FeedFinderTests}/Info.plist | 0 .../FeedFinderTests}/RSFeedFinderTests.m | 0 .../FeedFinderTests}/Resources/DaringFireball.html | 0 .../FeedFinderTests}/Resources/furbo.html | 0 .../FeedFinderTests}/Resources/indiestack.html | 0 .../FeedFinderTests}/Resources/inessential.html | 0 .../FeedFinderTests}/Resources/sixcolors.html | 0 .../xcconfig/RSFeedFinderTests_target.xcconfig | 0 .../xcconfig/RSFeedFinder_project.xcconfig | 0 .../xcconfig/RSFeedFinder_project_debug.xcconfig | 0 .../xcconfig/RSFeedFinder_project_release.xcconfig | 0 .../xcconfig/RSFeedFinder_target.xcconfig | 0 20 files changed, 0 insertions(+), 0 deletions(-) rename Frameworks/{RSFeedFinder/RSFeedFinder.xcodeproj => FeedFinder/FeedFinder.xcodeproj}/project.pbxproj (100%) rename Frameworks/{RSFeedFinder/RSFeedFinder.xcodeproj => FeedFinder/FeedFinder.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (100%) rename Frameworks/{RSFeedFinder/RSFeedFinder => FeedFinder/FeedFinder}/FeedFinder.swift (100%) rename Frameworks/{RSFeedFinder/RSFeedFinder => FeedFinder/FeedFinder}/FeedSpecifier.swift (100%) rename Frameworks/{RSFeedFinder/RSFeedFinder => FeedFinder/FeedFinder}/HTMLFeedFinder.swift (100%) rename Frameworks/{RSFeedFinder/RSFeedFinder => FeedFinder/FeedFinder}/Info.plist (100%) rename Frameworks/{RSFeedFinder/RSFeedFinder => FeedFinder/FeedFinder}/RSFeedFinder.h (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/HTMLFeedFinderTests.swift (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/Info.plist (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/RSFeedFinderTests.m (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/Resources/DaringFireball.html (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/Resources/furbo.html (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/Resources/indiestack.html (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/Resources/inessential.html (100%) rename Frameworks/{RSFeedFinder/RSFeedFinderTests => FeedFinder/FeedFinderTests}/Resources/sixcolors.html (100%) rename Frameworks/{RSFeedFinder => FeedFinder}/xcconfig/RSFeedFinderTests_target.xcconfig (100%) rename Frameworks/{RSFeedFinder => FeedFinder}/xcconfig/RSFeedFinder_project.xcconfig (100%) rename Frameworks/{RSFeedFinder => FeedFinder}/xcconfig/RSFeedFinder_project_debug.xcconfig (100%) rename Frameworks/{RSFeedFinder => FeedFinder}/xcconfig/RSFeedFinder_project_release.xcconfig (100%) rename Frameworks/{RSFeedFinder => FeedFinder}/xcconfig/RSFeedFinder_target.xcconfig (100%) diff --git a/Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj/project.pbxproj b/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj/project.pbxproj rename to Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj diff --git a/Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Frameworks/FeedFinder/FeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Frameworks/RSFeedFinder/RSFeedFinder/FeedFinder.swift b/Frameworks/FeedFinder/FeedFinder/FeedFinder.swift similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinder/FeedFinder.swift rename to Frameworks/FeedFinder/FeedFinder/FeedFinder.swift diff --git a/Frameworks/RSFeedFinder/RSFeedFinder/FeedSpecifier.swift b/Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinder/FeedSpecifier.swift rename to Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift diff --git a/Frameworks/RSFeedFinder/RSFeedFinder/HTMLFeedFinder.swift b/Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinder/HTMLFeedFinder.swift rename to Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift diff --git a/Frameworks/RSFeedFinder/RSFeedFinder/Info.plist b/Frameworks/FeedFinder/FeedFinder/Info.plist similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinder/Info.plist rename to Frameworks/FeedFinder/FeedFinder/Info.plist diff --git a/Frameworks/RSFeedFinder/RSFeedFinder/RSFeedFinder.h b/Frameworks/FeedFinder/FeedFinder/RSFeedFinder.h similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinder/RSFeedFinder.h rename to Frameworks/FeedFinder/FeedFinder/RSFeedFinder.h diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/HTMLFeedFinderTests.swift b/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/HTMLFeedFinderTests.swift rename to Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/Info.plist b/Frameworks/FeedFinder/FeedFinderTests/Info.plist similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/Info.plist rename to Frameworks/FeedFinder/FeedFinderTests/Info.plist diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/RSFeedFinderTests.m b/Frameworks/FeedFinder/FeedFinderTests/RSFeedFinderTests.m similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/RSFeedFinderTests.m rename to Frameworks/FeedFinder/FeedFinderTests/RSFeedFinderTests.m diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/DaringFireball.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/DaringFireball.html similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/DaringFireball.html rename to Frameworks/FeedFinder/FeedFinderTests/Resources/DaringFireball.html diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/furbo.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/furbo.html similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/furbo.html rename to Frameworks/FeedFinder/FeedFinderTests/Resources/furbo.html diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/indiestack.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/indiestack.html similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/indiestack.html rename to Frameworks/FeedFinder/FeedFinderTests/Resources/indiestack.html diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/inessential.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/inessential.html similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/inessential.html rename to Frameworks/FeedFinder/FeedFinderTests/Resources/inessential.html diff --git a/Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/sixcolors.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/sixcolors.html similarity index 100% rename from Frameworks/RSFeedFinder/RSFeedFinderTests/Resources/sixcolors.html rename to Frameworks/FeedFinder/FeedFinderTests/Resources/sixcolors.html diff --git a/Frameworks/RSFeedFinder/xcconfig/RSFeedFinderTests_target.xcconfig b/Frameworks/FeedFinder/xcconfig/RSFeedFinderTests_target.xcconfig similarity index 100% rename from Frameworks/RSFeedFinder/xcconfig/RSFeedFinderTests_target.xcconfig rename to Frameworks/FeedFinder/xcconfig/RSFeedFinderTests_target.xcconfig diff --git a/Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_project.xcconfig b/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project.xcconfig similarity index 100% rename from Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_project.xcconfig rename to Frameworks/FeedFinder/xcconfig/RSFeedFinder_project.xcconfig diff --git a/Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_project_debug.xcconfig b/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_debug.xcconfig similarity index 100% rename from Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_project_debug.xcconfig rename to Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_debug.xcconfig diff --git a/Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_project_release.xcconfig b/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_release.xcconfig similarity index 100% rename from Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_project_release.xcconfig rename to Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_release.xcconfig diff --git a/Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_target.xcconfig b/Frameworks/FeedFinder/xcconfig/RSFeedFinder_target.xcconfig similarity index 100% rename from Frameworks/RSFeedFinder/xcconfig/RSFeedFinder_target.xcconfig rename to Frameworks/FeedFinder/xcconfig/RSFeedFinder_target.xcconfig From 168f6138acaf160d5afeb13c3ab03b9717445bd6 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Thu, 21 Jun 2018 13:07:31 -0700 Subject: [PATCH 03/40] Rename RSFeedFinder.h to FeedFinder.h. --- Frameworks/FeedFinder/FeedFinder/{RSFeedFinder.h => FeedFinder.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Frameworks/FeedFinder/FeedFinder/{RSFeedFinder.h => FeedFinder.h} (100%) diff --git a/Frameworks/FeedFinder/FeedFinder/RSFeedFinder.h b/Frameworks/FeedFinder/FeedFinder/FeedFinder.h similarity index 100% rename from Frameworks/FeedFinder/FeedFinder/RSFeedFinder.h rename to Frameworks/FeedFinder/FeedFinder/FeedFinder.h From b61df8c1851679f3c106b5e6417fefd2ed49e3a5 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Thu, 21 Jun 2018 13:18:28 -0700 Subject: [PATCH 04/40] Rename RSFeedFinder references to FeedFinder. --- .../FeedFinder.xcodeproj/project.pbxproj | 191 ++++++++++-------- Frameworks/FeedFinder/FeedFinder/FeedFinder.h | 14 +- .../FeedFinder/FeedFinder/FeedFinder.swift | 2 +- .../FeedFinder/FeedFinder/FeedSpecifier.swift | 2 +- .../FeedFinder/HTMLFeedFinder.swift | 2 +- ...{RSFeedFinderTests.m => FeedFinderTests.m} | 8 +- .../FeedFinderTests/HTMLFeedFinderTests.swift | 4 +- ...config => FeedFinderTests_target.xcconfig} | 4 +- ...t.xcconfig => FeedFinder_project.xcconfig} | 0 ...nfig => FeedFinder_project_debug.xcconfig} | 2 +- ...ig => FeedFinder_project_release.xcconfig} | 2 +- ...et.xcconfig => FeedFinder_target.xcconfig} | 4 +- 12 files changed, 125 insertions(+), 110 deletions(-) rename Frameworks/FeedFinder/FeedFinderTests/{RSFeedFinderTests.m => FeedFinderTests.m} (86%) rename Frameworks/FeedFinder/xcconfig/{RSFeedFinderTests_target.xcconfig => FeedFinderTests_target.xcconfig} (63%) rename Frameworks/FeedFinder/xcconfig/{RSFeedFinder_project.xcconfig => FeedFinder_project.xcconfig} (100%) rename Frameworks/FeedFinder/xcconfig/{RSFeedFinder_project_debug.xcconfig => FeedFinder_project_debug.xcconfig} (88%) rename Frameworks/FeedFinder/xcconfig/{RSFeedFinder_project_release.xcconfig => FeedFinder_project_release.xcconfig} (79%) rename Frameworks/FeedFinder/xcconfig/{RSFeedFinder_target.xcconfig => FeedFinder_target.xcconfig} (77%) diff --git a/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj b/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj index 6da537d74..30812b880 100644 --- a/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj +++ b/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj @@ -7,21 +7,21 @@ objects = { /* Begin PBXBuildFile section */ - 8430C4701D57ED6D00E02399 /* FeedSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8430C46F1D57ED6D00E02399 /* FeedSpecifier.swift */; }; - 8430C4721D57F88600E02399 /* HTMLFeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8430C4711D57F88600E02399 /* HTMLFeedFinder.swift */; }; - 8430C4741D57FE9600E02399 /* HTMLFeedFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8430C4731D57FE9600E02399 /* HTMLFeedFinderTests.swift */; }; - 8430C4761D57FF0600E02399 /* DaringFireball.html in Resources */ = {isa = PBXBuildFile; fileRef = 8430C4751D57FF0600E02399 /* DaringFireball.html */; }; - 8430C47A1D58033D00E02399 /* furbo.html in Resources */ = {isa = PBXBuildFile; fileRef = 8430C4771D58033D00E02399 /* furbo.html */; }; - 8430C47B1D58033D00E02399 /* inessential.html in Resources */ = {isa = PBXBuildFile; fileRef = 8430C4781D58033D00E02399 /* inessential.html */; }; - 8430C47C1D58033D00E02399 /* sixcolors.html in Resources */ = {isa = PBXBuildFile; fileRef = 8430C4791D58033D00E02399 /* sixcolors.html */; }; - 8444267C1D5138A00092EDD4 /* FeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8444267B1D5138A00092EDD4 /* FeedFinder.swift */; }; - 8452130F1FCA45EA003B6E93 /* indiestack.html in Resources */ = {isa = PBXBuildFile; fileRef = 8452130E1FCA45EA003B6E93 /* indiestack.html */; }; 84B06FEF1ED3808F00F0B54B /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FEE1ED3808F00F0B54B /* RSWeb.framework */; }; 84B06FF31ED3812600F0B54B /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FF21ED3812600F0B54B /* RSCore.framework */; }; - 84BAAE231C8E6B3B009F5239 /* RSFeedFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84BAAE221C8E6B3B009F5239 /* RSFeedFinder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 84BAAE2A1C8E6B3B009F5239 /* RSFeedFinder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BAAE1F1C8E6B3B009F5239 /* RSFeedFinder.framework */; }; - 84BAAE2F1C8E6B3B009F5239 /* RSFeedFinderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 84BAAE2E1C8E6B3B009F5239 /* RSFeedFinderTests.m */; }; + 84BAAE2A1C8E6B3B009F5239 /* FeedFinder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */; }; 84F466571F03523100225386 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F466561F03523100225386 /* RSParser.framework */; }; + 84FE13C220DC3D960029AB7B /* FeedFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84FE13C120DC3D960029AB7B /* FeedFinder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 84FE13C420DC3DA70029AB7B /* FeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13C320DC3DA70029AB7B /* FeedFinder.swift */; }; + 84FE13C620DC3DAE0029AB7B /* FeedSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13C520DC3DAE0029AB7B /* FeedSpecifier.swift */; }; + 84FE13C820DC3DB50029AB7B /* HTMLFeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13C720DC3DB50029AB7B /* HTMLFeedFinder.swift */; }; + 84FE13D420DC3DDF0029AB7B /* FeedFinderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13CB20DC3DDF0029AB7B /* FeedFinderTests.m */; }; + 84FE13D520DC3DDF0029AB7B /* indiestack.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13CD20DC3DDF0029AB7B /* indiestack.html */; }; + 84FE13D620DC3DDF0029AB7B /* sixcolors.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13CE20DC3DDF0029AB7B /* sixcolors.html */; }; + 84FE13D720DC3DDF0029AB7B /* DaringFireball.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13CF20DC3DDF0029AB7B /* DaringFireball.html */; }; + 84FE13D820DC3DDF0029AB7B /* inessential.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13D020DC3DDF0029AB7B /* inessential.html */; }; + 84FE13D920DC3DDF0029AB7B /* furbo.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13D120DC3DDF0029AB7B /* furbo.html */; }; + 84FE13DA20DC3DDF0029AB7B /* HTMLFeedFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13D220DC3DDF0029AB7B /* HTMLFeedFinderTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -35,33 +35,33 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 8430C46F1D57ED6D00E02399 /* FeedSpecifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FeedSpecifier.swift; path = RSFeedFinder/FeedSpecifier.swift; sourceTree = ""; }; - 8430C4711D57F88600E02399 /* HTMLFeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HTMLFeedFinder.swift; path = RSFeedFinder/HTMLFeedFinder.swift; sourceTree = ""; }; - 8430C4731D57FE9600E02399 /* HTMLFeedFinderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLFeedFinderTests.swift; sourceTree = ""; }; - 8430C4751D57FF0600E02399 /* DaringFireball.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = DaringFireball.html; path = Resources/DaringFireball.html; sourceTree = ""; }; - 8430C4771D58033D00E02399 /* furbo.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = furbo.html; path = Resources/furbo.html; sourceTree = ""; }; - 8430C4781D58033D00E02399 /* inessential.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = inessential.html; path = Resources/inessential.html; sourceTree = ""; }; - 8430C4791D58033D00E02399 /* sixcolors.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = sixcolors.html; path = Resources/sixcolors.html; sourceTree = ""; }; - 8444267B1D5138A00092EDD4 /* FeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FeedFinder.swift; path = RSFeedFinder/FeedFinder.swift; sourceTree = ""; }; - 8452130E1FCA45EA003B6E93 /* indiestack.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = indiestack.html; path = Resources/indiestack.html; sourceTree = ""; }; 84B06FEE1ED3808F00F0B54B /* RSWeb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSWeb.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Evergreen-edcdqyvewhytnmcfaiesnqiqeynn/Build/Products/Debug/RSWeb.framework"; sourceTree = ""; }; 84B06FF01ED380A700F0B54B /* RSXML.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSXML.framework; path = ../RSXML/build/Debug/RSXML.framework; sourceTree = ""; }; 84B06FF21ED3812600F0B54B /* RSCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSCore.framework; path = ../RSCore/build/Debug/RSCore.framework; sourceTree = ""; }; - 84BAAE1F1C8E6B3B009F5239 /* RSFeedFinder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RSFeedFinder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 84BAAE221C8E6B3B009F5239 /* RSFeedFinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RSFeedFinder.h; path = RSFeedFinder/RSFeedFinder.h; sourceTree = ""; }; - 84BAAE241C8E6B3B009F5239 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = RSFeedFinder/Info.plist; sourceTree = ""; }; - 84BAAE291C8E6B3B009F5239 /* RSFeedFinderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RSFeedFinderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 84BAAE2E1C8E6B3B009F5239 /* RSFeedFinderTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RSFeedFinderTests.m; sourceTree = ""; }; - 84BAAE301C8E6B3B009F5239 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FeedFinder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 84BAAE291C8E6B3B009F5239 /* FeedFinderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FeedFinderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 84E697E51C8E6C10009C585A /* RSCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSCore.framework; path = ../RSCore/build/Debug/RSCore.framework; sourceTree = ""; }; 84E697E71C8E6C16009C585A /* RSXML.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSXML.framework; path = ../RSXML/build/Debug/RSXML.framework; sourceTree = ""; }; 84E697E91C8E6C20009C585A /* RSWeb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSWeb.framework; path = ../RSWeb/build/Debug/RSWeb.framework; sourceTree = ""; }; 84F466561F03523100225386 /* RSParser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSParser.framework; path = ../RSParser/build/Debug/RSParser.framework; sourceTree = ""; }; - D511EF0920242E7A00712EC3 /* RSFeedFinder_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RSFeedFinder_project.xcconfig; sourceTree = ""; }; - D511EF0A20242E7A00712EC3 /* RSFeedFinder_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RSFeedFinder_target.xcconfig; sourceTree = ""; }; - D511EF0B20242E7A00712EC3 /* RSFeedFinder_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RSFeedFinder_project_release.xcconfig; sourceTree = ""; }; - D511EF0C20242E7A00712EC3 /* RSFeedFinderTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RSFeedFinderTests_target.xcconfig; sourceTree = ""; }; - D511EF0D20242E7A00712EC3 /* RSFeedFinder_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = RSFeedFinder_project_debug.xcconfig; sourceTree = ""; }; + 84FE13C120DC3D960029AB7B /* FeedFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FeedFinder.h; path = FeedFinder/FeedFinder.h; sourceTree = ""; }; + 84FE13C320DC3DA70029AB7B /* FeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FeedFinder.swift; path = FeedFinder/FeedFinder.swift; sourceTree = ""; }; + 84FE13C520DC3DAE0029AB7B /* FeedSpecifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FeedSpecifier.swift; path = FeedFinder/FeedSpecifier.swift; sourceTree = ""; }; + 84FE13C720DC3DB50029AB7B /* HTMLFeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HTMLFeedFinder.swift; path = FeedFinder/HTMLFeedFinder.swift; sourceTree = ""; }; + 84FE13C920DC3DCA0029AB7B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = FeedFinder/Info.plist; sourceTree = ""; }; + 84FE13CB20DC3DDF0029AB7B /* FeedFinderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedFinderTests.m; sourceTree = ""; }; + 84FE13CD20DC3DDF0029AB7B /* indiestack.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = indiestack.html; sourceTree = ""; }; + 84FE13CE20DC3DDF0029AB7B /* sixcolors.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = sixcolors.html; sourceTree = ""; }; + 84FE13CF20DC3DDF0029AB7B /* DaringFireball.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DaringFireball.html; sourceTree = ""; }; + 84FE13D020DC3DDF0029AB7B /* inessential.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = inessential.html; sourceTree = ""; }; + 84FE13D120DC3DDF0029AB7B /* furbo.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = furbo.html; sourceTree = ""; }; + 84FE13D220DC3DDF0029AB7B /* HTMLFeedFinderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLFeedFinderTests.swift; sourceTree = ""; }; + 84FE13D320DC3DDF0029AB7B /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 84FE13DC20DC3E4E0029AB7B /* FeedFinder_project_debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FeedFinder_project_debug.xcconfig; sourceTree = ""; }; + D511EF0920242E7A00712EC3 /* FeedFinder_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinder_project.xcconfig; sourceTree = ""; }; + D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinder_target.xcconfig; sourceTree = ""; }; + D511EF0B20242E7A00712EC3 /* FeedFinder_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinder_project_release.xcconfig; sourceTree = ""; }; + D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinderTests_target.xcconfig; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -79,7 +79,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84BAAE2A1C8E6B3B009F5239 /* RSFeedFinder.framework in Frameworks */, + 84BAAE2A1C8E6B3B009F5239 /* FeedFinder.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -100,15 +100,15 @@ 84BAAE151C8E6B3B009F5239 = { isa = PBXGroup; children = ( - 84BAAE221C8E6B3B009F5239 /* RSFeedFinder.h */, - 8444267B1D5138A00092EDD4 /* FeedFinder.swift */, - 8430C46F1D57ED6D00E02399 /* FeedSpecifier.swift */, - 8430C4711D57F88600E02399 /* HTMLFeedFinder.swift */, - 84BAAE241C8E6B3B009F5239 /* Info.plist */, + 84FE13C120DC3D960029AB7B /* FeedFinder.h */, + 84FE13C320DC3DA70029AB7B /* FeedFinder.swift */, + 84FE13C520DC3DAE0029AB7B /* FeedSpecifier.swift */, + 84FE13C720DC3DB50029AB7B /* HTMLFeedFinder.swift */, + 84FE13C920DC3DCA0029AB7B /* Info.plist */, 84E697E91C8E6C20009C585A /* RSWeb.framework */, 84E697E71C8E6C16009C585A /* RSXML.framework */, 84E697E51C8E6C10009C585A /* RSCore.framework */, - 84BAAE2D1C8E6B3B009F5239 /* RSFeedFinderTests */, + 84FE13CA20DC3DDF0029AB7B /* FeedFinderTests */, 84BAAE201C8E6B3B009F5239 /* Products */, 84B06FED1ED3808E00F0B54B /* Frameworks */, D511EF0820242E7A00712EC3 /* xcconfig */, @@ -118,35 +118,43 @@ 84BAAE201C8E6B3B009F5239 /* Products */ = { isa = PBXGroup; children = ( - 84BAAE1F1C8E6B3B009F5239 /* RSFeedFinder.framework */, - 84BAAE291C8E6B3B009F5239 /* RSFeedFinderTests.xctest */, + 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */, + 84BAAE291C8E6B3B009F5239 /* FeedFinderTests.xctest */, ); name = Products; sourceTree = ""; }; - 84BAAE2D1C8E6B3B009F5239 /* RSFeedFinderTests */ = { + 84FE13CA20DC3DDF0029AB7B /* FeedFinderTests */ = { isa = PBXGroup; children = ( - 84BAAE2E1C8E6B3B009F5239 /* RSFeedFinderTests.m */, - 8430C4731D57FE9600E02399 /* HTMLFeedFinderTests.swift */, - 8430C4751D57FF0600E02399 /* DaringFireball.html */, - 8452130E1FCA45EA003B6E93 /* indiestack.html */, - 8430C4771D58033D00E02399 /* furbo.html */, - 8430C4781D58033D00E02399 /* inessential.html */, - 8430C4791D58033D00E02399 /* sixcolors.html */, - 84BAAE301C8E6B3B009F5239 /* Info.plist */, + 84FE13CB20DC3DDF0029AB7B /* FeedFinderTests.m */, + 84FE13CC20DC3DDF0029AB7B /* Resources */, + 84FE13D220DC3DDF0029AB7B /* HTMLFeedFinderTests.swift */, + 84FE13D320DC3DDF0029AB7B /* Info.plist */, ); - path = RSFeedFinderTests; + path = FeedFinderTests; + sourceTree = ""; + }; + 84FE13CC20DC3DDF0029AB7B /* Resources */ = { + isa = PBXGroup; + children = ( + 84FE13CD20DC3DDF0029AB7B /* indiestack.html */, + 84FE13CE20DC3DDF0029AB7B /* sixcolors.html */, + 84FE13CF20DC3DDF0029AB7B /* DaringFireball.html */, + 84FE13D020DC3DDF0029AB7B /* inessential.html */, + 84FE13D120DC3DDF0029AB7B /* furbo.html */, + ); + path = Resources; sourceTree = ""; }; D511EF0820242E7A00712EC3 /* xcconfig */ = { isa = PBXGroup; children = ( - D511EF0920242E7A00712EC3 /* RSFeedFinder_project.xcconfig */, - D511EF0D20242E7A00712EC3 /* RSFeedFinder_project_debug.xcconfig */, - D511EF0B20242E7A00712EC3 /* RSFeedFinder_project_release.xcconfig */, - D511EF0A20242E7A00712EC3 /* RSFeedFinder_target.xcconfig */, - D511EF0C20242E7A00712EC3 /* RSFeedFinderTests_target.xcconfig */, + D511EF0920242E7A00712EC3 /* FeedFinder_project.xcconfig */, + 84FE13DC20DC3E4E0029AB7B /* FeedFinder_project_debug.xcconfig */, + D511EF0B20242E7A00712EC3 /* FeedFinder_project_release.xcconfig */, + D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */, + D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */, ); path = xcconfig; sourceTree = ""; @@ -158,16 +166,16 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 84BAAE231C8E6B3B009F5239 /* RSFeedFinder.h in Headers */, + 84FE13C220DC3D960029AB7B /* FeedFinder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 84BAAE1E1C8E6B3B009F5239 /* RSFeedFinder */ = { + 84BAAE1E1C8E6B3B009F5239 /* FeedFinder */ = { isa = PBXNativeTarget; - buildConfigurationList = 84BAAE331C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "RSFeedFinder" */; + buildConfigurationList = 84BAAE331C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinder" */; buildPhases = ( 84BAAE1A1C8E6B3B009F5239 /* Sources */, 84BAAE1B1C8E6B3B009F5239 /* Frameworks */, @@ -178,14 +186,14 @@ ); dependencies = ( ); - name = RSFeedFinder; + name = FeedFinder; productName = RSFeedFinder; - productReference = 84BAAE1F1C8E6B3B009F5239 /* RSFeedFinder.framework */; + productReference = 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */; productType = "com.apple.product-type.framework"; }; - 84BAAE281C8E6B3B009F5239 /* RSFeedFinderTests */ = { + 84BAAE281C8E6B3B009F5239 /* FeedFinderTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 84BAAE361C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "RSFeedFinderTests" */; + buildConfigurationList = 84BAAE361C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinderTests" */; buildPhases = ( 84BAAE251C8E6B3B009F5239 /* Sources */, 84BAAE261C8E6B3B009F5239 /* Frameworks */, @@ -196,9 +204,9 @@ dependencies = ( 84BAAE2C1C8E6B3B009F5239 /* PBXTargetDependency */, ); - name = RSFeedFinderTests; + name = FeedFinderTests; productName = RSFeedFinderTests; - productReference = 84BAAE291C8E6B3B009F5239 /* RSFeedFinderTests.xctest */; + productReference = 84BAAE291C8E6B3B009F5239 /* FeedFinderTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -220,7 +228,7 @@ }; }; }; - buildConfigurationList = 84BAAE191C8E6B3B009F5239 /* Build configuration list for PBXProject "RSFeedFinder" */; + buildConfigurationList = 84BAAE191C8E6B3B009F5239 /* Build configuration list for PBXProject "FeedFinder" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -232,8 +240,8 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 84BAAE1E1C8E6B3B009F5239 /* RSFeedFinder */, - 84BAAE281C8E6B3B009F5239 /* RSFeedFinderTests */, + 84BAAE1E1C8E6B3B009F5239 /* FeedFinder */, + 84BAAE281C8E6B3B009F5239 /* FeedFinderTests */, ); }; /* End PBXProject section */ @@ -250,11 +258,11 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8430C47B1D58033D00E02399 /* inessential.html in Resources */, - 8430C4761D57FF0600E02399 /* DaringFireball.html in Resources */, - 8452130F1FCA45EA003B6E93 /* indiestack.html in Resources */, - 8430C47A1D58033D00E02399 /* furbo.html in Resources */, - 8430C47C1D58033D00E02399 /* sixcolors.html in Resources */, + 84FE13D820DC3DDF0029AB7B /* inessential.html in Resources */, + 84FE13D920DC3DDF0029AB7B /* furbo.html in Resources */, + 84FE13D720DC3DDF0029AB7B /* DaringFireball.html in Resources */, + 84FE13D520DC3DDF0029AB7B /* indiestack.html in Resources */, + 84FE13D620DC3DDF0029AB7B /* sixcolors.html in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -265,9 +273,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8430C4721D57F88600E02399 /* HTMLFeedFinder.swift in Sources */, - 8430C4701D57ED6D00E02399 /* FeedSpecifier.swift in Sources */, - 8444267C1D5138A00092EDD4 /* FeedFinder.swift in Sources */, + 84FE13C420DC3DA70029AB7B /* FeedFinder.swift in Sources */, + 84FE13C820DC3DB50029AB7B /* HTMLFeedFinder.swift in Sources */, + 84FE13C620DC3DAE0029AB7B /* FeedSpecifier.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -275,8 +283,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8430C4741D57FE9600E02399 /* HTMLFeedFinderTests.swift in Sources */, - 84BAAE2F1C8E6B3B009F5239 /* RSFeedFinderTests.m in Sources */, + 84FE13DA20DC3DDF0029AB7B /* HTMLFeedFinderTests.swift in Sources */, + 84FE13D420DC3DDF0029AB7B /* FeedFinderTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -285,7 +293,7 @@ /* Begin PBXTargetDependency section */ 84BAAE2C1C8E6B3B009F5239 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 84BAAE1E1C8E6B3B009F5239 /* RSFeedFinder */; + target = 84BAAE1E1C8E6B3B009F5239 /* FeedFinder */; targetProxy = 84BAAE2B1C8E6B3B009F5239 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -293,50 +301,57 @@ /* Begin XCBuildConfiguration section */ 84BAAE311C8E6B3B009F5239 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0D20242E7A00712EC3 /* RSFeedFinder_project_debug.xcconfig */; buildSettings = { + SWIFT_VERSION = 4.0; }; name = Debug; }; 84BAAE321C8E6B3B009F5239 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0B20242E7A00712EC3 /* RSFeedFinder_project_release.xcconfig */; + baseConfigurationReference = D511EF0B20242E7A00712EC3 /* FeedFinder_project_release.xcconfig */; buildSettings = { }; name = Release; }; 84BAAE341C8E6B3B009F5239 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0A20242E7A00712EC3 /* RSFeedFinder_target.xcconfig */; + baseConfigurationReference = D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */; buildSettings = { + INFOPLIST_FILE = FeedFinder/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinder; + SWIFT_VERSION = 4.0; }; name = Debug; }; 84BAAE351C8E6B3B009F5239 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0A20242E7A00712EC3 /* RSFeedFinder_target.xcconfig */; + baseConfigurationReference = D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */; buildSettings = { + INFOPLIST_FILE = FeedFinder/Info.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinder; }; name = Release; }; 84BAAE371C8E6B3B009F5239 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0C20242E7A00712EC3 /* RSFeedFinderTests_target.xcconfig */; + baseConfigurationReference = D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */; buildSettings = { + INFOPLIST_FILE = FeedFinderTests/Info.plist; }; name = Debug; }; 84BAAE381C8E6B3B009F5239 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0C20242E7A00712EC3 /* RSFeedFinderTests_target.xcconfig */; + baseConfigurationReference = D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */; buildSettings = { + INFOPLIST_FILE = FeedFinderTests/Info.plist; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 84BAAE191C8E6B3B009F5239 /* Build configuration list for PBXProject "RSFeedFinder" */ = { + 84BAAE191C8E6B3B009F5239 /* Build configuration list for PBXProject "FeedFinder" */ = { isa = XCConfigurationList; buildConfigurations = ( 84BAAE311C8E6B3B009F5239 /* Debug */, @@ -345,7 +360,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 84BAAE331C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "RSFeedFinder" */ = { + 84BAAE331C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinder" */ = { isa = XCConfigurationList; buildConfigurations = ( 84BAAE341C8E6B3B009F5239 /* Debug */, @@ -354,7 +369,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 84BAAE361C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "RSFeedFinderTests" */ = { + 84BAAE361C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinderTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 84BAAE371C8E6B3B009F5239 /* Debug */, diff --git a/Frameworks/FeedFinder/FeedFinder/FeedFinder.h b/Frameworks/FeedFinder/FeedFinder/FeedFinder.h index bea1e4af0..0e51c8f2d 100644 --- a/Frameworks/FeedFinder/FeedFinder/FeedFinder.h +++ b/Frameworks/FeedFinder/FeedFinder/FeedFinder.h @@ -1,6 +1,6 @@ // -// RSFeedFinder.h -// RSFeedFinder +// FeedFinder.h +// FeedFinder // // Created by Brent Simmons on 3/7/16. // Copyright © 2016 Ranchero Software, LLC. All rights reserved. @@ -8,13 +8,13 @@ #import -//! Project version number for RSFeedFinder. -FOUNDATION_EXPORT double RSFeedFinderVersionNumber; +//! Project version number for FeedFinder. +FOUNDATION_EXPORT double FeedFinderVersionNumber; -//! Project version string for RSFeedFinder. -FOUNDATION_EXPORT const unsigned char RSFeedFinderVersionString[]; +//! Project version string for FeedFinder. +FOUNDATION_EXPORT const unsigned char FeedFinderVersionString[]; -// In this header, you should import all the public headers of your framework using statements like #import +// In this header, you should import all the public headers of your framework using statements like #import /* Given a URL, find one or more feeds. diff --git a/Frameworks/FeedFinder/FeedFinder/FeedFinder.swift b/Frameworks/FeedFinder/FeedFinder/FeedFinder.swift index 6b40a9c46..332bc802b 100644 --- a/Frameworks/FeedFinder/FeedFinder/FeedFinder.swift +++ b/Frameworks/FeedFinder/FeedFinder/FeedFinder.swift @@ -1,6 +1,6 @@ // // FeedFinder.swift -// RSFeedFinder +// FeedFinder // // Created by Brent Simmons on 8/2/16. // Copyright © 2016 Ranchero Software, LLC. All rights reserved. diff --git a/Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift b/Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift index 8ea5f59bf..268f464b2 100644 --- a/Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift +++ b/Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift @@ -1,6 +1,6 @@ // // FeedSpecifier.swift -// RSFeedFinder +// FeedFinder // // Created by Brent Simmons on 8/7/16. // Copyright © 2016 Ranchero Software, LLC. All rights reserved. diff --git a/Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift b/Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift index fd3ad6ba5..7550ff53a 100644 --- a/Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift +++ b/Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift @@ -1,6 +1,6 @@ // // HTMLFeedFinder.swift -// RSFeedFinder +// FeedFinder // // Created by Brent Simmons on 8/7/16. // Copyright © 2016 Ranchero Software, LLC. All rights reserved. diff --git a/Frameworks/FeedFinder/FeedFinderTests/RSFeedFinderTests.m b/Frameworks/FeedFinder/FeedFinderTests/FeedFinderTests.m similarity index 86% rename from Frameworks/FeedFinder/FeedFinderTests/RSFeedFinderTests.m rename to Frameworks/FeedFinder/FeedFinderTests/FeedFinderTests.m index 9a0ae0bb5..7b4edc8b6 100644 --- a/Frameworks/FeedFinder/FeedFinderTests/RSFeedFinderTests.m +++ b/Frameworks/FeedFinder/FeedFinderTests/FeedFinderTests.m @@ -1,6 +1,6 @@ // -// RSFeedFinderTests.m -// RSFeedFinderTests +// FeedFinderTests.m +// FeedFinderTests // // Created by Brent Simmons on 3/7/16. // Copyright © 2016 Ranchero Software, LLC. All rights reserved. @@ -8,11 +8,11 @@ #import -@interface RSFeedFinderTests : XCTestCase +@interface FeedFinderTests : XCTestCase @end -@implementation RSFeedFinderTests +@implementation FeedFinderTests - (void)setUp { [super setUp]; diff --git a/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift b/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift index 212b03385..ed5c78013 100644 --- a/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift +++ b/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift @@ -1,13 +1,13 @@ // // HTMLFeedFinderTests.swift -// RSFeedFinder +// FeedFinder // // Created by Brent Simmons on 8/7/16. // Copyright © 2016 Ranchero Software, LLC. All rights reserved. // import XCTest -@testable import RSFeedFinder +@testable import FeedFinder import RSParser class HTMLFeedFinderTests: XCTestCase { diff --git a/Frameworks/FeedFinder/xcconfig/RSFeedFinderTests_target.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinderTests_target.xcconfig similarity index 63% rename from Frameworks/FeedFinder/xcconfig/RSFeedFinderTests_target.xcconfig rename to Frameworks/FeedFinder/xcconfig/FeedFinderTests_target.xcconfig index 6a9c5c16b..c759ef8c6 100644 --- a/Frameworks/FeedFinder/xcconfig/RSFeedFinderTests_target.xcconfig +++ b/Frameworks/FeedFinder/xcconfig/FeedFinderTests_target.xcconfig @@ -1,7 +1,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks -INFOPLIST_FILE = RSFeedFinderTests/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSFeedFinderTests +INFOPLIST_FILE = FeedFinderTests/Info.plist +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinderTests PRODUCT_NAME = $(TARGET_NAME) diff --git a/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_project.xcconfig similarity index 100% rename from Frameworks/FeedFinder/xcconfig/RSFeedFinder_project.xcconfig rename to Frameworks/FeedFinder/xcconfig/FeedFinder_project.xcconfig diff --git a/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_debug.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_project_debug.xcconfig similarity index 88% rename from Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_debug.xcconfig rename to Frameworks/FeedFinder/xcconfig/FeedFinder_project_debug.xcconfig index cc5fe82e8..4480287e9 100644 --- a/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_debug.xcconfig +++ b/Frameworks/FeedFinder/xcconfig/FeedFinder_project_debug.xcconfig @@ -1,4 +1,4 @@ -#include "./RSFeedFinder_project.xcconfig" +#include "./FeedFinder_project.xcconfig" DEBUG_INFORMATION_FORMAT = dwarf ENABLE_TESTABILITY = YES diff --git a/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_release.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_project_release.xcconfig similarity index 79% rename from Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_release.xcconfig rename to Frameworks/FeedFinder/xcconfig/FeedFinder_project_release.xcconfig index 1b3df8a4d..4f6878e2a 100644 --- a/Frameworks/FeedFinder/xcconfig/RSFeedFinder_project_release.xcconfig +++ b/Frameworks/FeedFinder/xcconfig/FeedFinder_project_release.xcconfig @@ -1,4 +1,4 @@ -#include "./RSFeedFinder_project.xcconfig" +#include "./FeedFinder_project.xcconfig" DEBUG_INFORMATION_FORMAT = dwarf-with-dsym ENABLE_NS_ASSERTIONS = NO diff --git a/Frameworks/FeedFinder/xcconfig/RSFeedFinder_target.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_target.xcconfig similarity index 77% rename from Frameworks/FeedFinder/xcconfig/RSFeedFinder_target.xcconfig rename to Frameworks/FeedFinder/xcconfig/FeedFinder_target.xcconfig index 51f45f1c3..2cbf5f4fc 100644 --- a/Frameworks/FeedFinder/xcconfig/RSFeedFinder_target.xcconfig +++ b/Frameworks/FeedFinder/xcconfig/FeedFinder_target.xcconfig @@ -7,8 +7,8 @@ DYLIB_INSTALL_NAME_BASE = @rpath LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/Frameworks DEFINES_MODULE = YES FRAMEWORK_VERSION = A -INFOPLIST_FILE = RSFeedFinder/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.RSFeedFinder +INFOPLIST_FILE = FeedFinder/Info.plist +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinder PRODUCT_NAME = $(TARGET_NAME) From caece76cd15f1ef3f2aada95e79d92ad56f41848 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Thu, 21 Jun 2018 13:23:53 -0700 Subject: [PATCH 05/40] Add RSCore submodule. Start SubmoduleCheatSheet.md. --- .gitmodules | 3 +++ Technotes/SubmoduleCheatSheet.md | 8 ++++++++ submodules/RSCore | 1 + 3 files changed, 12 insertions(+) create mode 100644 .gitmodules create mode 100644 Technotes/SubmoduleCheatSheet.md create mode 160000 submodules/RSCore diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..9635257ec --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "submodules/RSCore"] + path = submodules/RSCore + url = https://github.com/brentsimmons/RSCore diff --git a/Technotes/SubmoduleCheatSheet.md b/Technotes/SubmoduleCheatSheet.md new file mode 100644 index 000000000..2615a7c6f --- /dev/null +++ b/Technotes/SubmoduleCheatSheet.md @@ -0,0 +1,8 @@ +# Git Submodules + +Evergreen uses [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to include shared frameworks. At this writing (June 2018) they are DB5, RSCore, RSWeb, RSTree, and RSParser. + +To add a submodule: + + git submodule add https://github.com/username/path + diff --git a/submodules/RSCore b/submodules/RSCore new file mode 160000 index 000000000..43e3f0a07 --- /dev/null +++ b/submodules/RSCore @@ -0,0 +1 @@ +Subproject commit 43e3f0a07aed5d3ffa3bec341625e3d743d3f568 From 0a965d2e9522266e0ca06b2d977390aa53fe91a3 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Thu, 21 Jun 2018 13:25:10 -0700 Subject: [PATCH 06/40] Add DB5, RSParser, RSTree, and RSWeb submodules. --- .gitmodules | 12 ++++++++++++ submodules/DB5 | 1 + submodules/RSParser | 1 + submodules/RSTree | 1 + submodules/RSWeb | 1 + 5 files changed, 16 insertions(+) create mode 160000 submodules/DB5 create mode 160000 submodules/RSParser create mode 160000 submodules/RSTree create mode 160000 submodules/RSWeb diff --git a/.gitmodules b/.gitmodules index 9635257ec..ae21dac1d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,15 @@ [submodule "submodules/RSCore"] path = submodules/RSCore url = https://github.com/brentsimmons/RSCore +[submodule "submodules/DB5"] + path = submodules/DB5 + url = https://github.com/brentsimmons/DB5 +[submodule "submodules/RSWeb"] + path = submodules/RSWeb + url = https://github.com/brentsimmons/RSWeb +[submodule "submodules/RSParser"] + path = submodules/RSParser + url = https://github.com/brentsimmons/RSParser +[submodule "submodules/RSTree"] + path = submodules/RSTree + url = https://github.com/brentsimmons/RSTree diff --git a/submodules/DB5 b/submodules/DB5 new file mode 160000 index 000000000..6b32b49be --- /dev/null +++ b/submodules/DB5 @@ -0,0 +1 @@ +Subproject commit 6b32b49bed78535ae0e608a23edf04df5a9a0c70 diff --git a/submodules/RSParser b/submodules/RSParser new file mode 160000 index 000000000..677aee859 --- /dev/null +++ b/submodules/RSParser @@ -0,0 +1 @@ +Subproject commit 677aee8591ebafc21bc77b619b5a701c203b0165 diff --git a/submodules/RSTree b/submodules/RSTree new file mode 160000 index 000000000..5f919d00b --- /dev/null +++ b/submodules/RSTree @@ -0,0 +1 @@ +Subproject commit 5f919d00b81365c6fefac52b75dc3442d055ca76 diff --git a/submodules/RSWeb b/submodules/RSWeb new file mode 160000 index 000000000..d38736115 --- /dev/null +++ b/submodules/RSWeb @@ -0,0 +1 @@ +Subproject commit d3873611520499f47bbf94e9fe76d3860ec94191 From 0efd637db8087338d00a0ac34b7ff9ee931c585c Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Thu, 21 Jun 2018 13:26:37 -0700 Subject: [PATCH 07/40] Add to SubmoduleCheatSheet. --- Technotes/SubmoduleCheatSheet.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Technotes/SubmoduleCheatSheet.md b/Technotes/SubmoduleCheatSheet.md index 2615a7c6f..fc18d4962 100644 --- a/Technotes/SubmoduleCheatSheet.md +++ b/Technotes/SubmoduleCheatSheet.md @@ -6,3 +6,8 @@ To add a submodule: git submodule add https://github.com/username/path +(It’s unlikely you’ll need to do that. Adding a submodule is done super-rarely, if ever, and it’s Brent’s call.) + +To update a submodule — to get the latest changes: + + TBD I surely wish I knew how From 3909e7d41f107a19b8fea56e5de339519595892a Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Fri, 22 Jun 2018 13:13:49 -0700 Subject: [PATCH 08/40] Add submodule xcodeprojs to workspace. --- .gitmodules | 3 + Evergreen.xcodeproj/project.pbxproj | 467 ++++++++++++++++++++++++---- submodules/RSDatabase | 1 + 3 files changed, 412 insertions(+), 59 deletions(-) create mode 160000 submodules/RSDatabase diff --git a/.gitmodules b/.gitmodules index ae21dac1d..5010488b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "submodules/RSTree"] path = submodules/RSTree url = https://github.com/brentsimmons/RSTree +[submodule "submodules/RSDatabase"] + path = submodules/RSDatabase + url = https://github.com/brentsimmons/RSDatabase diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index d020f9242..7a680a7bf 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -109,8 +109,6 @@ 84AD1EAA2031617300BC20B7 /* FolderPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EA92031617300BC20B7 /* FolderPasteboardWriter.swift */; }; 84AD1EBA2031649C00BC20B7 /* SmartFeedPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EB92031649C00BC20B7 /* SmartFeedPasteboardWriter.swift */; }; 84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AD1EBB2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift */; }; - 84B06FE91ED3803A00F0B54B /* RSFeedFinder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */; }; - 84B06FEA1ED3803A00F0B54B /* RSFeedFinder.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84B7178C201E66580091657D /* SidebarViewController+ContextualMenus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7178B201E66580091657D /* SidebarViewController+ContextualMenus.swift */; }; 84B99C671FAE35E600ECDEDB /* FeedListTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C661FAE35E600ECDEDB /* FeedListTreeControllerDelegate.swift */; }; 84B99C691FAE36B800ECDEDB /* FeedListFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C681FAE36B800ECDEDB /* FeedListFolder.swift */; }; @@ -121,6 +119,18 @@ 84BBB12D20142A4700F054F5 /* Inspector.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84BBB12B20142A4700F054F5 /* Inspector.storyboard */; }; 84BBB12E20142A4700F054F5 /* InspectorWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BBB12C20142A4700F054F5 /* InspectorWindowController.swift */; }; 84C12A151FF5B0080009A267 /* FeedList.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84C12A141FF5B0080009A267 /* FeedList.storyboard */; }; + 84C37FA520DD8D8400CA8CF5 /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F8120DD8CF200CA8CF5 /* RSCore.framework */; }; + 84C37FA620DD8D8400CA8CF5 /* RSCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F8120DD8CF200CA8CF5 /* RSCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84C37FA920DD8D9000CA8CF5 /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F9F20DD8D0500CA8CF5 /* RSWeb.framework */; }; + 84C37FAA20DD8D9000CA8CF5 /* RSWeb.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F9F20DD8D0500CA8CF5 /* RSWeb.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84C37FAD20DD8D9900CA8CF5 /* RSTree.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F9520DD8CFE00CA8CF5 /* RSTree.framework */; }; + 84C37FAE20DD8D9900CA8CF5 /* RSTree.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F9520DD8CFE00CA8CF5 /* RSTree.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84C37FB120DD8DA100CA8CF5 /* DB5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F2820DD8CCE00CA8CF5 /* DB5.framework */; }; + 84C37FB220DD8DA100CA8CF5 /* DB5.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F2820DD8CCE00CA8CF5 /* DB5.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84C37FB520DD8DBB00CA8CF5 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F8C20DD8CF800CA8CF5 /* RSParser.framework */; }; + 84C37FB620DD8DBB00CA8CF5 /* RSParser.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37F8C20DD8CF800CA8CF5 /* RSParser.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 84C37FC520DD8E1D00CA8CF5 /* RSDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37FC020DD8E0C00CA8CF5 /* RSDatabase.framework */; }; + 84C37FC620DD8E1D00CA8CF5 /* RSDatabase.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84C37FC020DD8E0C00CA8CF5 /* RSDatabase.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84CC88181FE59CBF00644329 /* SmartFeedsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CC88171FE59CBF00644329 /* SmartFeedsController.swift */; }; 84D52E951FE588BB00D14F5B /* DetailStatusBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84D52E941FE588BB00D14F5B /* DetailStatusBarView.swift */; }; 84D5BA20201E8FB6009092BD /* SidebarGearMenuDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84D5BA1F201E8FB6009092BD /* SidebarGearMenuDelegate.swift */; }; @@ -254,27 +264,6 @@ remoteGlobalIDString = 849C645F1ED37A5D003D8FC0; remoteInfo = Evergreen; }; - 84B06FE51ED3803200F0B54B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 84BAAE1F1C8E6B3B009F5239; - remoteInfo = RSFeedFinder; - }; - 84B06FE71ED3803200F0B54B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 84BAAE291C8E6B3B009F5239; - remoteInfo = RSFeedFinderTests; - }; - 84B06FEB1ED3803A00F0B54B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 84BAAE1E1C8E6B3B009F5239; - remoteInfo = RSFeedFinder; - }; 84BB4B671F1174D400858766 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 84BB4B611F1174D400858766 /* Data.xcodeproj */; @@ -296,6 +285,153 @@ remoteGlobalIDString = 844BEE5A1F0AB3C8004AB7CD; remoteInfo = Data; }; + 84C37F2720DD8CCE00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84F22BD11B52DC2E000060CE; + remoteInfo = DB5; + }; + 84C37F2920DD8CCE00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84F22BDB1B52DC2E000060CE; + remoteInfo = DB5Tests; + }; + 84C37F8020DD8CF200CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84CFF4F41AC3C69700CEA6C8; + remoteInfo = RSCore; + }; + 84C37F8220DD8CF200CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84CFF4FF1AC3C69700CEA6C8; + remoteInfo = RSCoreTests; + }; + 84C37F8420DD8CF200CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 842DD7BC1E14993900E061EB; + remoteInfo = RSCoreiOS; + }; + 84C37F8B20DD8CF800CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F8620DD8CF800CA8CF5 /* RSParser.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84FF5F841EFA285800C15A01; + remoteInfo = RSParser; + }; + 84C37F8D20DD8CF800CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F8620DD8CF800CA8CF5 /* RSParser.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84FF5F8D1EFA285800C15A01; + remoteInfo = RSParserTests; + }; + 84C37F9420DD8CFE00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F8F20DD8CFD00CA8CF5 /* RSTree.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 842A0BE11CFCB9BC00BF746C; + remoteInfo = RSTree; + }; + 84C37F9620DD8CFE00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F8F20DD8CFD00CA8CF5 /* RSTree.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 842A0BEB1CFCB9BC00BF746C; + remoteInfo = RSTreeTests; + }; + 84C37F9E20DD8D0500CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 849C08B61E0CAC85006B03FA; + remoteInfo = RSWeb; + }; + 84C37FA020DD8D0500CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 849C08BF1E0CAC86006B03FA; + remoteInfo = RSWebTests; + }; + 84C37FA220DD8D0500CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 849C08D51E0CACA3006B03FA; + remoteInfo = RSWebiOS; + }; + 84C37FA720DD8D8400CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 84CFF4F31AC3C69700CEA6C8; + remoteInfo = RSCore; + }; + 84C37FAB20DD8D9000CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 849C08B51E0CAC85006B03FA; + remoteInfo = RSWeb; + }; + 84C37FAF20DD8D9900CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F8F20DD8CFD00CA8CF5 /* RSTree.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 842A0BE01CFCB9BC00BF746C; + remoteInfo = RSTree; + }; + 84C37FB320DD8DA100CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 84F22BD01B52DC2E000060CE; + remoteInfo = DB5; + }; + 84C37FB720DD8DBB00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37F8620DD8CF800CA8CF5 /* RSParser.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 84FF5F831EFA285800C15A01; + remoteInfo = RSParser; + }; + 84C37FBF20DD8E0C00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84F22C551B52E0D9000060CE; + remoteInfo = RSDatabase; + }; + 84C37FC120DD8E0C00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 84F22C5F1B52E0D9000060CE; + remoteInfo = RSDatabaseTests; + }; + 84C37FC320DD8E0C00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8400ABF71E0CFBD800AA7C57; + remoteInfo = RSDatabaseiOS; + }; + 84C37FC720DD8E1D00CA8CF5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 84F22C541B52E0D9000060CE; + remoteInfo = RSDatabase; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -305,10 +441,15 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 84C37FAA20DD8D9000CA8CF5 /* RSWeb.framework in Embed Frameworks */, 84BB4B781F11753300858766 /* Data.framework in Embed Frameworks */, + 84C37FC620DD8E1D00CA8CF5 /* RSDatabase.framework in Embed Frameworks */, + 84C37FAE20DD8D9900CA8CF5 /* RSTree.framework in Embed Frameworks */, 84FB9A301EDCD6C4003D53B9 /* Sparkle.framework in Embed Frameworks */, + 84C37FB220DD8DA100CA8CF5 /* DB5.framework in Embed Frameworks */, + 84C37FB620DD8DBB00CA8CF5 /* RSParser.framework in Embed Frameworks */, 846E77421F6EF6A100A165E2 /* Database.framework in Embed Frameworks */, - 84B06FEA1ED3803A00F0B54B /* RSFeedFinder.framework in Embed Frameworks */, + 84C37FA620DD8D8400CA8CF5 /* RSCore.framework in Embed Frameworks */, 846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -457,7 +598,6 @@ 84AD1EA92031617300BC20B7 /* FolderPasteboardWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderPasteboardWriter.swift; sourceTree = ""; }; 84AD1EB92031649C00BC20B7 /* SmartFeedPasteboardWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartFeedPasteboardWriter.swift; sourceTree = ""; }; 84AD1EBB2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarOutlineDataSource.swift; sourceTree = ""; }; - 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSFeedFinder.xcodeproj; path = Frameworks/RSFeedFinder/RSFeedFinder.xcodeproj; sourceTree = ""; }; 84B7178B201E66580091657D /* SidebarViewController+ContextualMenus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SidebarViewController+ContextualMenus.swift"; sourceTree = ""; }; 84B99C661FAE35E600ECDEDB /* FeedListTreeControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListTreeControllerDelegate.swift; sourceTree = ""; }; 84B99C681FAE36B800ECDEDB /* FeedListFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListFolder.swift; sourceTree = ""; }; @@ -467,6 +607,12 @@ 84BBB12B20142A4700F054F5 /* Inspector.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Inspector.storyboard; sourceTree = ""; }; 84BBB12C20142A4700F054F5 /* InspectorWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InspectorWindowController.swift; sourceTree = ""; }; 84C12A141FF5B0080009A267 /* FeedList.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FeedList.storyboard; sourceTree = ""; }; + 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = DB5.xcodeproj; path = submodules/DB5/DB5.xcodeproj; sourceTree = ""; }; + 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = submodules/RSCore/RSCore.xcodeproj; sourceTree = ""; }; + 84C37F8620DD8CF800CA8CF5 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = submodules/RSParser/RSParser.xcodeproj; sourceTree = ""; }; + 84C37F8F20DD8CFD00CA8CF5 /* RSTree.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSTree.xcodeproj; path = submodules/RSTree/RSTree.xcodeproj; sourceTree = ""; }; + 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSWeb.xcodeproj; path = submodules/RSWeb/RSWeb.xcodeproj; sourceTree = ""; }; + 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSDatabase.xcodeproj; path = submodules/RSDatabase/RSDatabase.xcodeproj; sourceTree = ""; }; 84CBDDAE1FD3674C005A61AA /* Technotes */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Technotes; sourceTree = ""; }; 84CC08051FF5D2E000C0C0ED /* FeedListSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListSplitViewController.swift; sourceTree = ""; }; 84CC88171FE59CBF00644329 /* SmartFeedsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartFeedsController.swift; sourceTree = ""; }; @@ -554,10 +700,15 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 84C37FA920DD8D9000CA8CF5 /* RSWeb.framework in Frameworks */, 84BB4B771F11753300858766 /* Data.framework in Frameworks */, + 84C37FC520DD8E1D00CA8CF5 /* RSDatabase.framework in Frameworks */, + 84C37FAD20DD8D9900CA8CF5 /* RSTree.framework in Frameworks */, 846E77411F6EF6A100A165E2 /* Database.framework in Frameworks */, - 84B06FE91ED3803A00F0B54B /* RSFeedFinder.framework in Frameworks */, + 84C37FB120DD8DA100CA8CF5 /* DB5.framework in Frameworks */, + 84C37FB520DD8DBB00CA8CF5 /* RSParser.framework in Frameworks */, 846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */, + 84C37FA520DD8D8400CA8CF5 /* RSCore.framework in Frameworks */, 84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -939,9 +1090,14 @@ D5907CDA2002F084005947E5 /* xcconfig */, 849C64611ED37A5D003D8FC0 /* Products */, 846E77301F6EF5D600A165E2 /* Account.xcodeproj */, - 846E77161F6EF5D000A165E2 /* Database.xcodeproj */, 84BB4B611F1174D400858766 /* Data.xcodeproj */, - 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */, + 846E77161F6EF5D000A165E2 /* Database.xcodeproj */, + 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */, + 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */, + 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */, + 84C37F8620DD8CF800CA8CF5 /* RSParser.xcodeproj */, + 84C37F8F20DD8CFD00CA8CF5 /* RSTree.xcodeproj */, + 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */, ); sourceTree = ""; }; @@ -986,15 +1142,6 @@ path = Evergreen/Dinosaurs; sourceTree = ""; }; - 84B06FE11ED3803200F0B54B /* Products */ = { - isa = PBXGroup; - children = ( - 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */, - 84B06FE81ED3803200F0B54B /* RSFeedFinderTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; 84BB4B621F1174D400858766 /* Products */ = { isa = PBXGroup; children = ( @@ -1018,6 +1165,63 @@ path = Evergreen/Inspector; sourceTree = ""; }; + 84C37F2320DD8CCD00CA8CF5 /* Products */ = { + isa = PBXGroup; + children = ( + 84C37F2820DD8CCE00CA8CF5 /* DB5.framework */, + 84C37F2A20DD8CCE00CA8CF5 /* DB5Tests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 84C37F7B20DD8CF200CA8CF5 /* Products */ = { + isa = PBXGroup; + children = ( + 84C37F8120DD8CF200CA8CF5 /* RSCore.framework */, + 84C37F8320DD8CF200CA8CF5 /* RSCoreTests.xctest */, + 84C37F8520DD8CF200CA8CF5 /* RSCore.framework */, + ); + name = Products; + sourceTree = ""; + }; + 84C37F8720DD8CF800CA8CF5 /* Products */ = { + isa = PBXGroup; + children = ( + 84C37F8C20DD8CF800CA8CF5 /* RSParser.framework */, + 84C37F8E20DD8CF800CA8CF5 /* RSParserTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 84C37F9020DD8CFD00CA8CF5 /* Products */ = { + isa = PBXGroup; + children = ( + 84C37F9520DD8CFE00CA8CF5 /* RSTree.framework */, + 84C37F9720DD8CFE00CA8CF5 /* RSTreeTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 84C37F9920DD8D0400CA8CF5 /* Products */ = { + isa = PBXGroup; + children = ( + 84C37F9F20DD8D0500CA8CF5 /* RSWeb.framework */, + 84C37FA120DD8D0500CA8CF5 /* RSWebTests.xctest */, + 84C37FA320DD8D0500CA8CF5 /* RSWeb.framework */, + ); + name = Products; + sourceTree = ""; + }; + 84C37FBA20DD8E0C00CA8CF5 /* Products */ = { + isa = PBXGroup; + children = ( + 84C37FC020DD8E0C00CA8CF5 /* RSDatabase.framework */, + 84C37FC220DD8E0C00CA8CF5 /* RSDatabaseTests.xctest */, + 84C37FC420DD8E0C00CA8CF5 /* RSDatabase.framework */, + ); + name = Products; + sourceTree = ""; + }; 84DAEE201F86CAE00058304B /* Importers */ = { isa = PBXGroup; children = ( @@ -1213,10 +1417,15 @@ buildRules = ( ); dependencies = ( - 84B06FEC1ED3803A00F0B54B /* PBXTargetDependency */, 84BB4B7A1F11753300858766 /* PBXTargetDependency */, 846E77401F6EF67A00A165E2 /* PBXTargetDependency */, 846E77441F6EF6A100A165E2 /* PBXTargetDependency */, + 84C37FA820DD8D8400CA8CF5 /* PBXTargetDependency */, + 84C37FAC20DD8D9000CA8CF5 /* PBXTargetDependency */, + 84C37FB020DD8D9900CA8CF5 /* PBXTargetDependency */, + 84C37FB420DD8DA100CA8CF5 /* PBXTargetDependency */, + 84C37FB820DD8DBB00CA8CF5 /* PBXTargetDependency */, + 84C37FC820DD8E1D00CA8CF5 /* PBXTargetDependency */, ); name = Evergreen; productName = Evergreen; @@ -1307,8 +1516,28 @@ ProjectRef = 846E77161F6EF5D000A165E2 /* Database.xcodeproj */; }, { - ProductGroup = 84B06FE11ED3803200F0B54B /* Products */; - ProjectRef = 84B06FE01ED3803200F0B54B /* RSFeedFinder.xcodeproj */; + ProductGroup = 84C37F2320DD8CCD00CA8CF5 /* Products */; + ProjectRef = 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */; + }, + { + ProductGroup = 84C37F7B20DD8CF200CA8CF5 /* Products */; + ProjectRef = 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */; + }, + { + ProductGroup = 84C37FBA20DD8E0C00CA8CF5 /* Products */; + ProjectRef = 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */; + }, + { + ProductGroup = 84C37F8720DD8CF800CA8CF5 /* Products */; + ProjectRef = 84C37F8620DD8CF800CA8CF5 /* RSParser.xcodeproj */; + }, + { + ProductGroup = 84C37F9020DD8CFD00CA8CF5 /* Products */; + ProjectRef = 84C37F8F20DD8CFD00CA8CF5 /* RSTree.xcodeproj */; + }, + { + ProductGroup = 84C37F9920DD8D0400CA8CF5 /* Products */; + ProjectRef = 84C37F9820DD8D0400CA8CF5 /* RSWeb.xcodeproj */; }, ); projectRoot = ""; @@ -1351,20 +1580,6 @@ remoteRef = 846E773B1F6EF5D700A165E2 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 84B06FE61ED3803200F0B54B /* RSFeedFinder.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = RSFeedFinder.framework; - remoteRef = 84B06FE51ED3803200F0B54B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 84B06FE81ED3803200F0B54B /* RSFeedFinderTests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = RSFeedFinderTests.xctest; - remoteRef = 84B06FE71ED3803200F0B54B /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 84BB4B681F1174D400858766 /* Data.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -1379,6 +1594,111 @@ remoteRef = 84BB4B691F1174D400858766 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 84C37F2820DD8CCE00CA8CF5 /* DB5.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = DB5.framework; + remoteRef = 84C37F2720DD8CCE00CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F2A20DD8CCE00CA8CF5 /* DB5Tests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = DB5Tests.xctest; + remoteRef = 84C37F2920DD8CCE00CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F8120DD8CF200CA8CF5 /* RSCore.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSCore.framework; + remoteRef = 84C37F8020DD8CF200CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F8320DD8CF200CA8CF5 /* RSCoreTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSCoreTests.xctest; + remoteRef = 84C37F8220DD8CF200CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F8520DD8CF200CA8CF5 /* RSCore.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSCore.framework; + remoteRef = 84C37F8420DD8CF200CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F8C20DD8CF800CA8CF5 /* RSParser.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSParser.framework; + remoteRef = 84C37F8B20DD8CF800CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F8E20DD8CF800CA8CF5 /* RSParserTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSParserTests.xctest; + remoteRef = 84C37F8D20DD8CF800CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F9520DD8CFE00CA8CF5 /* RSTree.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSTree.framework; + remoteRef = 84C37F9420DD8CFE00CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F9720DD8CFE00CA8CF5 /* RSTreeTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSTreeTests.xctest; + remoteRef = 84C37F9620DD8CFE00CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37F9F20DD8D0500CA8CF5 /* RSWeb.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSWeb.framework; + remoteRef = 84C37F9E20DD8D0500CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37FA120DD8D0500CA8CF5 /* RSWebTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSWebTests.xctest; + remoteRef = 84C37FA020DD8D0500CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37FA320DD8D0500CA8CF5 /* RSWeb.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSWeb.framework; + remoteRef = 84C37FA220DD8D0500CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37FC020DD8E0C00CA8CF5 /* RSDatabase.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSDatabase.framework; + remoteRef = 84C37FBF20DD8E0C00CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37FC220DD8E0C00CA8CF5 /* RSDatabaseTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = RSDatabaseTests.xctest; + remoteRef = 84C37FC120DD8E0C00CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84C37FC420DD8E0C00CA8CF5 /* RSDatabase.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = RSDatabase.framework; + remoteRef = 84C37FC320DD8E0C00CA8CF5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ /* Begin PBXResourcesBuildPhase section */ @@ -1655,16 +1975,41 @@ target = 849C645F1ED37A5D003D8FC0 /* Evergreen */; targetProxy = 849C64721ED37A5D003D8FC0 /* PBXContainerItemProxy */; }; - 84B06FEC1ED3803A00F0B54B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = RSFeedFinder; - targetProxy = 84B06FEB1ED3803A00F0B54B /* PBXContainerItemProxy */; - }; 84BB4B7A1F11753300858766 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Data; targetProxy = 84BB4B791F11753300858766 /* PBXContainerItemProxy */; }; + 84C37FA820DD8D8400CA8CF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RSCore; + targetProxy = 84C37FA720DD8D8400CA8CF5 /* PBXContainerItemProxy */; + }; + 84C37FAC20DD8D9000CA8CF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RSWeb; + targetProxy = 84C37FAB20DD8D9000CA8CF5 /* PBXContainerItemProxy */; + }; + 84C37FB020DD8D9900CA8CF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RSTree; + targetProxy = 84C37FAF20DD8D9900CA8CF5 /* PBXContainerItemProxy */; + }; + 84C37FB420DD8DA100CA8CF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = DB5; + targetProxy = 84C37FB320DD8DA100CA8CF5 /* PBXContainerItemProxy */; + }; + 84C37FB820DD8DBB00CA8CF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RSParser; + targetProxy = 84C37FB720DD8DBB00CA8CF5 /* PBXContainerItemProxy */; + }; + 84C37FC820DD8E1D00CA8CF5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = RSDatabase; + targetProxy = 84C37FC720DD8E1D00CA8CF5 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -2163,6 +2508,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; }; name = Debug; }; @@ -2170,6 +2517,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; }; name = Release; }; diff --git a/submodules/RSDatabase b/submodules/RSDatabase new file mode 160000 index 000000000..4e7358074 --- /dev/null +++ b/submodules/RSDatabase @@ -0,0 +1 @@ +Subproject commit 4e7358074ed3c358ebfe3741a38f43e020665694 From 74e07521eab9e98a20a7064985c38c07df4d9645 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 23 Jun 2018 11:35:55 -0700 Subject: [PATCH 09/40] Build still broken. De-framework-ized FeedFinder. --- Evergreen.xcodeproj/project.pbxproj | 27 + .../FeedFinder/FeedFinder.swift | 0 .../FeedFinder/FeedSpecifier.swift | 0 .../FeedFinder/HTMLFeedFinder.swift | 0 .../FeedFinder.xcodeproj/project.pbxproj | 384 ----- .../contents.xcworkspacedata | 7 - Frameworks/FeedFinder/FeedFinder/FeedFinder.h | 29 - Frameworks/FeedFinder/FeedFinder/Info.plist | 28 - .../FeedFinderTests/FeedFinderTests.m | 39 - .../FeedFinderTests/HTMLFeedFinderTests.swift | 66 - .../FeedFinder/FeedFinderTests/Info.plist | 24 - .../Resources/DaringFireball.html | 1463 ----------------- .../FeedFinderTests/Resources/furbo.html | 372 ----- .../FeedFinderTests/Resources/indiestack.html | 715 -------- .../Resources/inessential.html | 172 -- .../FeedFinderTests/Resources/sixcolors.html | 1102 ------------- .../xcconfig/FeedFinderTests_target.xcconfig | 18 - .../xcconfig/FeedFinder_project.xcconfig | 58 - .../FeedFinder_project_debug.xcconfig | 15 - .../FeedFinder_project_release.xcconfig | 9 - .../xcconfig/FeedFinder_target.xcconfig | 14 - Technotes/SubmoduleCheatSheet.md | 4 +- 22 files changed, 30 insertions(+), 4516 deletions(-) rename {Frameworks/FeedFinder => Evergreen}/FeedFinder/FeedFinder.swift (100%) rename {Frameworks/FeedFinder => Evergreen}/FeedFinder/FeedSpecifier.swift (100%) rename {Frameworks/FeedFinder => Evergreen}/FeedFinder/HTMLFeedFinder.swift (100%) delete mode 100644 Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj delete mode 100644 Frameworks/FeedFinder/FeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 Frameworks/FeedFinder/FeedFinder/FeedFinder.h delete mode 100644 Frameworks/FeedFinder/FeedFinder/Info.plist delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/FeedFinderTests.m delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/Info.plist delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/Resources/DaringFireball.html delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/Resources/furbo.html delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/Resources/indiestack.html delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/Resources/inessential.html delete mode 100644 Frameworks/FeedFinder/FeedFinderTests/Resources/sixcolors.html delete mode 100644 Frameworks/FeedFinder/xcconfig/FeedFinderTests_target.xcconfig delete mode 100644 Frameworks/FeedFinder/xcconfig/FeedFinder_project.xcconfig delete mode 100644 Frameworks/FeedFinder/xcconfig/FeedFinder_project_debug.xcconfig delete mode 100644 Frameworks/FeedFinder/xcconfig/FeedFinder_project_release.xcconfig delete mode 100644 Frameworks/FeedFinder/xcconfig/FeedFinder_target.xcconfig diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 7a680a7bf..bb66c1263 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -150,6 +150,12 @@ 84F2D5371FC22FCC00998D64 /* PseudoFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F2D5351FC22FCB00998D64 /* PseudoFeed.swift */; }; 84F2D5381FC22FCC00998D64 /* TodayFeedDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F2D5361FC22FCB00998D64 /* TodayFeedDelegate.swift */; }; 84F2D53A1FC2308B00998D64 /* UnreadFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F2D5391FC2308B00998D64 /* UnreadFeed.swift */; }; + 84F3EE1620DEC97E003FADEB /* FeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F3EE0620DEC97E003FADEB /* FeedFinder.swift */; }; + 84F3EE1720DEC97E003FADEB /* FeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F3EE0620DEC97E003FADEB /* FeedFinder.swift */; }; + 84F3EE1820DEC97E003FADEB /* FeedSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F3EE0720DEC97E003FADEB /* FeedSpecifier.swift */; }; + 84F3EE1920DEC97E003FADEB /* FeedSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F3EE0720DEC97E003FADEB /* FeedSpecifier.swift */; }; + 84F3EE1A20DEC97E003FADEB /* HTMLFeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F3EE0820DEC97E003FADEB /* HTMLFeedFinder.swift */; }; + 84F3EE1B20DEC97E003FADEB /* HTMLFeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F3EE0820DEC97E003FADEB /* HTMLFeedFinder.swift */; }; 84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; }; 84FB9A301EDCD6C4003D53B9 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */; }; @@ -634,6 +640,9 @@ 84F2D5351FC22FCB00998D64 /* PseudoFeed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PseudoFeed.swift; sourceTree = ""; }; 84F2D5361FC22FCB00998D64 /* TodayFeedDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TodayFeedDelegate.swift; sourceTree = ""; }; 84F2D5391FC2308B00998D64 /* UnreadFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadFeed.swift; sourceTree = ""; }; + 84F3EE0620DEC97E003FADEB /* FeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedFinder.swift; sourceTree = ""; }; + 84F3EE0720DEC97E003FADEB /* FeedSpecifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedSpecifier.swift; sourceTree = ""; }; + 84F3EE0820DEC97E003FADEB /* HTMLFeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLFeedFinder.swift; sourceTree = ""; }; 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Frameworks/Vendor/Sparkle.framework; sourceTree = SOURCE_ROOT; }; 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaviconURLFinder.swift; sourceTree = ""; }; D553737C20186C1F006D8857 /* Article+Scriptability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Article+Scriptability.swift"; sourceTree = ""; }; @@ -1075,6 +1084,7 @@ 8444C9011FED81880051386C /* Exporters */, 84F2D5341FC22FCB00998D64 /* SmartFeeds */, 849A97561ED9EB0D007D329B /* Data */, + 84F3EE0420DEC97E003FADEB /* FeedFinder */, 8426119C1FCB6ED40086A189 /* HTMLMetadata */, 848F6AE31FC29CFA002D422E /* Favicons */, 845213211FCA5B10003B6E93 /* Images */, @@ -1266,6 +1276,17 @@ path = Evergreen/SmartFeeds; sourceTree = ""; }; + 84F3EE0420DEC97E003FADEB /* FeedFinder */ = { + isa = PBXGroup; + children = ( + 84F3EE0620DEC97E003FADEB /* FeedFinder.swift */, + 84F3EE0720DEC97E003FADEB /* FeedSpecifier.swift */, + 84F3EE0820DEC97E003FADEB /* HTMLFeedFinder.swift */, + ); + name = FeedFinder; + path = Evergreen/FeedFinder; + sourceTree = ""; + }; 84FB9A2C1EDCD6A4003D53B9 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -1786,6 +1807,9 @@ 840D61832029031C009BC708 /* DetailViewController.swift in Sources */, 840D61812029031C009BC708 /* MasterViewController.swift in Sources */, 840D617F2029031C009BC708 /* AppDelegate.swift in Sources */, + 84F3EE1720DEC97E003FADEB /* FeedFinder.swift in Sources */, + 84F3EE1B20DEC97E003FADEB /* HTMLFeedFinder.swift in Sources */, + 84F3EE1920DEC97E003FADEB /* FeedSpecifier.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1866,8 +1890,10 @@ 84F204CE1FAACB660076E152 /* FeedListViewController.swift in Sources */, 84AD1EBC2032AF5C00BC20B7 /* SidebarOutlineDataSource.swift in Sources */, 845A29241FC9255E007B49E3 /* SidebarCellAppearance.swift in Sources */, + 84F3EE1620DEC97E003FADEB /* FeedFinder.swift in Sources */, 845EE7B11FC2366500854A1F /* StarredFeedDelegate.swift in Sources */, 848F6AE51FC29CFB002D422E /* FaviconDownloader.swift in Sources */, + 84F3EE1820DEC97E003FADEB /* FeedSpecifier.swift in Sources */, 849EE72120391F560082A1EA /* MainWindowSharingServicePickerDelegate.swift in Sources */, 849A97981ED9EFAA007D329B /* Node-Extensions.swift in Sources */, 849EE70F203919360082A1EA /* AppImages.swift in Sources */, @@ -1889,6 +1915,7 @@ 841ABA6020145EC100980E11 /* BuiltinSmartFeedInspectorViewController.swift in Sources */, D5E4CC54202C1361009B4FFC /* AppDelegate+Scriptability.swift in Sources */, D5F4EDB5200744A700B9E363 /* ScriptingObject.swift in Sources */, + 84F3EE1A20DEC97E003FADEB /* HTMLFeedFinder.swift in Sources */, D5F4EDB920074D7C00B9E363 /* Folder+Scriptability.swift in Sources */, 842611A01FCB72600086A189 /* FeaturedImageDownloader.swift in Sources */, 849A97781ED9EC04007D329B /* TimelineCellLayout.swift in Sources */, diff --git a/Frameworks/FeedFinder/FeedFinder/FeedFinder.swift b/Evergreen/FeedFinder/FeedFinder.swift similarity index 100% rename from Frameworks/FeedFinder/FeedFinder/FeedFinder.swift rename to Evergreen/FeedFinder/FeedFinder.swift diff --git a/Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift b/Evergreen/FeedFinder/FeedSpecifier.swift similarity index 100% rename from Frameworks/FeedFinder/FeedFinder/FeedSpecifier.swift rename to Evergreen/FeedFinder/FeedSpecifier.swift diff --git a/Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift b/Evergreen/FeedFinder/HTMLFeedFinder.swift similarity index 100% rename from Frameworks/FeedFinder/FeedFinder/HTMLFeedFinder.swift rename to Evergreen/FeedFinder/HTMLFeedFinder.swift diff --git a/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj b/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj deleted file mode 100644 index 30812b880..000000000 --- a/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.pbxproj +++ /dev/null @@ -1,384 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 84B06FEF1ED3808F00F0B54B /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FEE1ED3808F00F0B54B /* RSWeb.framework */; }; - 84B06FF31ED3812600F0B54B /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B06FF21ED3812600F0B54B /* RSCore.framework */; }; - 84BAAE2A1C8E6B3B009F5239 /* FeedFinder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */; }; - 84F466571F03523100225386 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F466561F03523100225386 /* RSParser.framework */; }; - 84FE13C220DC3D960029AB7B /* FeedFinder.h in Headers */ = {isa = PBXBuildFile; fileRef = 84FE13C120DC3D960029AB7B /* FeedFinder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 84FE13C420DC3DA70029AB7B /* FeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13C320DC3DA70029AB7B /* FeedFinder.swift */; }; - 84FE13C620DC3DAE0029AB7B /* FeedSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13C520DC3DAE0029AB7B /* FeedSpecifier.swift */; }; - 84FE13C820DC3DB50029AB7B /* HTMLFeedFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13C720DC3DB50029AB7B /* HTMLFeedFinder.swift */; }; - 84FE13D420DC3DDF0029AB7B /* FeedFinderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13CB20DC3DDF0029AB7B /* FeedFinderTests.m */; }; - 84FE13D520DC3DDF0029AB7B /* indiestack.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13CD20DC3DDF0029AB7B /* indiestack.html */; }; - 84FE13D620DC3DDF0029AB7B /* sixcolors.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13CE20DC3DDF0029AB7B /* sixcolors.html */; }; - 84FE13D720DC3DDF0029AB7B /* DaringFireball.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13CF20DC3DDF0029AB7B /* DaringFireball.html */; }; - 84FE13D820DC3DDF0029AB7B /* inessential.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13D020DC3DDF0029AB7B /* inessential.html */; }; - 84FE13D920DC3DDF0029AB7B /* furbo.html in Resources */ = {isa = PBXBuildFile; fileRef = 84FE13D120DC3DDF0029AB7B /* furbo.html */; }; - 84FE13DA20DC3DDF0029AB7B /* HTMLFeedFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE13D220DC3DDF0029AB7B /* HTMLFeedFinderTests.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 84BAAE2B1C8E6B3B009F5239 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84BAAE161C8E6B3B009F5239 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 84BAAE1E1C8E6B3B009F5239; - remoteInfo = RSFeedFinder; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 84B06FEE1ED3808F00F0B54B /* RSWeb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSWeb.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Evergreen-edcdqyvewhytnmcfaiesnqiqeynn/Build/Products/Debug/RSWeb.framework"; sourceTree = ""; }; - 84B06FF01ED380A700F0B54B /* RSXML.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSXML.framework; path = ../RSXML/build/Debug/RSXML.framework; sourceTree = ""; }; - 84B06FF21ED3812600F0B54B /* RSCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSCore.framework; path = ../RSCore/build/Debug/RSCore.framework; sourceTree = ""; }; - 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FeedFinder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 84BAAE291C8E6B3B009F5239 /* FeedFinderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FeedFinderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 84E697E51C8E6C10009C585A /* RSCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSCore.framework; path = ../RSCore/build/Debug/RSCore.framework; sourceTree = ""; }; - 84E697E71C8E6C16009C585A /* RSXML.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSXML.framework; path = ../RSXML/build/Debug/RSXML.framework; sourceTree = ""; }; - 84E697E91C8E6C20009C585A /* RSWeb.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSWeb.framework; path = ../RSWeb/build/Debug/RSWeb.framework; sourceTree = ""; }; - 84F466561F03523100225386 /* RSParser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RSParser.framework; path = ../RSParser/build/Debug/RSParser.framework; sourceTree = ""; }; - 84FE13C120DC3D960029AB7B /* FeedFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FeedFinder.h; path = FeedFinder/FeedFinder.h; sourceTree = ""; }; - 84FE13C320DC3DA70029AB7B /* FeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FeedFinder.swift; path = FeedFinder/FeedFinder.swift; sourceTree = ""; }; - 84FE13C520DC3DAE0029AB7B /* FeedSpecifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FeedSpecifier.swift; path = FeedFinder/FeedSpecifier.swift; sourceTree = ""; }; - 84FE13C720DC3DB50029AB7B /* HTMLFeedFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HTMLFeedFinder.swift; path = FeedFinder/HTMLFeedFinder.swift; sourceTree = ""; }; - 84FE13C920DC3DCA0029AB7B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = FeedFinder/Info.plist; sourceTree = ""; }; - 84FE13CB20DC3DDF0029AB7B /* FeedFinderTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FeedFinderTests.m; sourceTree = ""; }; - 84FE13CD20DC3DDF0029AB7B /* indiestack.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = indiestack.html; sourceTree = ""; }; - 84FE13CE20DC3DDF0029AB7B /* sixcolors.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = sixcolors.html; sourceTree = ""; }; - 84FE13CF20DC3DDF0029AB7B /* DaringFireball.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = DaringFireball.html; sourceTree = ""; }; - 84FE13D020DC3DDF0029AB7B /* inessential.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = inessential.html; sourceTree = ""; }; - 84FE13D120DC3DDF0029AB7B /* furbo.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = furbo.html; sourceTree = ""; }; - 84FE13D220DC3DDF0029AB7B /* HTMLFeedFinderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLFeedFinderTests.swift; sourceTree = ""; }; - 84FE13D320DC3DDF0029AB7B /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 84FE13DC20DC3E4E0029AB7B /* FeedFinder_project_debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FeedFinder_project_debug.xcconfig; sourceTree = ""; }; - D511EF0920242E7A00712EC3 /* FeedFinder_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinder_project.xcconfig; sourceTree = ""; }; - D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinder_target.xcconfig; sourceTree = ""; }; - D511EF0B20242E7A00712EC3 /* FeedFinder_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinder_project_release.xcconfig; sourceTree = ""; }; - D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FeedFinderTests_target.xcconfig; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 84BAAE1B1C8E6B3B009F5239 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 84F466571F03523100225386 /* RSParser.framework in Frameworks */, - 84B06FF31ED3812600F0B54B /* RSCore.framework in Frameworks */, - 84B06FEF1ED3808F00F0B54B /* RSWeb.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 84BAAE261C8E6B3B009F5239 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 84BAAE2A1C8E6B3B009F5239 /* FeedFinder.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 84B06FED1ED3808E00F0B54B /* Frameworks */ = { - isa = PBXGroup; - children = ( - 84F466561F03523100225386 /* RSParser.framework */, - 84B06FF21ED3812600F0B54B /* RSCore.framework */, - 84B06FF01ED380A700F0B54B /* RSXML.framework */, - 84B06FEE1ED3808F00F0B54B /* RSWeb.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 84BAAE151C8E6B3B009F5239 = { - isa = PBXGroup; - children = ( - 84FE13C120DC3D960029AB7B /* FeedFinder.h */, - 84FE13C320DC3DA70029AB7B /* FeedFinder.swift */, - 84FE13C520DC3DAE0029AB7B /* FeedSpecifier.swift */, - 84FE13C720DC3DB50029AB7B /* HTMLFeedFinder.swift */, - 84FE13C920DC3DCA0029AB7B /* Info.plist */, - 84E697E91C8E6C20009C585A /* RSWeb.framework */, - 84E697E71C8E6C16009C585A /* RSXML.framework */, - 84E697E51C8E6C10009C585A /* RSCore.framework */, - 84FE13CA20DC3DDF0029AB7B /* FeedFinderTests */, - 84BAAE201C8E6B3B009F5239 /* Products */, - 84B06FED1ED3808E00F0B54B /* Frameworks */, - D511EF0820242E7A00712EC3 /* xcconfig */, - ); - sourceTree = ""; - }; - 84BAAE201C8E6B3B009F5239 /* Products */ = { - isa = PBXGroup; - children = ( - 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */, - 84BAAE291C8E6B3B009F5239 /* FeedFinderTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 84FE13CA20DC3DDF0029AB7B /* FeedFinderTests */ = { - isa = PBXGroup; - children = ( - 84FE13CB20DC3DDF0029AB7B /* FeedFinderTests.m */, - 84FE13CC20DC3DDF0029AB7B /* Resources */, - 84FE13D220DC3DDF0029AB7B /* HTMLFeedFinderTests.swift */, - 84FE13D320DC3DDF0029AB7B /* Info.plist */, - ); - path = FeedFinderTests; - sourceTree = ""; - }; - 84FE13CC20DC3DDF0029AB7B /* Resources */ = { - isa = PBXGroup; - children = ( - 84FE13CD20DC3DDF0029AB7B /* indiestack.html */, - 84FE13CE20DC3DDF0029AB7B /* sixcolors.html */, - 84FE13CF20DC3DDF0029AB7B /* DaringFireball.html */, - 84FE13D020DC3DDF0029AB7B /* inessential.html */, - 84FE13D120DC3DDF0029AB7B /* furbo.html */, - ); - path = Resources; - sourceTree = ""; - }; - D511EF0820242E7A00712EC3 /* xcconfig */ = { - isa = PBXGroup; - children = ( - D511EF0920242E7A00712EC3 /* FeedFinder_project.xcconfig */, - 84FE13DC20DC3E4E0029AB7B /* FeedFinder_project_debug.xcconfig */, - D511EF0B20242E7A00712EC3 /* FeedFinder_project_release.xcconfig */, - D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */, - D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */, - ); - path = xcconfig; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 84BAAE1C1C8E6B3B009F5239 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 84FE13C220DC3D960029AB7B /* FeedFinder.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 84BAAE1E1C8E6B3B009F5239 /* FeedFinder */ = { - isa = PBXNativeTarget; - buildConfigurationList = 84BAAE331C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinder" */; - buildPhases = ( - 84BAAE1A1C8E6B3B009F5239 /* Sources */, - 84BAAE1B1C8E6B3B009F5239 /* Frameworks */, - 84BAAE1C1C8E6B3B009F5239 /* Headers */, - 84BAAE1D1C8E6B3B009F5239 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = FeedFinder; - productName = RSFeedFinder; - productReference = 84BAAE1F1C8E6B3B009F5239 /* FeedFinder.framework */; - productType = "com.apple.product-type.framework"; - }; - 84BAAE281C8E6B3B009F5239 /* FeedFinderTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 84BAAE361C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinderTests" */; - buildPhases = ( - 84BAAE251C8E6B3B009F5239 /* Sources */, - 84BAAE261C8E6B3B009F5239 /* Frameworks */, - 84BAAE271C8E6B3B009F5239 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 84BAAE2C1C8E6B3B009F5239 /* PBXTargetDependency */, - ); - name = FeedFinderTests; - productName = RSFeedFinderTests; - productReference = 84BAAE291C8E6B3B009F5239 /* FeedFinderTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 84BAAE161C8E6B3B009F5239 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "Ranchero Software"; - TargetAttributes = { - 84BAAE1E1C8E6B3B009F5239 = { - CreatedOnToolsVersion = 7.2.1; - LastSwiftMigration = 0800; - }; - 84BAAE281C8E6B3B009F5239 = { - CreatedOnToolsVersion = 7.2.1; - LastSwiftMigration = 0800; - }; - }; - }; - buildConfigurationList = 84BAAE191C8E6B3B009F5239 /* Build configuration list for PBXProject "FeedFinder" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 84BAAE151C8E6B3B009F5239; - productRefGroup = 84BAAE201C8E6B3B009F5239 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 84BAAE1E1C8E6B3B009F5239 /* FeedFinder */, - 84BAAE281C8E6B3B009F5239 /* FeedFinderTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 84BAAE1D1C8E6B3B009F5239 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 84BAAE271C8E6B3B009F5239 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 84FE13D820DC3DDF0029AB7B /* inessential.html in Resources */, - 84FE13D920DC3DDF0029AB7B /* furbo.html in Resources */, - 84FE13D720DC3DDF0029AB7B /* DaringFireball.html in Resources */, - 84FE13D520DC3DDF0029AB7B /* indiestack.html in Resources */, - 84FE13D620DC3DDF0029AB7B /* sixcolors.html in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 84BAAE1A1C8E6B3B009F5239 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 84FE13C420DC3DA70029AB7B /* FeedFinder.swift in Sources */, - 84FE13C820DC3DB50029AB7B /* HTMLFeedFinder.swift in Sources */, - 84FE13C620DC3DAE0029AB7B /* FeedSpecifier.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 84BAAE251C8E6B3B009F5239 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 84FE13DA20DC3DDF0029AB7B /* HTMLFeedFinderTests.swift in Sources */, - 84FE13D420DC3DDF0029AB7B /* FeedFinderTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 84BAAE2C1C8E6B3B009F5239 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 84BAAE1E1C8E6B3B009F5239 /* FeedFinder */; - targetProxy = 84BAAE2B1C8E6B3B009F5239 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 84BAAE311C8E6B3B009F5239 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - SWIFT_VERSION = 4.0; - }; - name = Debug; - }; - 84BAAE321C8E6B3B009F5239 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0B20242E7A00712EC3 /* FeedFinder_project_release.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 84BAAE341C8E6B3B009F5239 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */; - buildSettings = { - INFOPLIST_FILE = FeedFinder/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinder; - SWIFT_VERSION = 4.0; - }; - name = Debug; - }; - 84BAAE351C8E6B3B009F5239 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0A20242E7A00712EC3 /* FeedFinder_target.xcconfig */; - buildSettings = { - INFOPLIST_FILE = FeedFinder/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinder; - }; - name = Release; - }; - 84BAAE371C8E6B3B009F5239 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */; - buildSettings = { - INFOPLIST_FILE = FeedFinderTests/Info.plist; - }; - name = Debug; - }; - 84BAAE381C8E6B3B009F5239 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D511EF0C20242E7A00712EC3 /* FeedFinderTests_target.xcconfig */; - buildSettings = { - INFOPLIST_FILE = FeedFinderTests/Info.plist; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 84BAAE191C8E6B3B009F5239 /* Build configuration list for PBXProject "FeedFinder" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84BAAE311C8E6B3B009F5239 /* Debug */, - 84BAAE321C8E6B3B009F5239 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 84BAAE331C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinder" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84BAAE341C8E6B3B009F5239 /* Debug */, - 84BAAE351C8E6B3B009F5239 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 84BAAE361C8E6B3B009F5239 /* Build configuration list for PBXNativeTarget "FeedFinderTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 84BAAE371C8E6B3B009F5239 /* Debug */, - 84BAAE381C8E6B3B009F5239 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 84BAAE161C8E6B3B009F5239 /* Project object */; -} diff --git a/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 869932f23..000000000 --- a/Frameworks/FeedFinder/FeedFinder.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Frameworks/FeedFinder/FeedFinder/FeedFinder.h b/Frameworks/FeedFinder/FeedFinder/FeedFinder.h deleted file mode 100644 index 0e51c8f2d..000000000 --- a/Frameworks/FeedFinder/FeedFinder/FeedFinder.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// FeedFinder.h -// FeedFinder -// -// Created by Brent Simmons on 3/7/16. -// Copyright © 2016 Ranchero Software, LLC. All rights reserved. -// - -#import - -//! Project version number for FeedFinder. -FOUNDATION_EXPORT double FeedFinderVersionNumber; - -//! Project version string for FeedFinder. -FOUNDATION_EXPORT const unsigned char FeedFinderVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - -/* Given a URL, find one or more feeds. - -Download URL - If is feed, return URL - If is web page, find possible feeds in web page - Download each possible URL - If URL is feed, add to URLs list - return URLs list -*/ - diff --git a/Frameworks/FeedFinder/FeedFinder/Info.plist b/Frameworks/FeedFinder/FeedFinder/Info.plist deleted file mode 100644 index 3343335ab..000000000 --- a/Frameworks/FeedFinder/FeedFinder/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2016 Ranchero Software, LLC. All rights reserved. - NSPrincipalClass - - - diff --git a/Frameworks/FeedFinder/FeedFinderTests/FeedFinderTests.m b/Frameworks/FeedFinder/FeedFinderTests/FeedFinderTests.m deleted file mode 100644 index 7b4edc8b6..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/FeedFinderTests.m +++ /dev/null @@ -1,39 +0,0 @@ -// -// FeedFinderTests.m -// FeedFinderTests -// -// Created by Brent Simmons on 3/7/16. -// Copyright © 2016 Ranchero Software, LLC. All rights reserved. -// - -#import - -@interface FeedFinderTests : XCTestCase - -@end - -@implementation FeedFinderTests - -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void)testExample { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. -} - -- (void)testPerformanceExample { - // This is an example of a performance test case. - [self measureBlock:^{ - // Put the code you want to measure the time of here. - }]; -} - -@end diff --git a/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift b/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift deleted file mode 100644 index ed5c78013..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/HTMLFeedFinderTests.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// HTMLFeedFinderTests.swift -// FeedFinder -// -// Created by Brent Simmons on 8/7/16. -// Copyright © 2016 Ranchero Software, LLC. All rights reserved. -// - -import XCTest -@testable import FeedFinder -import RSParser - -class HTMLFeedFinderTests: XCTestCase { - - func parserData(_ filename: String, _ fileExtension: String, _ url: String) -> ParserData { - - let bundle = Bundle(for: HTMLFeedFinderTests.self) - let path = bundle.path(forResource: filename, ofType: fileExtension)! - let data = try! Data(contentsOf: URL(fileURLWithPath: path)) - return ParserData(url: url, data: data) - } - - func feedFinder(_ fileName: String, _ fileExtension: String, _ url: String) -> HTMLFeedFinder { - - let d = parserData(fileName, fileExtension, url) - return HTMLFeedFinder(parserData: d) - } - - func testPerformanceWithDaringFireball() { - - let d = parserData("DaringFireball", "html", "https://daringfireball.net/") - self.measure { - - let finder = HTMLFeedFinder(parserData: d) - let _ = finder.feedSpecifiers - } - } - - func testFindingBestFeedWithDaringFireBall() { - - let finder = feedFinder("DaringFireball", "html", "https://daringfireball.net/") - let feedSpecifiers = finder.feedSpecifiers - let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers)! - XCTAssert(bestFeedSpecifier.urlString == "https://daringfireball.net/feeds/json") - } - - func testFindingBestFeedWithFurbo() { - - let finder = feedFinder("furbo", "html", "http://furbo.org") - let feedSpecifiers = finder.feedSpecifiers - let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers)! - XCTAssert(bestFeedSpecifier.urlString == "http://furbo.org/feed/") - } - - func testFindingBestFeedWithIndieStack() { - - let finder = feedFinder("indiestack", "html", "http://indiestack.com/") - let feedSpecifiers = finder.feedSpecifiers - let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers)! - XCTAssert(bestFeedSpecifier.urlString == "http://indiestack.com/feed/json/") - } - -} - - - diff --git a/Frameworks/FeedFinder/FeedFinderTests/Info.plist b/Frameworks/FeedFinder/FeedFinderTests/Info.plist deleted file mode 100644 index ba72822e8..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/Frameworks/FeedFinder/FeedFinderTests/Resources/DaringFireball.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/DaringFireball.html deleted file mode 100644 index 4bcdf3000..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/Resources/DaringFireball.html +++ /dev/null @@ -1,1463 +0,0 @@ - - - - - Daring Fireball - - - - - - - - - - - - - - -
- - - -
- - -
-
-How Much Faster is the iPhone X’s ‘Telephoto’ Lens Than the iPhone 7 Plus’s?  -
-
-

Dan Provost:

- -
-

I also used the manual camera app Halide to get an ISO and shutter speed reading at the various light levels, and came to the conclusion that the iPhone X requires roughly 2 fewer stops of light before switching to the telephoto lens, as compared to the iPhone 7 Plus. This is obviously great news, and speaks to how improved the second lens is after just one year. In my own use of the phone for the past couple weeks, it does indeed seem to be the case that I am very rarely presented with a 2X cropped image.

-
- -

Impressive.

- -
- - -
- - -
-
-FCC Unveils Plan to Repeal Net Neutrality Rules  -
-
-

Brian Fung, reporting for The Washington Post:

- -
-

The Federal Communications Commission took aim at a signature Obama-era regulation Tuesday, unveiling a plan that would give Internet providers broad powers to determine what websites and online services their customers see and use.

- -

Under the agency’s proposal, providers of high-speed Internet services, such as Comcast, Verizon and AT&T, would be able to block websites they do not like and charge Web companies for speedier delivery of their content.

-
- -

This is literally bad for everyone but these mega-ISPs. Horrendously bad — and unpopular — policy.

- -
- - -
- - -
-
-Google Collects Android Users’ Locations Even When Location Services Are Disabled  -
-
-

Keith Collins, reporting for Quartz:

- -
-

Many people realize that smartphones track their locations. But what if you actively turn off location services, haven’t used any apps, and haven’t even inserted a carrier SIM card?

- -

Even if you take all of those precautions, phones running Android software gather data about your location and send it back to Google when they’re connected to the internet, a Quartz investigation has revealed.

- -

Since the beginning of 2017, Android phones have been collecting the addresses of nearby cellular towers — even when location services are disabled — and sending that data back to Google. The result is that Google, the unit of Alphabet behind Android, has access to data about individuals’ locations and their movements that go far beyond a reasonable consumer expectation of privacy.

- -

Quartz observed the data collection occur and contacted Google, which confirmed the practice.

- -

The cell tower addresses have been included in information sent to the system Google uses to manage push notifications and messages on Android phones for the past 11 months, according to a Google spokesperson. They were never used or stored, the spokesperson said, and the company is now taking steps to end the practice after being contacted by Quartz. By the end of November, the company said, Android phones will no longer send cell-tower location data to Google, at least as part of this particular service, which consumers cannot disable.

-
- -

If they were “never used or stored”, why did they start collecting them in the first place? This is like a kid caught with their hand in the cookie jar saying they weren’t going to eat any cookies. Sure.

- -
- - -
-CNBC’s Google Pixel Buds Review  -
-
-

Todd Haselton, writing for CNBC:

- -
-

There’s nothing I recommend about the Pixel Buds. They’re cheap-feeling and uncomfortable, and you’re better off using the Google Translate app on a phone instead of trying to fumble with the headphones while trying to translate a conversation. The idea is neat, but it just doesn’t work well enough to recommend to anyone on any level.

-
- -

Hardware is hard.

- -
- - -
- - -
-
-iPhone 7 Plus and Portrait Mode Lighting Effects  -
-
-

Steven Troughton-Smith discovered that portrait mode lighting effects can be edited on an iPhone 7 Plus after using a hex editor on an exported photo to enable the feature:

- -
-

Just to add insult to injury, if you AirDrop that photo back to the iPhone 7 Plus now it shows the Portrait Lighting UI, and lets you change mode. So Portrait Lighting is 100% an artificial software limitation. 7 Plus photos can have it, 7 Plus can do it.

-
- -

My understanding is that these effects aren’t enabled on iPhone 7 Plus because performance was really slow at capture time. It really does require the A11 Bionic chip for adequate performance live in the camera. And Apple decided against shipping it as a feature for 7 Plus that could only be applied in post, because that felt like half a feature. So I’ve heard.

- -

What I don’t know is why the new lighting effects are not available when you use an iPhone X or 8 Plus to edit a portrait mode photo that was taken using an iPhone 7 Plus. This should be possible.

- -
- - -
-The Best iPhone Fast Chargers and Wireless Chargers  -
-
-

Joanna Stern, writing for The Wall Street Journal:

- -
-

Wireless charging means you can toss your phone on a pad (sold separately!) on your desk and it will charge throughout the day. With a fast charger (sold separately!), you can plug your phone in and go from zero to 50% in 30 minutes.

- -

Both can make a real difference in how you combat battery anxiety disorder. But figuring out which gear you need is complicated.

- -

I went in search of the best options for both speed and wireless convenience, charging and draining iPhones nearly 30 times. My finding: Getting the best chargers doesn’t mean running up your charge card.

-
- -

I second her recommendation of this 3-in-1 cable from Monoprice — Lightning, USB-C, and micro USB all on a single cable.

- -
- - -
-BuzzFeed: McMaster Mocked Trump’s Intelligence in a Private Dinner  -
-
-

Joseph Bernstein, reporting for BuzzFeed:

- -
-

Over a July dinner with Oracle CEO Safra Catz — who has been mentioned as a candidate for several potential administration jobs — McMaster bluntly trashed his boss, said the sources, four of whom told BuzzFeed News they heard about the exchange directly from Catz. The top national security official dismissed the president variously as an “idiot” and a “dope” with the intelligence of a “kindergartner,” the sources said.

- -

A sixth source who was not familiar with the details of the dinner told BuzzFeed News that McMaster had made similarly derogatory comments about Trump’s intelligence to him in private, including that the president lacked the necessary brainpower to understand the matters before the National Security Council.

-
- -
- - -
- - -
-
-The Talk Show: ‘Christmas Mitzvah’  -
-
-

Merlin Mann returns to the show for a Thanksgiving-week holiday spectacular. Topics include the history of Markdown, nerding out with Keyboard Maestro, kids today and the computers they want to use, caring about idiomatic native UI design, a look back at last year’s election, and more.

- -

Brought to you by these fine sponsors:

- -
    -
  • Away: Travel smarter with the suitcase that charges your phone. Get $20 off with code TALKSHOW.
  • -
  • Eero: Finally, Wi-Fi that works. Use code THETALKSHOW for free shipping in the U.S. and Canada.
  • -
  • Fracture: Your photos, printed directly on glass. Great gift idea. Save 15% off your first order with code TALK15.
  • -
- -
- - -
-Microsoft App Center  -
-
-

My thanks to Microsoft for sponsoring this week’s DF RSS feed to promote App Center, their recently-launched service for Apple developers that connects to your GitHub repo to automatically build, test, distribute, and monitor iOS and Mac apps. App Center is the next generation of HockeyApp, which was acquired by Microsoft a few years ago.

- -

The basic HockeyApp features like beta distribution and crash reporting got a revamped user interface, and Microsoft added new features for building, testing, analytics, and push notifications. Simply connect your repo, build the app on App Center’s Mac cloud, and run automated UI tests on thousands of real iOS devices in their hosted device lab. You can not only distribute your builds to testers, but also deploy directly to the App Store.

- -

You can use all of these features together, or just the pieces that complement your current workflow. Spend less time on drudgery, and more time on your app. Sign up now.

- -
- - -
- - -
-
-HomePod Delayed Until ‘Early 2018’  -
-
-

I just got this statement from an Apple spokesperson:

- -
-

“We can’t wait for people to experience HomePod, Apple’s -breakthrough wireless speaker for the home, but we need a little -more time before it’s ready for our customers. We’ll start -shipping in the US, UK and Australia in early 2018.”

-
- -

I had a feeling this would happen when the iPhone X press briefings came and went without a word about HomePod. It’s a tough miss for Apple — there are surely going to be a lot of Amazon Echo devices under Christmas trees this year.

- -
- - -
- - -
-
-Apple Machine Learning Journal: ‘An On-Device Deep Neural Network for Face Detection’  -
-
-

Apple Machine Learning Journal:

- -
-

We faced several challenges. The deep-learning models need to be -shipped as part of the operating system, taking up valuable NAND -storage space. They also need to be loaded into RAM and require -significant computational time on the GPU and/or CPU. Unlike -cloud-based services, whose resources can be dedicated solely to a -vision problem, on-device computation must take place while -sharing these system resources with other running applications. -Finally, the computation must be efficient enough to process a -large Photos library in a reasonably short amount of time, but -without significant power usage or thermal increase.

-
- -
- - -
- - -
-
-Face ID’s Innovation: Continuous Authentication  -
-
-

Rich Mogull, writing at TidBITS:

- -
-

Every year, as I travel around the security conference circuit, -the hallway conversations always turn to the interesting things -attendees have seen lately. To be honest, I can’t remember the -last time I was excited about a legitimately cool security -technology. I see plenty of security evolution, but not much -revolution.

- -

That is, until my iPhone X arrived on launch day, and I got to try -Face ID in real-world usage. Put simply, Face ID is the most -compelling advancement in security I have seen in a very long -time. It’s game-changing not merely due to the raw technology, but -also because of Apple’s design and implementation.

-
- -
- - -
-Vector  -
-
-

Rene Ritchie has re-launched Vector as a daily — yes, daily — podcast. I’m halfway through yesterday’s “Designing for iPhone X Roundtable” episode, with guests Sebastiaan de With, Linda Dong, Marc Edwards, and Brad Ellis, and it’s terrific.

- -
- - -
-The Ringer: ‘The 50 Best Superhero Movies of All Time’  -
-
-

I largely somewhat agree with these rankings — but far more so than I usually do with such lists. But the whole thing is worth it just for the sub-list of the best superhero villains of all time — they nailed that one.

- -
- - -
-Jimmy Iovine and Most Bomb Record in the Solar System  -
-
-

Jason Kottke on the golden record NASA sent into deep space with Voyager:

- -
-

Carl Sagan was project director, Ann Druyan the creative director, -and Ferris produced the Record. And the sound engineer for the -Golden Record? I was surprised to learn: none other than Jimmy -Iovine, who was recommended to Ferris by John Lennon.

-
- -

As Kottke asks, how was this not in The Defiant Ones?

- -
- - -
- - -
-
-How Facebook Figures Out Everyone You’ve Ever Met  -
-
-

Excellent investigation by Kashmir Hill, writing for Gizmodo, on Facebook’s creepy “People You May Know” system:

- -
-

In the months I’ve been writing about PYMK, as Facebook calls it, -I’ve heard more than a hundred bewildering anecdotes:

- -
    -
  • A man who years ago donated sperm to a couple, secretly, so they -could have a child — only to have Facebook recommend the child -as a person he should know. He still knows the couple but is not -friends with them on Facebook.
  • -
  • A social worker whose client called her by her nickname on their -second visit, because she’d shown up in his People You May Know, -despite their not having exchanged contact information.
  • -
  • A woman whose father left her family when she was six years old -— and saw his then-mistress suggested to her as a Facebook -friend 40 years later.
  • -
  • An attorney who wrote: “I deleted Facebook after it recommended -as PYMK a man who was defense counsel on one of my cases. We had -only communicated through my work email, which is not connected -to my Facebook, which convinced me Facebook was scanning my work -email.”
  • -
-
- -

Even if, like me, you’ve never even signed up for Facebook, they almost certainly have a detailed profile of you.

- -
- - -
- - -
-
-Ming-Chi Kuo on 2018 iPhones  -
-
-

MacRumors on the latest from Ming-Chi Kuo:

- -
-

Kuo expects the 5.8-inch model to have 458 pixels per inch, -suggesting the second-generation iPhone X’s display will likely -continue to have a resolution of 1,125×2,436. He said the 6.5-inch -model will have roughly 480 to 500 PPI, while the 6.1-inch model -is estimated to have between 320 and 330 PPI.

- -

In his latest research note, obtained by MacRumors, Kuo said the -6.1-inch model will have a lower-resolution LCD display and target -the low-end and mid-range markets with an estimated $649 to $749 -starting price in the United States.

- -

If accurate, next year’s new iPhone lineup would consist of the -second-gen iPhone X with the same size screen, a larger 6.5-inch -version that we’re tentatively calling the iPhone X Plus, and a -mid-range 6.1-inch LCD model that adopts an iPhone X form factor -and features but with a cheaper price point.

-
- -

A “Plus” sized version of the iPhone X makes perfect sense. Even without these rumors from the supply chain, I’d have been surprised if Apple didn’t create such a phone next. The iPhone X may well draw some current Plus-sized iPhone users, but in use it feels like a “regular” sized iPhone with an edge-to-edge display. Given the popularity of Plus-sized phones, I can’t see why Apple wouldn’t do that with the X design.

- -

But this 6.1-inch model with an LCD display makes no sense to me. First, I’d be surprised to see the X design trickle down to the $750 price range after just one year. Second, the size makes no sense to me. There’s a clear difference between the 4.7-inch and 5.5-inch regular and Plus classic-style iPhones. There would be a clear difference between 5.8-inch and 6.5-inch X-style phones. An additional 6.1-inch lower-priced X-style phone would just confuse things terribly. I don’t think Kuo has the story right on this phone.

- -
- - -
-Ina Fried Reviews Google’s Pixel Buds  -
-
-

Ina Fried, writing for Axios:

- -
-

Apple’s AirPods are more elegant as well as smaller and more -comfortable. However, Pixel Buds have some other appeals, most -notably the ability to aid in real-time language translation.

-
- -

The real-time translation feature is cool, but how often would you need it? I’ve been using AirPods for about a year and I don’t think I would have used this feature even once. And it seems like it’s more of a feature of the Google Translate app, not the Pixel Buds themselves.

- -

Given that they both cost $159, Apple comes out way ahead here.

- -
- - -
-Long-Term Coffee Consumption and Risk of Cardiovascular Disease  -
-
-

New paper published in Circulation:

- -
-

Background — Considerable controversy exists regarding the -association between coffee consumption and cardiovascular disease -(CVD) risk. A meta-analysis was performed to assess the -dose-response relationship of long-term coffee consumption with -CVD risk. […]

- -

Conclusions — A non-linear association between coffee -consumption with CVD risk was observed in this meta-analysis. -Moderate coffee consumption was inversely significantly -associated with CVD risk, with the lowest CVD risk at 3 to 5 -cups/d, and heavy coffee consumption was not associated with -elevated CVD risk.

-
- -

I like that 5 cups of coffee per day qualified as “moderate”. That’s right around what I consume.

- -
- - -
- - -
-
-Squarespace Domains  -
-
-

My thanks to Squarespace for sponsoring this week’s DF RSS feed. Buying a domain name from Squarespace is quick, simple, and fun. Search for the domain you want, or type any word or phrase into the search field, and Squarespace will suggest some great options. Every domain comes with a beautiful, ad-free parking page, WHOIS Privacy, and a 2048-bit SSL certificate to secure your website — all at no additional cost. Once you lock down your domain, create a beautiful website with one of Squarespace’s award-winning templates.

- -

Try Squarespace for free. When you’re ready to subscribe, get 10 percent off at squarespace.com with offer code “DARING17”.

- -
- - -
-The Talk Show: ‘Bed Is Where My Problems Are’  -
-
-

Ben Thompson returns to the show to talk about the iPhone X.

- -

Brought to you by these fine sponsors:

- -
    -
  • Casper: You can be sure of your purchase with Casper’s 100 night risk-free, sleep-on-it trial.
  • -
  • Squarespace: Make your next move. Use code talkshow for 10% off your first order.
  • -
  • Fracture: Photos printed in vivid color directly on glass. Get 10% off your first order.
  • -
- -
- - -
- - -
-
-Logitech Makes It Right  -
-
-

Logitech, on their company blog:

- -
-

We heard you and we want to make it right.

- -

If you are a Harmony Link user, we will reach out to you between -now and March 2018 to make arrangements to replace your Link with -a free Harmony Hub, a product with similar app-based remote -control features to Link, with the added benefit of controlling -many popular connected home devices plus, it works with popular -voice assistants.

-
- -
- - -
-Equifax Faces Hundreds of Class-Action Lawsuits and an SEC Subpoena Over the Way It Handled Its Data Breach  -
-
-

Hayley Tsukayama, reporting for The Washington Post:

- -
-

Equifax also said in its filings that it had received subpoenas -from the Securities and Exchange Commission, as well as the U.S. -Attorney’s Office for the Northern District of Georgia “regarding -trading activities by certain of our employees in relation to the -cybersecurity incident.” Shortly after news of the breach broke, -reports circulated that top officials had sold Equifax stock after -the company found out about the breach, but before disclosing it -to the public. Equifax said this week that it had cleared its -executives of wrongdoing after an internal investigation found -that the executives did not personally know about the breach -before their stock sales.

-
- -

Yeah, I’m sure the SEC will just take their word for it.

- -
- - -
-Clips 2.0  -
-
-

Major new release of Apple’s app “for making and sharing fun videos with text, effects, graphics, and more.” Headline feature for iPhone X:

- -
-

Selfie Scenes on iPhone X make Clips even more fun by using the -TrueDepth camera to place you in beautifully animated -landscapes, abstract art, and even onboard the Millennium Falcon -from Star Wars: The Last Jedi. Each scene is a full 360‑degree -experience, so however you move iPhone X, the scene surrounds -you on all sides.

-
- -

Here’s a perfect example from Rian Johnson.

- -

For an app that only debuted six months ago, Clips 2.0 is an ambitious 2.0. The entire user interface has been redone, and I think it makes everything more clear and obvious. I think Clips is the single best example of a productivity app designed for iOS.

- -

Ryan Christoffel, writing for MacStories, has a really good rundown of what’s new and what’s changed in 2.0:

- -
-

When Clips first debuted earlier this year, it was unknown what -kind of support the app would receive from Apple going forward. -Would it be another Music Memos, released to the public then -largely left alone? While Clips 1.1 was an encouraging sign of -life, today’s 2.0 clearly demonstrates Apple’s commitment to this -app. And I’m glad for that.

-
- -

I think Clips has flown under the radar since its release, but Apple seems very serious about it. It’s a big hit, apparently, in schools, where kids are using it to create presentations for classwork using iPads.

- -

And one for the road: Rene Ritchie has a good look at it for iMore.

- -
- - -
-SuperDuper 3.0  -
-
-

Dave Nanian, Shirt Pocket Software:

- -
-

With that last bit of explanation, I’m happy to say that we’ve -reached the end of this particular voyage. SuperDuper! 3.0 -(release 100!) is done, and you’ll find the download in the normal -places, as well as in the built-in updater, for both Beta and -Regular users.

- -

SuperDuper! 3.0 has, literally, many hundreds of changes under the -hood to support APFS, High Sierra and all version of macOS from -10.9 to the the present.

- -

SuperDuper! 3.0 is the first bootable backup application to -support snapshot copying on APFS, which provides an incredible -extra level of safety, security and accuracy when backing up. -It’s super cool, entirely supported (after all, it’s what Time -Machine uses… and it was first overall), and totally transparent -to the user.

-
- -

Fantastic update to one of my very favorite Mac utilities. I bought SuperDuper 1.5 in 2005, and I believe every single update since then has been free. I wish they’d charge me, I love SuperDuper so much.

- -

If you’re not familiar with it, SuperDuper lets you clone any volume to another drive or disk image. It’s really configurable, but with a very easy to understand UI. It’s also really smart, and incredibly trustworthy. I recommend it wholeheartedly.

- -
- - -
-Wallpaper Interview With Jony Ive on Apple Park  -
-
-

Nick Compton, writing for Wallpaper:

- -
-

The building, though, is not a metaphor for open systems, or -creative flow made concrete. It is a made object. Apple’s success -has been built on higher-order industrialisation; not just -designing beautiful objects that do all manner of new things but -producing them in incredible numbers and at consistent quality. -Its new building is, in some ways, the ultimate Apple product, in -places using the same materials the company uses in its laptops -and phones.

- -

Ive, above all else, is a maker, thrilled to have his CNC milling -machines close at hand. This culture of making was at the heart of -what Behling calls the ‘hybrid studio’ forged by the Apple and -Foster + Partners teams. ‘One of the connections that we made very -quickly was that their approach to problem solving was uncannily -similar to ours,’ Ive says. ‘We both make lots and lots of models -and prototypes. We made full-size prototypes of parts of the -building, we made prototypes to examine and explore a material. -The prototyping took many forms.’

-
- -

Gorgeous architectural photography throughout this piece — save it to read on the biggest display you have.

- -
- - -
-USB-C Earbuds: Slim Pickings  -
-
-

Helen Havlak, writing for The Verge:

- -
-

Two weeks after starting my cheap Pixel 2 earbud search, I finally -have a working pair — but they cost almost twice the amount I -wanted to spend, and don’t feel very premium. If I lose or break -them, it’ll cost me almost $50 and another 10-day wait. The next -time I upgrade my phone, they may not be compatible. Even the -Apple Store sells $29 Lightning EarPods. Google needs to do a lot -better by its Pixel owners than a single $149 USB-C option. Even -better, just give us back the damn headphone jack.

-
- -

Apple does better than selling $29 Lightning earbuds — they include a pair in the box with every iPhone. It’s embarrassing that Google doesn’t include a pair of USB-C earbuds with the Pixels.

- -
- - -
-Nintendo at Its Best  -
-
-

Chris Compendio, reviewing Super Mario Odyssey for Paste:

- -
-

I found that this videogame was persistent in its mission to bring -me joy. Super Mario Odyssey is extra — in that same area in the -Wooded Kingdom, I stood next to a boom box, and Mario, without any -button prompt, automatically began dancing to the music. When I -left Mario alone for more than a few seconds, he would lay down -for a nap, and a bird would eventually land on his nose, with each -kingdom having a different kind of bird. There are many moments -like this that serve little to no purpose other than smiles, -laughs and entertainment. Nintendo has a classic charm in all of -their products. They do not simply go for the extra mile, but for -at least fifty miles beyond that.

-
- -

I bought it last week, but haven’t had time to play yet. Looking forward to it.

- -
- - -
- - -
-
-Forking the iPhone  -
-
-

Jean-Louis Gassée:

- -
-

What we see is Apple is doing what they do best: Taking chances. -They made a risky bet with the iPhone X and covered it with the -iPhone 8. The new and improved perception of Apple might come from -the realization that both bets are winning, and that the iPhone X -is a radically new, as opposed to a merely improved, breed of -smartphone — and probably is the start of a new succession of -carefully incremented future models.

-
- -

A fork is exactly right: the iterative, familiar iPhone 8 and 8 Plus on one side of the fork, and the novel, back-to-the-drawing board iPhone X on the other.

- -
- - -
-TripAdvisor Removed Warnings About Rapes and Injuries at Mexico Resorts  -
-
-

Raquel Rutledge and Andrew Mollica, reporting for The Milwaukee Journal Sentinel:

- -
-

Seven years ago, TripAdvisor repeatedly removed a post written by -Kristie Love, a 35-year-old mother of two from Dallas. Love told -how she had been raped by a security guard at a highly rated -all-inclusive Mexican resort owned by the global chain, Iberostar, -based in Spain.

- -

She wrote how, after an evening with friends, she had returned to -her room to find the electronic key card no longer opened her door -at the Iberostar Paraiso near Playa del Carmen. She headed to the -lobby of the sprawling resort to get her card reactivated and -stopped to ask a uniformed guard whether she was walking in the -right direction.

- -

He motioned her to follow him, then overpowered her, dragged her -into some bushes and raped her. When she reached the lobby in -tears, hotel staff refused to call police.

- -

A TripAdvisor moderator spotted the post soon after it had -published and deemed it in violation of the company’s “family -friendly” guidelines.

- -

The following year, another young woman, 19 and on vacation with -her family, reported to hotel officials in the same resort complex -that a security guard had raped her in the bathroom.

- -

And in 2015, still another woman, Jamie Valeri, 34, a mother of -six from Wisconsin, was sexually assaulted at the same resort -after she and her husband simultaneously blacked out in the middle -of the day, barely into their third drink.

-
- -

It’s positively sickening that as a matter of TripAdvisor policy, actual rapes, sexual assaults, and druggings are OK, but reports about these crimes on their forums are not. TripAdvisor should get sued out of existence.

- -
- - -
-Most-Used OS in the World?  -
-
-

Andrew Tanenbaum, creator of the MINIX operating system, in an open letter to Intel CEO Brian Krzanich:

- -
-

Thanks for putting a version of MINIX 3 inside the ME-11 -management engine chip used on almost all recent desktop and -laptop computers in the world. I guess that makes MINIX the most -widely used computer operating system in the world, even more than -Windows, Linux, or MacOS. And I didn’t even know until I read a -press report about it. Also here and here and -here and here and here (in Dutch), and a bunch of -other places.

-
- -

It’s an interesting development, having a full-blown operating system running inside a CPU. And it’s a nice feather in the cap for MINIX, which heretofore had best been known as a teaching OS for computer science students. But it can’t be the most-used OS in the world. Android is. (Or, if you only want to count the kernel-level operating system, Linux, which runs at the heart of Android.)

- -

MINIX is now almost certainly the most widely-used OS on Intel-based computers, but Intel-based computers are now far outnumbered by ARM-based ones.

- -
- - -
-Horace Dediu: Apple Watch Will Soon Generate More Revenue Than iPod at Peak  -
-
-

Bookmark this for the next time you see someone claim Apple Watch is a flop.

- -
- - -
-Notcho  -
-
-

Notcho, from Cromulent Labs:

- -
-

Not a fan of the notch? Want to hide the horns? Now you can -quickly and easily create wallpapers that hide the notch on your -new iPhone X.

-
- -

It’s a clever little hack: you give Notcho an image, and Notcho lets you export a version with black bars and rounded corners at the top to hide the iPhone X’s sensor array notch. I don’t actually think this is a good idea — if there’s anywhere where I think embracing the notch is just fine, it’s on the lock and home screens. Where the notch should have been hidden is when you’re using apps. This utility doesn’t (and can’t) do anything about it. This was Apple’s decision to make, and even if you disagree with how they decided to handle it, I don’t think you should fight it. I still don’t like it, but I have to say that after nearly two weeks with iPhone X, I really don’t notice it.

- -

But damn if the name “Notcho” isn’t clever — it might be the best possible name for a utility that does this. Also clever is the monetization strategy: Notcho is free to download and use, but any wallpapers you create with it are watermarked with “Notcho” in the bottom right corner. For $2 you can remove the watermark. And if anyone is going to be bothered by that watermark, it’s the same sort of person who’s bothered by the notch.

- -

(I really hope that floppy disk icon for the Save button is a joke.)

- -
- - -
- -
- - -
-

Twitter’s 280-Character Own Goal

- - -

J.K. Rowling, on Twitter raising the per-tweet character limit to 280:

- -
-

Twitter’s destroyed its USP. The whole point, for me, was how -inventive people could be within that concise framework.

-
- -

USP is “unique selling proposition”. By doubling the character limit, Twitter has eliminated what made them unique. Yes, there were many trade-offs with the 140-character limit, both pros and cons. But one of the pros is it made Twitter unique. Twitter timelines now look more like Facebook — but Facebook is already there for Facebook-like timelines. Twitter trying to be more like Facebook is like basketball trying to be more like football — a bad idea that won’t work.

- -

Stephen King was more succinct:

- -
-

280 characters? Fuck that.

-
- -

Andy Ihnatko:

- -
-

I like the word-Tetris of making a complete thought fit in a -140-character box.

-
- -

John Dingell, 91-year-old retired Congressman from Michigan (who is truly excellent at Twitter):

- -
-

99% of you people don’t even deserve 140 characters.

-
- -

It’s no surprise that writers, in particular, object to this change. I agree with Ihnatko — the 140-character limit made it a challenge. Fitting certain complex thoughts into a mere 140 characters sometimes felt like solving a small challenge, like one of The New York Times’s tiny little 5 × 5 crossword puzzles.

- -

But perhaps the best commentary comes from William Shakespeare:

- -
-

Brevity is the soul of wit.

-
- -

Given 280 characters, people are going to use them, even to express thoughts that could have fit in 140. Given unlimited characters, such as in email, people ramble aimlessly.

- -

That’s why email feels like a dreary chore, and Twitter feels like fun. The fewer tweets that fit in a single screen at a time, the less fun Twitter feels. I’m sure Twitter considered this change carefully, but I’m convinced they’ve made a terrible mistake. 

- -
- -
- - - -
-
-Understanding Apple’s Multinational Tax Payments  -
-
-

Great piece by Shawn Tully for Fortune:

- -
-

I figured that if this reporter found corporate taxes baffling, so -did lots of sophisticated Fortune readers. So I dug into the -financials of Apple to grasp how the world’s most valuable -publicly traded company accounts for taxes. Albert Meyer, a -forensic accountant and former academic who runs investment firm -Bastiat Capital, helped explain how and why Apple books or defers -taxes on different categories of income, and which rates it -applies to each category. With his help, I present a primer on -taxation of multinationals, using Apple as a case study.

-
- -

I still don’t quite understand the whole thing, but I have a much better grasp than I did before. And I’m more convinced than ever that Apple is doing something complicated, not something devious.

- -
-

It’s important to emphasize that Apple actually pays a lot of tax -compared to other U.S.-based corporations with immense foreign -earnings, and takes a highly conservative approach to tax -accounting. […]

- -

For FY 2016, Apple booked total pre-tax earnings of $61.4 billion. -On its income statement, Apple showed a “provision for taxes” of -$15.685 billion. That number is an expense that’s deducted -straight from pre-tax income of $61.4 billion to yield net income -of $45.7 billion. Hence, its reported “effective tax rate” was -25.6% ($15.685 billion divided by $61.4 billion), well below the -official 35%, but on the high side for multinationals, many of -which are in the teens.

-
- -

The news coverage on Apple’s tax avoidance would lead you to believe (and in fact has led many to believe) that Apple pays a lower effective tax rate than most companies, when the truth is they pay a higher rate than most of their peers.

- -

And later:

- -
-

It’s important to note that Apple is extremely responsible in the -use of this exemption for reinvested earnings. Many multinationals -report that they intend to plough all of their foreign profits -into operations, and hence, don’t make any accruals for U.S. taxes -on their offshore earnings. Apple is the rare tech titan that books -large annual accruals that lower net income.

-
- -

The problem isn’t Apple’s tax structure, it’s U.S. law. You can argue that Apple should voluntarily pay more in taxes than they’re legally obligated to, but no one who holds such views would ever get hired as a finance executive at a large publicly held company.

- -
- - -
-Barry Ritholtz: ‘Why Apple Should Buy Netflix’  -
-
-

Barry Ritholtz, writing for Bloomberg:

- -
-

I try not to give billionaires or corporate managers unsolicited -advice on what they should do with their money. Warren Buffett and -Apple Inc. both have done rather well for themselves and their -investors without my help. Today, I violate my own rule: Apple -should buy Netflix Inc. in an all-stock deal for about $100 -billion. […]

- -

The upsides for Apple are fairly obvious; the biggest downside is -the cost. If anything, it might spare us the boring quarterly -routine of analysts expecting soft iPhone sales and then being -shocked when the company beats to the upside.

- -

If Apple passes on Netflix, don’t be surprised if Amazon does not. -That alone is reason to make the purchase.

-
- -

Usually when someone proposes Apple make a huge acquisition, I hurt my eyes by rolling them so far back in my head. I remain unconvinced that Apple should buy Netflix, but I don’t roll my eyes at the notion.

- -

I think the main problem is that there’s nothing magical about Netflix. Surely Apple could buy HBO for less money than Netflix would cost, and I would put HBO’s original content up against Netflix’s any day. I also think it’s a mistake to underestimate Apple’s ability to build its own first-class original content streaming service based on the crappy shows it’s released to date. A couple of more deals like the Amazing Stories one with Steven Spielberg and they’ll already have a foot in the game — for way less than the $100 billion it would take to buy Netflix.

- -

And, just as I was about to publish this post, this just in: Apple has announced a deal for a two-season scripted TV series starring Jennifer Aniston and Reese Witherspoon as competing morning TV show hosts, with House of Cards producer Jay Carson writing the pilot and serving as showrunner.

- -

Ritholtz (and others, like Om Malik and Ben Thompson) argue that Apple’s incredible cash hoard would allow them to make an expensive acquisition like Netflix. My argument is that Apple’s cash hoard would allow them to outbid the competition for the best new shows. Make Apple Studios the place where top notch talent takes new pitches first, knowing they’ll get paid top dollar and treated well. The trick isn’t the money — the trick is hiring the right executives to identify the best new shows.

- -
- - -
-Logitech Will Brick Its Harmony Link Hub for All Owners in March  -
-
-

Chris Welch, reporting for The Verge:

- -
-

Logitech has announced that it’s shutting down all services for -the Harmony Link hub, a plastic puck the company released in 2011 -that gave smartphones and tablets the ability to act as universal -remotes for thousands of devices.

- -

Owners of the product have received an email from the company -warning that the Link will completely stop working in March. “On -March 16th, 2018, Logitech will discontinue service and support -for Harmony Link. Your Harmony Link will no longer function after -this date,” the email says. There’s no explanation or reason given -as to why service is ending in the email, but a Logitech employee -provided more details on the company’s forums. “There is a -technology certificate license that will expire next March. The -certificate will not be renewed as we are focusing resources on -our current app-based remote, the Harmony Hub.”

-
- -

This sucks, but it seems like the way of the future with cloud-backed products. In the old days, products stopped working when they broke. Now, they stop working when the company that sold them loses interest in continuing to support them. It feels spiteful. More than ever, it matters how much you trust the company from which you buy stuff.

- -
- - -
-Apple at Its Best  -
-
-

Ben Thompson, writing at Stratechery:

- -
-

In these instances the iPhone X is reaching the very pinnacle of -computing: doing a necessary job, in this case security, better -than humans can. The fact that this case is security is -particularly noteworthy: it has long been taken as a matter of -fact that there is an inescapable trade-off between security and -ease-of-use; TouchID made it far easier to have effective security -for the vast majority of situations, and FaceID makes it -invisible.

- -

The trick Apple pulled, though, was going beyond that: the first -time I saw notifications be hidden and then revealed (as in the -GIF above) through simply a glance produced the sort of -surprise-and-delight that has traditionally characterized Apple’s -best products. And, to be sure, surprise-and-delight is -particularly important to the iPhone X: so much is new, -particularly in terms of the interaction model, that frustrations -are inevitable; in that Apple’s attempt to analogize the iPhone X -to the original iPhone is more about contrasts than comparisons.

-
- -

“Surprise and delight” are intangibles. You can’t measure them with a benchmark or instrument. There are contingents of hardcore power user and open source nerd types who disdain surprise and delight as product attributes — and no surprise, those are the folks who seem to be dismissing iPhone X as a cynical cash grab.

- -
- - -
-Steven Soderbergh’s ‘Mosaic’  -
-
-

Angela Watercutter, writing for Wired:

- -
-

Where they ended up was a smartphone-enabled story, developed and -released by Silver’s company PodOp, that lets viewers decide which -way they want to be told Mosaic’s tale of a children’s book -author, played by Sharon Stone, who turns up dead in the idyllic -ski haven of Park City, Utah. After watching each segment — some -only a few minutes, some as long as a standard television episode -— viewers are given options for whose point of view they want to -follow and where they want to go next. Those who want to be -completest and watch both options before moving on can do so, -those who want to race to find out whodunit can do that too. -Because each node, filmed by Soderbergh himself, feels like a TV -show, launching Mosaic can be akin to sneaking a quick show on -Netflix while commuting to work or waiting on a friend; but -because it’s a long story that’s easily flipped through, it can -also be enjoyed like the pulpy crime novel on your nightstand, -something you chip away at a little bit at a time before bed.

-
- -

This sounds fantastic, especially in the hands of someone as innovative and talented as Soderbergh. iOS-only (for now?), but that includes Apple TV.

- -
- - -
- - -
-
-iPhone X 4K Video vs. the Panasonic GH5 Professional Video Camera  -
-
-

Impressive side-by-side comparison. The Panasonic GH5 sells for $2000 for the body only, and costs around $2800 with a lens. The iPhone X camera largely held its own in outdoor lighting.

- -
- - -
-Apple to Release Software Update to Solve iOS 11 Issue When Typing the Letter ‘i’  -
-
-

Benjamin Mayo, writing for 9to5Mac:

- -
-

Some iPhone and iPad users are facing a weird bug after updating -to iOS 11.1. When trying to type the lowercase letter ‘i’, -autocorrect replaces the word with the letter ‘A’ and a question -mark symbol.

- -

Apple has documented steps for a workaround fix until a real -bug-fix software update is released …

-
- -

Such a weird bug — and embarrassing for Apple because it makes the device look so dumb. What I’ve heard is that this is a machine learning problem — that, more or less, for some reason the machine learning algorithm for autocorrect was learning something it never should have learned.

- -
- - -
- -
- - -
-

iPhone X Review Roundup

- - -

Because I’ve only had about 24 hours with the iPhone X, I’m in no position to write a review yet. But my quick take:

- -
    -
  • Face ID works great. In practice it’s like not even having a passcode on the phone. You just swipe and you’re in. It’s also very quick to set up — way quicker than setting up even a single fingerprint in Touch ID.
  • -
  • I don’t really notice the notch while using it.
  • -
  • I do notice the lack of a home button. I think I’ll get used to the new no-home-button UI soon, but 10 years of habits die hard.
  • -
  • The device feels great.
  • -
- -

I was far from alone in not getting an extended period of time to test the phone before the review embargo lifted.

- -

Here’s what others are saying in their reviews.

- -

Matthew Panzarino used iPhone X for a week, and stress-tested it with a family trip to Disneyland. (He did the same thing with the iPhone 6 and 6 Plus three years ago — it’s a great conceit for a review.) He also got on-the-record interviews with Phil Schiller, Dan Riccio, Craig Federighi, and Alan Dye. Riccio flatly denied reports that Apple was scrambling to get Touch ID working with iPhone X:

- -
-

“I heard some rumor [that] we couldn’t get Touch ID to work -through the glass so we had to remove that,” Riccio says, -answering a question about whether there were late design -changes. “When we hit early line of sight on getting Face ID to -be [as] good as it was, we knew that if we could be successful we -could enable the product that we wanted to go off and do and if -that’s true it could be something that we could burn the bridges -and be all in with. This is assuming it was a better solution. -And that’s what we did. So we spent no time looking at -fingerprints on the back or through the glass or on the side -because if we did those things, which would be a last-minute -change, they would be a distraction relative to enabling the more -important thing that we were trying to achieve, which was Face ID -done in a high-quality way.”

-
- -

Panzarino, on the iPhone X’s OLED display:

- -
-

I hate to say it, but it makes the iPhone 8 Plus LCD look kind -of like butt. I love it, even though it is flawed in one -noticeable way.

- -

The one area where this display falls prey to standard OLED gripes -is in off-axis viewing. Apple tells me that it has done work to -counter the drop in saturation and shift to blue that affects OLED -screens traditionally. I can tell you that, compared to other OLED -screens, you have to get further “off of center” to see a real -shift in color, holding the phone 30 degrees or more off of dead -on. But it is still there. For people who share their phone’s -screen or use it at odd angles a lot, it will be noticeable. On -some phones, OLEDs go super blue. On the iPhone X it’s more of a -slight blue shift with a reduction in saturation and dynamic -range. It’s not terrible, but it definitely exists.

-
- -

I see the same thing with mine.

- -

Nicole Nguyen also used iPhone X for a week and wrote a great review for BuzzFeed:

- -
-

Whatever. I don’t feel strongly about the notch either way, but -it’s really the other end of the screen that feels awkward. It’s -when the keyboard, in any app, is on screen (which, for me, is -most of the time): There’s all this dead space on the bottom, -where Apple could have put common punctuation, frequently used -emojis, or literally anything, but instead left it blank. Other -full-screen apps on other phones put navigation or other design -elements in that area, and it doesn’t look crowded or crammed. It -looks fine. It’s puzzling why Apple didn’t put something more -useful down at the bottom, or why it didn’t add a row of numbers -or emojis up top and push down the keyboard to make it more -thumb-accessible.

-
- -

It does look like a waste of space, but I wonder if testing showed that there needs to be some space under the keyboard to separate it from the virtual home button? If there weren’t a gap under the keyboard, you might hit the home button while trying to hit the space bar, and vice versa. Update: I’ve heard from a little birdie that my speculation is correct; also: it’s about typing comfort.

- -
-

For a normal human who isn’t aware of the 30,000 invisible dots -being projected on their face or the 3D map of their head -encrypted somewhere deep inside their phone, there’s nothing -“futuristic” about these interactions. Using Face ID is what life -without a passcode — life before we all became paranoid -technofreaks — felt like.

-
- -

That’s my take too. It’s like not having a passcode set.

- -

Lance Ulanoff, in his review for Mashable:

- -
-

During my first 24 hours of using the iPhone X, I helplessly -pressed the space where a button should be. It’s a kind of Phantom -Home Button Syndrome that I expect all iPhone X owners will -experience in the early days.

- -

It fades, though, and rather quickly, thanks to a smartly designed -gesture interface and something Apple calls Face ID. […]

- -

One important limitation of Face ID: It only lets you register one -face. That may strike many as unnecessarily limiting since Touch -ID lets users register up to 10 fingerprints, but Apple says it -found the number of people who register more than one person’s -fingerprints is miniscule. There’s also the simple and obvious -fact that humans have 10 fingers, but just one face.

-
- -

I’m surprised it’s only a minuscule number. I’ve got a fingerprint registered on my son’s iPhone — I’m sure other parents do the same thing. And last week my wife let me put a fingerprint on her iPhone so I could use Apple Pay while pre-ordering her iPhone X while she slept. 

- -
- -
- - -
-

Face ID FUD

- - -

Seemingly-sensational Apple story from Bloomberg today, reported by Alex Webb and Sam Kim, “Inside Apple’s Struggle to Get the iPhone X to Market on Time”:

- -
-

As of early fall, it was clearer than ever that production -problems meant Apple Inc. wouldn’t have enough iPhone Xs in time -for the holidays. The challenge was how to make the sophisticated -phone — with advanced features such as facial recognition — in -large enough numbers.

- -

As Wall Street analysts and fan blogs watched for signs that the -company would stumble, Apple came up with a solution: It quietly -told suppliers they could reduce the accuracy of the -face-recognition technology to make it easier to manufacture, -according to people familiar with the situation.

-
- -

That sounds terrible. But what exactly does it mean? Does it mean Face ID will create too many false positives? Does it mean it will be too slow? Does it mean there will be too many false negatives? Surprise surprise, Bloomberg doesn’t say.

- -
-

Apple is famously demanding, leaning on suppliers and contract -manufacturers to help it make technological leaps and retain a -competitive edge. While a less accurate Face ID will still be far -better than the existing Touch ID, the company’s decision to -downgrade the technology for this model shows how hard it’s -becoming to create cutting-edge features that consumers are -hungry to try.

-
- -

“Downgraded technology” sounds terrible. But which components, exactly, were “downgraded”?

- -
-

Apple spokeswoman Trudy Muller said “Bloomberg’s claim that it -reduced the accuracy spec for Face ID is completely false and we -expect Face ID to be the new gold standard for facial -authentication. The quality and accuracy of Face ID haven’t -changed; it continues to be one in a million probability of a -random person unlocking your iPhone with Face ID.”

-
- -

It is extraordinary for Apple to issue a blanket “this is completely false” statement on any news story. Apple, as policy, no-comments every news story, even when they know it’s bullshit. So either this story is particularly strong bullshit, or Apple is lying, on the record, under an employee’s real name (as opposed to the anonymous “an Apple spokesperson” attribution).

- -

And what exactly is the point of Bloomberg’s story if, as reported, “Face ID will still be far better than the existing Touch ID”?

- -
-

To make matters worse, Apple lost one of its laser suppliers early -on. Finisar Corp. failed to meet Apple’s specifications in time -for the start of production, and now the Sunnyvale, -California-based company is racing to meet the standards by the -end of October. That left Apple reliant on fewer laser suppliers: -Lumentum Holdings Inc. and II-VI Inc.

-
- -

Apple didn’t “lose” a supplier — Apple cut the supplier because they weren’t producing adequate yields.

- -
-

To boost the number of usable dot projectors and accelerate -production, Apple relaxed some of the specifications for Face ID, -according to a different person with knowledge of the process. As -a result, it took less time to test completed modules, one of the -major sticking points, the person said.

- -

It’s not clear how much the new specs will reduce the technology’s -efficacy.

-
- -

Now we get to the real heart of the story. Did Apple adjust the specifications for the components, or just the testing parameters? And if “it’s not clear how much the new specs will reduce the technology’s efficacy”, what is the point of this story? When did Apple “relax” these specifications? Before or after the September event?

- -

To be clear, I have no idea whether Face ID works as advertised or not. I haven’t used it even once yet. Maybe it stinks, maybe it’s great, maybe it’s somewhere in between. But Bloomberg clearly doesn’t know either, yet they published this story which has a headline and summary — “The company let suppliers reduce accuracy of the phone’s Face ID system to speed up production” — which suggests that Face ID is going to stink because Apple’s suppliers couldn’t get enough good components out the door. If this weren’t merely clickbait, they’d be able to say how well it actually works.

- -
- -

Frankly, I don’t trust anything Bloomberg reports about iPhones any more. On July 3, they published this piece by Mark Gurman, “Apple Tests 3-D Face Scanning to Unlock Next iPhone”:

- -
-

Apple Inc. is working on a feature that will let you unlock your -iPhone using your face instead of a fingerprint.

- -

For its redesigned iPhone, set to go on sale later this year, -Apple is testing an improved security system that allows users to -log in, authenticate payments, and launch secure apps by scanning -their face, according to people familiar with the product. This is -powered by a new 3-D sensor, added the people, who asked not to be -identified discussing technology that’s still in development. The -company is also testing eye scanning to augment the system, one of -the people said.

- -

The sensor’s speed and accuracy are focal points of the feature. -It can scan a user’s face and unlock the iPhone within a few -hundred milliseconds, the person said. It is designed to work even -if the device is laying flat on a table, rather than just close up -to the face. The feature is still being tested and may not appear -with the new device. However, the intent is for it to replace the -Touch ID fingerprint scanner, according to the person. An Apple -spokesman declined to comment.

-
- -

Apple did in fact replace Touch ID with Face ID in the iPhone X, but the timing on Gurman’s story is wrong. They weren’t “testing” the viability of any of this in July. According to several trusted sources within Apple, including multiple engineers who worked directly on the iPhone X project, the decision to go “all-in on Face ID” (in the words of one source) was made over a year ago. Further, the design of the iPhone X hardware was “locked” — again, a source’s word — prior to January 2017. If I had to wager, I’d say it was locked a few months before the end of 2016. This was a nine-month-old decision that Bloomberg reported in the present tense.

- -

Beyond Bloomberg, there are the slew of reports from various “analysts” that suggested Apple was still working to incorporate Touch ID into the iPhone X display as late as this summer.

- -

Ming-Chi Kuo in January:

- -
-

In a note sent out to investors on Friday, and subsequently -obtained by AppleInsider, well-connected KGI analyst Ming-Chi Kuo -says he believes Apple is developing a new class of -bio-recognition technologies that play nice with “full-face,” or -zero-bezel, displays. Specifically, Kuo foresees Apple replacing -existing Touch ID technology with optical fingerprint readers, a -change that could arrive as soon as this year, as Apple is widely -rumored to introduce a full-screen OLED iPhone model this fall.

-
- -

By January, there were no plans to embed an “optical fingerprint reader” in the display of any Apple device this year. Apple did, of course, investigate ways to embed Touch ID sensors in edge-to-edge displays, but, again, those efforts were abandoned in favor of Face ID over a year ago.

- -

Cowen and Company analyst Timoth Arcuri, on June 21 (of this year), under the AppleInsider headline “Apple Still Undecided on Fingerprint Tech for ‘iPhone 8’, No Shipments Until October”:

- -
-

The OLED-embedded fingerprint technology for Apple’s “iPhone 8” -is “still being worked out,” an analyst claimed on Wednesday, -with the company only deciding on one of three options by the end -of June.

- -

The one settled point appears to be that there won’t be a sensor -on the back of the phone, Cowen and Company’s Timothy Arcuri -indicated in a memo obtained by AppleInsider. The three options -include thinning the cover glass over a sensor area, creating a -pinhole through the glass for an optical or ultrasonic sensor, or -trying a “film” sensor integrated into the display, using either -capacitive or infrared technology.

-
- -

This, it turns out, was complete nonsense. Again, Apple was “all-in” on Face ID over a year ago. The idea that they were still “working this out” in June is a joke.

- -

And back to Ming-Chi Kuo, in August:

- -
-

Apple has decided against an embedded Touch ID solution for its -forthcoming “iPhone 8” handset, according to well-connected -analyst Ming-Chi Kuo, leaving the door open for competitor Samsung -to debut similar technology in next year’s Galaxy Note 9.

- -

In a note to investors obtained by AppleInsider, Kuo says Apple -has “cancelled” plans to embed a fingerprint recognition solution -in the next-generation flagship iPhone. The analyst left embedded -Touch ID off a list of standout “iPhone 8” features published in -July, but did not indicate that Apple had abandoned the initiative -altogether.

-
- -

As with Gurman’s report in June, the problem here is with the timing, not the facts. By August of this year, this was a nearly year-old decision.

- -

The Wall Street Journal, in a September 7 report attributed to reporters “Yoko Kubota in Tokyo, Tripp Mickle in San Francisco, and Takashi Mochizuki in Tokyo”:

- -
-

The production delays earlier this summer stemmed in part from -Apple’s decision to build new phones using organic light-emitting -diode, or OLED, screens similar to those used by rival Samsung -Electronics Co. At the same time, Apple decided to ditch the -physical home button that contains fingerprint sensors for -unlocking the device. Apple tried to embed the Touch ID function, -or fingerprint scanner, in the new display, which proved -difficult, the people familiar with the process said.

- -

As deadlines approached, Apple eventually abandoned the -fingerprint scanner, the people said, and users will unlock the -phone using either an old-fashioned password or what is expected -to be a new facial-recognition feature. Nonetheless, precious time -was lost and production was put back by about a month, according -to people familiar with the situation.

-
- -

I quote the two Tokyo datelines in the byline because I don’t think this information came from Apple. Again, my sources at Apple, directly familiar with the decision, have told me that they chose Face ID over a year ago because they were convinced it was better than Touch ID. Touch ID was not abandoned because it was difficult to embed in the display.

- -

For good measure while I’m pouring out the claim chowder, here’s Zach Epstein, writing for BGR on July 20, “I Might Know the Truth About Touch ID on Apple’s iPhone 8” (note that the device he refers to as “iPhone 8” is the iPhone X):

- -
-

I have now received information from three different well-placed -sources over the past few weeks, and they have all told me the -same thing: The iPhone 8’s Touch ID fingerprint sensor is in the -power button.

- -

The news first came to me about a month ago from a source I know -well. I’ve since been told the same thing by two additional -sources I haven’t known for quite as long. All three sources have -provided information to me in the past that has proven to be -accurate.

-
- -

That’s a lot of “well-placed sources” for a bullshit story.

- -
- -

All of this fits with what I’ve heard from rank-and-file engineering sources within Apple for years. To wit, producing hardware at the iPhone’s scale, while pushing the boundaries of the industry in technology, is so difficult, so complicated, that it requires hardware designs to be locked down far in advance of when iPhones are actually announced and released. Apple’s iPhone hardware engineering teams did not spend 2017 working on the iPhone X and iPhone 8 — they spent this year working on new iPhone hardware for 2018 and 2019 (and perhaps beyond). Hardware is nothing like software. If Apple had really been dithering over Touch ID-embedded-in-the-display vs. Face ID in June of this year, iPhone X wouldn’t be hitting the market until 2018. And the final decisions on the hardware for the iPhones that will be debuting next year are being made right now.

- -

So where do these rumors come from? I don’t know. My guess is that if there’s an intent behind them, it’s that competitors (cough, Samsung?) within the Asian supply chain are attempting to sow doubt about Face ID. The narrative presented by analysts and certain news reports this summer was that Apple was still scrambling to get Touch ID working embedded within the iPhone X display, suggesting that Face ID was their Plan B.

- -

People are naturally skeptical about biometric ID systems. They were skeptical about Touch ID when it was still only rumored, just like they’re skeptical now about Face ID. Today, though, Touch ID is both trusted and familiar. So rumors claiming that Apple really wanted to get Touch ID into iPhone X but had to settle for Face ID play into both the skepticism of the new and the comfort of the familiar. FUD is one of the oldest tricks in the book.

- -

The other, simpler explanation is that it simply takes 9 months or longer for engineering decisions made within Apple to percolate out to the rumor reporters and analysts — and their sources are so far removed from the halls of Cupertino that they mistake old news for new news. 

- -
- -
- - - - - - - - - - -
- -
- - - diff --git a/Frameworks/FeedFinder/FeedFinderTests/Resources/furbo.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/furbo.html deleted file mode 100644 index 969d3f121..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/Resources/furbo.html +++ /dev/null @@ -1,372 +0,0 @@ - - - - - - - - - - - - - - - - furbo.org by Craig Hockenberry - - - - - - - - - - - - - -
- - - - -
-
- - - -
- -
-
- - - - - - -
- -
-

The Forensic Shit Show

- -
-

It turns out someone at the FBI advised another law enforcement officer in San Bernardino to reset the iPhone that the government wants Apple to unlock.

-

This is just another episode in a complete forensic shit show.

-

Remember, this is the same case where the media was allowed to roam freely through a crime scene. One of the photos in that gallery shows a computer without an Ethernet connection on the wall (the age of the apartment also suggests that there would be no wired Internet.)

-

What are the chances that there was a wireless network in that apartment? What are the chances that there are IP logs on that router? Or maybe some kind of data backed up to a disk on the router? Here’s another wild guess: maybe that router was used to connect to an online backup service.

-

Yep, someone did the equivalent of a “restore factory defaults” on a device under active investigation.

-

What we’re seeing here is law enforcement’s complete lack of understanding of how digital devices store and transmit data. This new evidence is much more intricate than smoking guns or blood splatters. The important stuff is what you don’t see: it’s a hard problem where the people dealing with it are untrained. Shit, I work in this business and trying to decipher what’s going on makes my head spin.

-

Yet law enforcement is asking Apple to not only provide data, but also to create a forensic instrument that allows them to extract information from any device. And by its very nature, this tool would be made widely available throughout the forensic and law enforcement community.

-

Basically, the government is asking Apple to hand over a golden key that can defeat the security of any device to folks that can’t even secure a wireless network. Worse, this whole process is being overseen by politicians that think the problem is predators getting access to their grandkid’s Playstation.

-

This is why the entire tech community is saying “No fucking way.”

-

Updated February 21st, 2016: Several people have commented about my use of “restore factory defaults” in the post above. My intention was figurative, not literal.

-

The folks involved with the investigation were pressing buttons without understanding the consequences of their actions. To me, it feels like a “reboot to fix” approach. The password reset did not damage any data, it just made automatic backups stop working because iCloud information on the device needed to be updated, and that can’t be done without a passcode.

-

Others have reminded me that the FBI had cleared the crime scene. That’s true, but since the Wi-Fi equipment was not collected as evidence, it still shows that the investigators were out of their league. In an electronic investigation, a router is a key piece of the puzzle.

-

Both of these things are details in a bigger picture: the FBI wants to hold the private keys to a public key encryption system that affects the privacy of hundreds of millions people. If they can’t get the details of an online backup service right, how the hell do we expect them to guard a back door?

-

There’s also a possibility that the iCloud password reset was intentional. If this is the case, we have a government that is extorting Apple by essentially planting evidence. Imagine what they could do with a private key.

-
- - - -
- -
- -
-

Strapped In

- -
-

A lot has happened since I purchased my Apple Watch on April 10th, 2015. One unexpected aspect to owning this device is my fascination with watch bands:

-
-Apple Watch Bands

-
My current collection of watch bands. And no, the watch isn’t upside down.
-
-

From left to right, in order of date purchased:

-
    -
  • -Sport Model with Blue Band ($400) – I picked the aluminum watch with a blue band because I knew it would be spending a lot of time in the water. To date, I’ve used it 110 times for over 35 hours of swimming. -
  • -
  • -Milanese Loop ($150) – I was intrigued by this band as soon as I saw it during the video at the product announcement. I love how the metal feels a lot like fabric. It also dresses up the utilitarian Sport model so it doesn’t look out of place when I’m someplace nice. -
  • -
  • -Black & Silver Nylon ($30) – This NATO-style band from Clockwork Synergy popped up on my Twitter timeline thanks to my pal Rob Rhyne. I love that it dresses up the watch and is waterproof. -
  • -
  • -Red Sport ($50) – When Apple started selling additional colors for the sport bands, getting one in my favorite color was a no-brainer. I also like that a little of my purchase goes to a worthwhile charity. -
  • -
  • -Orange Silicone ($20) – This band by MoKo was another recommendation from Twitter by Neven Mrgan. To me, the most interesting thing about this band is that it shows why Apple went with fluoroelastomer for their bands: it’s stiffer and “breathes” better than silicone. -
  • -
  • -Black Goat Leather ($200) – The leather bands from Apple are nice, but I prefer the classic look of this one from Lucrin. The company also offers a huge range of colors: my wife loves the dark green one I gave at Christmas. -
  • -
-

In this survey of my growing collection, there’s an interesting datapoint: the value of these bands ($450) exceeds the cost of the watch itself ($400).

-

If Apple decides to change the interchange mechanism in some future version of the watch, I will have very little desire to upgrade. As I continue to “work in” my leather band, I hope I’ll be using them for a long time.

-
- - - -
- -
- -
-

The New iPod

- -
-

Something tells me that there were a lot of Apple Watches under the tree this year:

-

Clicker Downloads for December 2015

-

That graph shows the last month of downloads for my free Clicker app for watchOS. Since this app does nothing on an iPhone or iPad, the only reason to get it is if you have a new watch.

-

Many of us, myself included, originally thought of the Apple Watch as a device in and of itself. But the more I use the computer on my wrist, the more it feels like a satellite to the computer that’s sitting in my pocket.

-

Accessories have always made great gifts for folks who love their computers. Giving the watch as a gift is a perfect option for someone who’s always playing around with the apps on their iPhone. Just like the iPod was an ideal match for someone who loved playing music on their desktop computer.

-
- - - -
- - - -
- -
-

A Responsive Factory

- -
-

Back in May 2014, we introduced a new Iconfactory home page. One of the main design goals for that site was to make the layout a responsive web design: the same site looked great whether you were looking at it on a desktop PC or an iPhone. Reading Ethan Marcotte’s book was a revelation.

-

Of course, that site was just a beginning. We run a lot of web sites (including some you’ve probably never heard of before). Clearly we had to pick our responsive battles.

-

We started with an update to our blog in January 2015. In October, we updated our iOS and OS X app catalog. And yesterday we launched a responsive design portfolio.

-

A year and a half after our first responsive design, we’ve hit a milestone. All of the sites listed in the Iconfactory’s red navigation bar are responsive designs and will display correctly on any device. Woo hoo!

-

Along the way, we cleaned up some of our branding elements and worked toward a more consistent experience across all the sites. Check out the post at the Iconfactory about the new SVG icons in Safari to see what that’s all about.

-

It’s clear we’re at a point in time where the vast assortment of screens is daunting. If you haven’t thought about how your site works on this wide variety of devices, now is a great time to start.

-
- - - -
-
- -
- -
-
- - -
- -
-
-
- - -
-
-
- -
- - - - - - - - - - - \ No newline at end of file diff --git a/Frameworks/FeedFinder/FeedFinderTests/Resources/indiestack.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/indiestack.html deleted file mode 100644 index 017a438d3..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/Resources/indiestack.html +++ /dev/null @@ -1,715 +0,0 @@ - - - - - - - - - - Indie Stack | Hacking the Mac, iOS, and more with Daniel Jalkut - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
-
- - -
-
- -

- Treat Warnings as Errors in Swift -

- - -
- -
-

For years I have maintained a zero-tolerance policy for warnings in shipping code. To help me enforce this, my “Release” build configurations define the build setting that induces Xcode to “treat warnings as errors”:

-
GCC_TREAT_WARNINGS_AS_ERRORS = YES
-
-

The comedy of this build setting is that it references “GCC,” a compiler that increasingly few of us even remember Apple ever using for macOS or iOS development. Apple’s fork of the popular open-source compiler was the standard for years, until Apple debuted clang, which is built on the LLVM framework.

-

It’s always been kind of annoying that, as time moved on, we were stuck specifying important build settings with names that included “GCC,” but I accepted it. After all, I configure the vast majority of these settings in “.xcconfig” files that I reuse in all my projects, so I almost never interact with them directly.

-

As I’ve started to shift some of my code from Objective-C to Swift, I assumed that my ancient GCC build setting would ensure that I don’t ship any builds with warnings. But today I realized that I had built a release build that didn’t treat a warning as an error. What’s the deal?

-

It looks like Apple has decided to break with tradition and establish a new build setting for Swift:

-
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES
-
-

Adding this to my .xcconfig file breaks the build when a warning is generated, and prevents me from accidentally shipping code that is known to be vulnerable to unexpected behavior. I think it would have been a nice touch if Apple had inferred SWIFT_TREAT_WARNINGS_AS_ERRORS when GCC_TREAT_WARNINGS_AS_ERRORS is set, so I’ve filed a bug requesting that it does. Radar #35352318.

-
- -
- -
-
- -
-
- -

- Selective Selector Mapping -

- - -
- -
-

I ran into an interesting challenge while porting some Objective-C code to Swift. The class in question served both as an NSTableView delegate and data source, meaning that it implemented methods both for controlling the table view’s behavior and for supplying its content.

-

Historically in Cocoa, most delegate relationships were established as informal protocols. If you wanted a particular class to be a table view data source, you simply implemented the required methods. For example, to populate a cell based table view, a data source would implement various methods, including one to indicate how many rows the view should have:

-
-- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView;
-
-

In recent years, Apple has increasingly converted these informal protocols to formal Objective-C protocols. These give the compiler the opportunity to generate errors if a particular class declares compliance, but neglects to implement a required method. At runtime, however, the compliance-checking is still pretty loose. NSTableView consults its data source, checks to see that it implements a required subset of methods, and dynamically dispatches to them if it does.

-

The dynamic nature of NSTableView hasn’t changed with Swift. An @objc class in Swift that complies with NSTableViewDataSource must still implement the required methods such that Apple’s Objective-C based NSTableView can dynamically look up and dispatch to the required delegate methods. Swift’s method rewriting “magic” even ensures that a delegate method can be written in modern Swift style, yet still appear identically to older Objective-C code:

-
-class MyDataSource: NSObject {
-	@objc func numberOfRows(in tableView: NSTableView) -> Int {
-		return 0
-	}
-}
-
-

Given an instance of MyDataSource, I can use the Objective-C runtime to confirm that a the legacy “numberOfRowsInTableView:” selector is actually implemented by the class above:

-
-let thisSource = MyDataSource()
-thisSource.responds(to: Selector("numberOfRowsInTableView:")) // false
-
-

Or can I? False? That’s no good. I’m using the discouraged “Selector” initializer here to ensure I get Swift to look for a very specific Selector, even if it doesn’t appear to be correct to the Swift-adapted side of the runtime.

-

I was scratching my head, trying to figure out why Objective-C could not see my method. Did I forget an @objc marker? No. Did I forget to make MyDataSource a subclass of NSObject? No. I finally discovered that I could second-guess the default Swift selector mapping to obtain a result that “worked”:

-
-class MyDataSource: NSObject {
-	@objc func numberOfRowsInTableView(_ tableView: NSTableView) -> Int {
-		return 0
-	}
-}
-
-let thisSource = MyDataSource()
-thisSource.responds(to: Selector("numberOfRowsInTableView:")) // true
-
-

Instances of MyDataSource will get the job done for Objective-C calls to “numberOfRowsInTableView:”, but I’ve lost all the pretty formatting that I expected to be able to use in Swift.

-

There’s something else I’m missing out in my Swift implementation: type checking of MyDataSource’s compliance with the NSTableViewDataSource protocol. Old habits die hard, and I had initially ported my class over with an old-fashioned, informal approach to complying with NSTableViewDataSource: I declared a plain NSObject that happens to implement the informal protocol.

-

It turns that adding that protocol conformance onto my class declaration not only gains me Swift’s protocol type checking, but changes the way key functions are mapped from Swift to Objective-C:

-
-class MyDataSource: NSObject, NSTableViewDataSource {
-	func numberOfRows(in tableView: NSTableView) -> Int {
-		return 0
-	}
-}
-
-let thisSource = MyDataSource()
-thisSource.responds(to: Selector("numberOfRowsInTableView:")) // true
-
-

Armed with the knowledge that my class intends to comply with NSTableViewDataSource, Swift generates the expected mapping to Objective-C. Notice in this final case, I don’t even have to remember to mark the function as @objc. I guess when Swift is creating the selector mapping for a function, it does so in a few phases, prioritizing more explicit scenarios over more general:

-
    -
  1. First, it defers to any explicit annotation with the @objc attribute. If I tag my “numberOfRows…” func above with “@objc(numberOfDoodads:)” then the method will be made available to Objective-C code dynamically looking for “numberOfDoodads:”.
  2. -
  3. If there’s no @objc specialization, it tries to match function implementations with declarations in superclasses or protocols the class complies with. This is what gives us the automatic mapping of Swift’s “numberOfRows(in:)” to Objective-C’s “numberOfRowsInTableView:”.
  4. -
  5. Finally it resorts to a default mapping based on Swift API Design Guidelines. This is what yielded the default “numberOfRowsIn:” mapping that I first encountered.
  6. -
-

This is an example of a Swift growing pain that is particularly likely to affect folks who are adapting older source bases (and older programming mindsets!) to Swift. If you run across a completely vexing failure of Objective-C to acknowledge your Swift class’s protocol compliance, start by making sure that you’ve actually declared the compliance in your class declaration!

-
- -
- -
-
- -
-
- -

- Swatch Your Step -

- - -
- -
-

Shortly after macOS 10.13 was released, I received an oddly specific bug report from a customer, who observed that the little square “swatches” in the standard Mac color panel no longer had any effect on MarsEdit’s rich text editor.

-

Screenshot of the macOS standard color panel.

-

I was able to reproduce the problem in the shipping 3.7.11 version of MarsEdit, which for various reasons is still built using an older version of Xcode, against the 10.6 SDK. The MarsEdit 4 Beta, which is built against the 10.12 SDK, does not exhibit the problem.

-

It’s not unusual for the behavior of Apple’s frameworks to vary based on the version of SDK an application was built against. The idea is usually to preserve the old behaviors of frameworks, so that any changes do not defy the expectations of a developer who has not been able to build and test their app against a later SDK. Sometimes, the variations in behavior lead to bugs like this one.

-

Using a totally straightforward demo app, consisting only of an NSTextView and a button to bring up the color panel, I was able to confirm that the bug affects an app that links against the macOS 10.9 SDK, but does not affect an app that links against the 10.10 SDK.

-

I filed Radar #34757710: “NSColorPanel swatches don’t work on apps linked against 10.9 or earlier.” I don’t know of a workaround yet, other than compiling against a later SDK.

-
- -
- -
-
- -
-
- -

- Xcode 9 Signing Workarounds -

- - -
- -
-

I wrote on Monday about issues with Xcode 9 relating to code signing. Although the gist of that post involved sandboxed Mac applications that launch sandboxed child processes, the fundamental issue is a bit broader: Xcode 9 adds a “com.apple.security.get-task-allow” entitlement to any binary it signs. For the majority of developers, this is probably not an issue, because the entitlement is removed when an Xcode archive is exported for distribution. Most developers, and particularly iOS developers, use Xcode archives.

-

For folks who don’t, side effects of this additional entitlement include, but may not be limited to:

-
    -
  1. Inability to launch sandboxed child processes.
  2. -
  3. Rejection from the Mac App Store.
  4. -
  5. Unknown consequences of shipping with an unintended entitlement.
  6. -
-

So, if you’re a developer who doesn’t use archives, what are your options? I’ve come up with four workarounds, and I present them here, roughly sorted by advisability and level of tedium:

-
    -
  1. -

    Use Xcode 8. The simplest solution is to not upgrade to Xcode 9 unless and until you need to. Xcode 8’s signing process does not impose the unintended entitlement, so there is no risk of shipping a product that has it, unless you add it yourself. The downside to sticking with Xcode 8 is you won’t enjoy any of the new features of Xcode 9, you’ll have to work to support either Swift 4, macOS 10.13, or iOS 11 SDK features in your app.

    -
  2. -
  3. -

    Manually re-sign the built-product. Code signing is code signing, and you’re free to sign anything you like to suit your needs, using the “codesign” command line tool. It frankly sounds like a pain in the neck to recursively re-sign every binary in the app bundle, ensuring that the suitable entitlements (minus the unwanted one) are preserved, but I’m sure it can be done.

    -
  4. -
  5. -

    Use Xcode archives. It strikes me as a little obnoxious to have to use Xcode archives when they don’t offer any added benefits for my dibstrution workflow. But as a long term solution, this is probably the safest bet. The new behavior in Xcode 9 strongly suggests that Apple expects most developers to use archives, and joining the crowd is usually a good idea when it comes to avoiding trouble with Apple’s developer tools.

    -

    If you are using Xcode archives for the first time, particularly with a complex project, you might discover that the resulting archives are not suitable for exporting a signed application. If you get a “Generic Xcode Archive” after running Build -> Archive, you know you’ve got a problem. By default the archive process builds all targets with an “install” option, rendering their built products into a file hierarchy that will be used to build the archive. If your project includes helper apps, for example, they will be “installed” alongside your main app, resulting in a generic archive of two apps, instead of the expected archive of a single app.

    -

    The solution for this problem is to ensure that the “SKIP_INSTALL” build setting is set to YES for any such helper app. Just archive your main app, export the “Built Products” from the resulting archive, and look at the file hierarchy to determine whether you have subtargets that need to have installation disabled.

    -
  6. -
  7. -

    Hack Xcode 9. In a hurry to ship an update to your app, and you’ve only got Xcode 9 handy? It turns out the imposition of this “com.apple.security.get-task-allow” entitlement is controlled by a single property list file inside Xcode’s application bundle. As a test, I edited the file:

    -
    -Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/PrivatePlugIns/IDEOSXSupportCore.ideplugin/Contents/Resources/BaseEntitlements.plist
    -
    -

    It contains a single entitlement, the one that’s causing our grief. I deleted the entitlement from the list, saved the file, and relaunched Xcode. After doing so, everything is “back to normal.”

    -

    I can’t strongly encourage you to hack your copy of Xcode because I don’t know what the consequences might be. “It seems fine,” but you’re on your own if you decide to do this. -

  8. -
-

This small change in Xcode 9 causes a lot of unexpected grief for folks who don’t use Xcode archives. I am curious to know how widespread the problem is, and enthusiastic to get the word out about it so that affected folks can work around the problem, or at least be aware of it. Myself, I’ll probably end up adopting the workaround of using Xcode archives, but I’m hopeful that Apple will see the merit of providing an option in an update to Xcode 9 that supports disabling the addition of this entitlement without archiving and exporting a built product.

-
- -
- -
-
- -
-
- -

- Unordered Directory Contents -

- - -
- -
-

Since I updated to macOS 10.13 High Sierra, some of my unit tests broke. Examining the failures more carefully, I discovered that they were making assumptions about the order that Foundation’s FileManager.contentsOfDirectory(atPath:) would return items.

-

I wrote a quick playground to test the behavior on a 10.12 machine:

-
-import Foundation
-
-let array = try! FileManager.default.contentsOfDirectory(atPath: "/Applications/Utilities")
-print("\(array.debugDescription)")
-
-

The results come back alphabetically ordered by file name:

-
-[".DS_Store", ".localized", "Activity Monitor.app", "Adobe Flash Player Install Manager.app", "AirPort Utility.app", "Audio MIDI Setup.app", "Bluetooth File Exchange.app", "Boot Camp Assistant.app", "ColorSync Utility.app", "Console.app", "Digital Color Meter.app", "Disk Utility.app", "Grab.app", "Grapher.app", "Keychain Access.app", "Migration Assistant.app", "Script Editor.app", "System Information.app", "Terminal.app", "VoiceOver Utility.app"]
-
-

The same playground on 10.13 tells a different story:

-
-["AirPort Utility.app", "VoiceOver Utility.app", "Terminal.app", "Activity Monitor.app", ".DS_Store", "Grapher.app", "Audio MIDI Setup.app", ".localized", "System Information.app", "Keychain Access.app", "Grab.app", "Migration Assistant.app", "Script Editor.app", "ColorSync Utility.app", "Console.app", "Disk Utility.app", "Bluetooth File Exchange.app", "Boot Camp Assistant.app", "Digital Color Meter.app"]
-
-

I thought at first this might have been related to the APFS conversion that 10.13 applied to my boot volume, but the same ordering discrepancy occurs for items on my HFS+ volumes as well.

-

After checking the 10.13 release notes for clues, and finding none, I consulted the documentation. Well, what do you know?

-

The order of the files in the returned array is undefined.

-

So, mea culpa. The test code in question probably shouldn’t have ever made assumptions about the ordering of items returned from this method. While it has evidently always been undefined, it appears they are only making good on that promise in 10.13. You have been warned!

-

Update: It turns out I have some real bugs in my apps, not just in my tests, because of assuming the results of this call will be reasonably sorted. Luckily I use a bottleneck method for obtaining the list of files, and I can impose my own sorting right at the source. If you’re looking to make the same kinds of changes to your app, be sure to heed Peter Maurer’s advice and use “localizedStandardCompare” (available since macOS10.6/iOS4) to obtain Finder-like ordering of the results.

-
- -
- -
-
- -
-
- -

- Sandbox Inheritance Tax -

- - -
- -
-

I ran into a subtle bug with Xcode 9 that I think is worth sharing. Specifically, this bug affects Mac applications that:

-
    -
  1. Are sandboxed.
  2. -
  3. Launch a sandboxed subprocess with NSTask (or posix_spawn).
  4. -
  5. Configure the subprocess to inherit the parent’s sandbox.
  6. -
-

When such an app is compiled with Xcode 9, the subprocess will crash whenever the parent process launches it. A canonical example of something that might suffer from this problem is a bundled crash-monitor. I embed one with my apps to keep an eye on the running status of the parent process, and to present a crash-reporting interface to users if the host app terminates prematurely. When I build and run my app with Xcode 9, the bundled crash monitor dies instantly upon being launched.

-

It took me a while to realize that the subprocess is dying because it fails to satisfy the contract for inheriting a sandbox. From Apple’s “Enabling App Sandbox Inheritance“:

-

-To enable sandbox inheritance, a child target must use exactly two App Sandbox entitlement keys: com.apple.security.app-sandbox and com.apple.security.inherit. If you specify any other App Sandbox entitlement, the system aborts the child process. -

-

Well, that’s funny because my child process does specify only those two keys, but the system is aborting it anyway. It turns out that Xcode 9 is inserting a third entitlement without my permission. Clicking on the detail of the “Process Product Packaging” build phase in Xcode’s log navigator, I can see that there are three entitlements for my target:

-

Xcode build log detail showing the wrong entitlements.

-

When my subprocess is launched, the system sees that extra “com.apple.security.get-task-allow” entitlement in the context of “com.apple.security.inherit”, and unceremoniously crashes my the child process.

-

I’m not sure what Apple’s reasoning is for imposing this entitlement on sandboxed targets, but it appears to be doing so across the board, for literally every sandboxed target in my app. I confirmed that all of my apps, XPC processes, helper tools, etc., are all getting this bonus entitlement.

-

I searched Xcode’s files, and discovered the entitlement listed in this file inside the Xcode app bundle:

-
-Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/PrivatePlugIns/IDEOSXSupportCore.ideplugin/Contents/Resources/BaseEntitlements.plist
-
-

Putting aside the question of whether it’s appropriate for Xcode to surreptitiously add entitlements that are not specified by the developer’s own list of permissions, the addition of the entitlement for these particular targets, ones that inherit their parent’s sandbox, turns out to be a fatal move.

-

Ideally I would be able to work around this by adding a custom build phase to manually tweak the generated entitlements file, removing the unwanted key. But the “Process Product Packaging” build phase happens so late in the build process that it’s after the last user-specified custom build phase. There’s no room in Xcode’s current design for fixing up the problematic entitlements before they are incorporated into the signed product. As far as I can tell the only clean workaround would be to redundantly re-sign the child app with a custom script, and corrected entitlements, after Xcode’s build process is completed.

-

I filed Radar #34628449, “Sandboxed project build with Xcode 9 cannot launch child process.”

-

Update: Colin Barrett pointed out on Twitter that the entitlement in question here, “com.apple.security.get-task-allow”, may be required in order to attach to and debug a process. If true, then I think this is something that was handled in a different way in Xcode 8. I can confirm that my apps do not have the entitlement imposed on them by Xcode 8, yet I am able to attach to and debug them.

-

If Apple changed the debugger infrastructure in Xcode 9 so that the relationship between the debugger and target processes is more locked down, requiring a specific entitlement, then that’s probably a good thing. But if this change was made without thinking about the implications for the above-cited “strict two entitlement” rule for sandbox inheritance, then probably some flexibility needs to be applied to that rule.

-

Finally, as I noted above the entitlement is being applied to all my targets. What I didn’t clarify is that the entitlement is added even when Building and Archiving. A release build’s binaries are endowed with this additional entitlement, which may also bring additional security vulnerabilities to the app.

-

I would not ship a sandboxed Mac app that is built with Xcode 9, until we understand more about when Xcode applies this entitlement, and whether it can be prevented for Release builds at the very least.

-

Update 2: I’ve learned that Xcode’s “Export Archive” functionality causes the unwanted entitlement to be removed. Apparently the assumption is that everybody creates Xcode archives as part of their build and release process. I am sure this is true for most (all?) iOS deployments, but for Developer-ID signed apps on the Mac, there has traditionally been less of an incentive to do this. Got a properly signed Mac application? Zip it up, put it on a web server, and you’re done.

-

I’m not sure yet whether I’ll switch my build process to use archiving, or whether I’ll pull some other stunt to redo the code signing with corrected entitlements. In any case this has been quite an adventure today getting to the bottom of this. I updated my bug report with Apple to request that they provide some standard build flag that would prevent the problematic entitlement from being added from the start. In the mean time, I’ll explore one of the workarounds and get my builds back to fully functional!

-
- -
- -
-
- -
-
- -

- Better Swift Completion -

- - -
- -
-

Apple released Xcode 9 earlier this week, and in spite of a few glitches here and there, I have found the update to be an overall improvement over Xcode 8. It’s nice that Apple continues to invest in the core tools for Mac and iOS developers.

-

I’ve been dabbling in more and more Swift development lately, and it’s brought to light a shortcoming in Xcode’s code completion which has unfortunately not improved in Xcode 9: completion of Swift function calls when there is a large quantity of candidates.

-

Take for example NSAttributedString. If I want to initialize a new instance in Swift, I type “NSAttributedString(” to bring up the list of compatible init methods I can choose from:

-

SwiftCompletion

-

The problem at this point is that I have to navigate the menu by hand. I can’t narrow down the list of completions any further by typing, because the very next character I type will be interpreted as the manual filling out of parameters of the NSAttributedString initializer.

-

BadCompletion

-

This is a situation where Objective-C gets much nicer treatment in the editor. Because completion in Objective-C begins when I start typing “init”, and because the named first parameter is part of the init message name, I can winnow down the results quite a bit:

-

Pasted Image 9 22 17 11 24 AM

-

Better still, because Xcode performs a fuzzy match on the typing, I can proceed to type the names of additional parameters to zero in completely on the variation I want:

-

MEAppController AppDelegate m Edited

-

When I accept the completion, all of my typing is replaced with the expected, templated parameter placeholders for the chose initializer.

-

I filed Radar #34594940 requesting better completion for Swift.

-
- -
- -
-
- -
-
- -

- JavaScript OSA Handler Invocation -

- - -
- -
-

When Apple added support to macOS to support JavaScript for Automation, they did so in a way that more or less allows folks who invoke AppleScripts to invoke JavaScript for Automation scripts as if they were exactly the same. An abstraction in Apple’s Open Script Architecture (OSA) makes it easy for script-running tools to theoretically handle any number of scripting languages without concern for the implementation details of those languages.

-

This mostly works, but I recently received a bug report that shed light on a problem with Apple’s implementation of JavaScript with respect to invoking a specific named handler. The OSA provides a mechanism for loading and running a specific handler, or function, within a script. My app FastScripts takes advantage of this to query a script about whether it would prefer to be invoked in another process or not. Unfortunately, when it comes to JavaScript, Apple’s implementation runs the whole script in addition to running just the specific, named handler.

-

If you’ve got Xcode handy, you can use this simple playground content to observe the problem:

-
-import OSAKit
-
-if let javaScriptLanguage = OSALanguage(forName: "JavaScript") {
-   let scriptSource = "Application('Safari').activate();" +
-         "function boo() { ObjC.import('Cocoa'); $.NSBeep(); }"
-   let myScript = OSAScript(source: scriptSource, language: javaScriptLanguage)
-
-  // Only the behavior of boo should be observed
-  myScript.executeHandler(withName: "boo", arguments: [], error: nil)
-}
-
-// Give time for the beep to sound
-RunLoop.current.run(until: Date(timeIntervalSinceNow:5))
-
-

The named function “boo()” only invokes NSBeep, so when this playground is run, all that should happen is a beep should be emitted from the Mac. Instead, when it runs Safari becomes the active application. This is because in addition to running the “boo()” handler, it also runs the whole script at the top level.

-

A workaround to the bug is to wrap the top level functionality of a script in a “run()” handler, so where the scriptSource is declared above, instead use:

-
-   let scriptSource = "function run() { Application('Safari').activate(); }" +
-         "function boo() { ObjC.import('Cocoa'); $.NSBeep(); }"
-
-

I hope this helps the one other person on earth who cares about invoking JavaScript for Automation methods indvidually! (Radar #33962901, though I’m not holding my breath on this one!)

-
- -
- -
-
- -
-
- -

- Xcode GitHub Integration -

- - -
- -
-

Apple’s beta release of Xcode 9 features impressive improvements to its source control features, including streamlined integration with GitHub. There’s even a fancy “Open in Xcode” button when you go to clone a project:

-

Screen capture of the GitHub interface for cloning a project

-

This integration is amazing. You just click the button, specify a save folder in Xcode, and boom! You’re off and …

-

Screen capture of build failure indicating a missing signing certificate

-

Oh, right. Code signing. The otherwise stellar GitHub integration in Xcode underscores a longstanding deficiency in how it manages code signing identities for multi-team, collaborative projects. Precisely the kinds of projects you’re liable to find on GitHub.

-

The problem could be solved, or at least diminished greatly, by providing some mechanism for declaring that a project should be code signed “with the user’s own default developer team.” The default branch of any open source project targeting Apple platforms, would specify the DEVELOPMENT_TEAM as something like:

-
-DEVELOPMENT_TEAM = Automatic
-
-

Xcode would provide a user-level setting for “Default Development Team”, and in the absence of any overriding setting, that team would be used whenever a project was configured as above.

-

I wrote about this problem once before, but with all the work being put into streamlining the experience of cloning from and pushing to GitHub, now is an ideal time for Apple to embrace a fix. Radar #32614751.

-

Another issue that stops short the cloning, and immediate building and running, of open source projects, is the need to fulfill external dependencies. In some cases this might require manually downloading and installing libraries, or cloning projects, but in the vast majority of cases the dependencies will be specified using built-in Git submodule support, or a popular package manager. In each of these cases, it should be trivial for Xcode to detect that the project it has just cloned also has dependencies:

-
    -
  • Git submodules: there is a .gitmodules directory.
  • -
  • Carthage: there is a Cartfile file.
  • -
  • CocoaPods: there is a Podfile file.
  • -
  • Swift Package Manager: there is a Swift.package file.
  • -
-

If Xcode sees evidence of any of these techniques at play, it could do the favor of checking them out immediately after cloning the project. Radar #32615265.

-

The GitHub integration coming in Xcode 9 provides a nearly effortless capability for cloning, building, and running open source projects that target Apple platforms. Ideally it would also go the extra mile and provide for variable, dynamic development teams, as well as conduct a rudimentary check for dependencies that must be checked out before commencing work on the project.

-
- -
- -
-
- -
-
- -

- Evergreen Images -

- - -
- -
-

Brent Simmons, the original developer of MarsEdit and NetNewsWire, is building a new feed reader app called Evergreen:

-

Evergreen is an open source, productivity-style feed reader for Macs.

-

It’s at a very early stage — we use it, but we don’t expect other people to use it yet.

-

I’ve never been one to shy away from early-stage software, so of course I ran to the GitHub project page, cloned the repository, and built it immediately on my own Mac.

-

Screenshot of Evergreen about box without a custom icon.

-

Ahh, the tell-tale sign of a young app: the generic about box. Personally, I like to give apps-in-progress an icon, even if only a placeholder image, as soon as possible. It occurred to me that Apple has done the favor of providing a pretty-darned-suitable image for “Evergreen” in the form of its Emoji glyph of the same name:

-

🌲

-

Since I have the source code right here, why don’t I render that tree at a large size in a graphics app, resize it to a million different resolutions, bundle it up and check it in to the Evergreen source base?

-

Because that’s not nearly as fun as doing it in code. I dove into the Evergreen application delegate class, adding the following function:

-
-private func evergreenImage() -> NSImage? {
-	var image: NSImage? = nil
-	let imageWidth = 1024
-	let imageHeight = 1024
-	let imageSize = NSMakeSize(CGFloat(imageWidth), CGFloat(imageHeight))
-
-	if let drawingContext = CGContext(data: nil, width: imageWidth, height: imageHeight, bitsPerComponent: 8, bytesPerRow: 0, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue) {
-
-		let graphicsContext = NSGraphicsContext(cgContext: drawingContext, flipped: false)
-		NSGraphicsContext.saveGraphicsState()
-		NSGraphicsContext.setCurrent(graphicsContext)
-
-		let targetRect = NSRect(origin: NSZeroPoint, size: imageSize)
-		NSString(string: "🌲").draw(in: targetRect, withAttributes: [NSFontAttributeName: NSFont.systemFont(ofSize: 1000)])
-
-		NSGraphicsContext.restoreGraphicsState()
-
-		if let coreImage = drawingContext.makeImage() {
-			image = NSImage(cgImage: coreImage, size: imageSize)
-		}
-	}
-
-	return image
-}
-
-

In summary this code: creates a CoreGraphics drawing context, renders a huge evergreen Emoji glyph into it, and creates an NSImage out of it.

-

Then from the “applicationDidFinishLaunching()” function:

-
-if let appIconImage = evergreenImage() {
-	appIconImage.setName("NSApplicationIcon")
-	NSApplication.shared().applicationIconImage = appIconImage
-}
-
-

Give the newly created image the canonical name, used by AppKit, for looking up the application icon, and immediately change the application’s icon image to reflect the new value. It worked a treat:

-

EvergreenEmoji

-

In programming there is usually a hard way, an easy way, and a fun way. Be sure to take the third option as often as possible.

-
- -
- -
-
- - - - -
-
- - -
- -
- - - - - - - - - \ No newline at end of file diff --git a/Frameworks/FeedFinder/FeedFinderTests/Resources/inessential.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/inessential.html deleted file mode 100644 index 3bd46888f..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/Resources/inessential.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - inessential: weblog - - - - - - - - - - -
- -
-

Lizcast

-

The Omni Group’s Liz Marley, who recently transitioned from testing to engineering, appears on the NSNorth 2016 podcast. She talks about…

- -

…challenges in engineering school, working with office cats, making the transition from software engineering to testing to developing and how knitting, like code, has the ultimate undo.

- -

Knitting is serious (though not somber) business here at Omni.

- -
-

OmniOutliner 4.5

-

OmniOutliner 4.5 is up on Omni’s site, and should be in the Mac App Store within days.

- -

With this release — see the release notes — I helped work on, of all things, printing bugs and features. This is the first time in my entire career where I worked on printing support that was more than just the most basic possible thing.

- -

And that sounds weird for the year 2016, I realize. But here’s the thing: working on printing support is far from glamorous. You wouldn’t call it fun. But the people who need these features really do need them, and it’s a matter of respect for OmniOutliner users that we do a great job even with printing.

- -

But I sure am glad to get it finished and shipping. And I’m proud of the work we did — more proud than I expected to be. It’s solid, and I think the people who print from OmniOutliner will be very pleased.

- -

Now we’re on to other new features, including editing Markdown documents with OmniOutliner.

- -
-

OmniDev

-

Omni is hiring a Mac/iOS developer!

- -

We’re also hiring a web developer, graphic designer, and phone support humans.

- -

I’ll let you try out my new beanbag chair.

- -
-

OmniJobs

-

We’re hiring a senior front-end web developer, a graphic designer, and support humans.

- -

You should apply.

- -
-

It Will Be Trump

-

The South Carolina primary is where the establishment fixes the errors of Iowa and New Hampshire. It’s Lee Atwater’s firewall.

- -

When Buchanan threatens Dole, South Carolina shuts it down. When McCain threatens Bush, South Carolina applies the kibosh.

- -

But is there any hope that it will function that way this time?

- -

I don’t think so. The establishment candidates are Bush, Rubio, and Kasich. They don’t have a shot. Nor does Cruz. Trump wins South Carolina.

- -

If that’s true, then it’s all over. If South Carolina fails — if the very primary that’s designed to toss the ball back to the establishment fails — then there’s no hope at all.

- -

Cruz will go on to win a few states, most notably Texas. But otherwise it’s going to be Trump. He’ll get the delegates he needs, and that will be that.

- -
-

Origin of Good (and Bad) Hair Day

-

When I was in middle school in the late ’70s I struggled to get my hair to feather properly. It just didn’t want to do it.

- -

Like many kids that age I was newly conscious of my appearance — and I naïvely thought that well-feathered hair was a necessary (though not sufficient) key to fitting in. (Which was probably true, by the way.)

- -

Every morning I would find that my hair behaved, at least somewhat, or it didn’t. So I categorized each day as a “good hair day” and a “bad hair day.”

- -

I told my friends about this categorization — including a neighborhood girl named Sarah. She ended up telling other kids at school.

- -

And pretty soon those kids, even kids I didn’t really know, would stop me in the halls or at lunch and say, “Hey Brent — good hair day or bad hair day?” Not meanly. Teasingly. It was funny.

- -

Years later I started hearing the phrase on TV, and I was surprised that my little middle-school thing had spread and become part of the culture.

- -

* * *

- - -

Of course, it’s also possible that I picked it up from Jane Pauley. But for all these years I’ve believed — no joke — that it was me, that it was my phrase. Maybe Jane Pauley got it (indirectly) from me.

- -

It’s highly unlikely — of course, I know this — that I’m the originator. But still, it had to be someone, right?

- -

(Not necessarily. It’s kind of obvious and could have had many originators.)

- -

* * *

- - -

I stopped categorizing good and bad hair days by the time I got to high school. And these days I’m just glad that I still have some hair.

- -
-

River5

-

River5 is Dave Winer’s river-of-news RSS aggregator.

- -

It’s a Node app. You can run it on a public machine and access it anywhere, or run it on your desktop and just read your news there.

- -
-

Stop Watch

-

Some time last week my iPhone started prompting me frequently to re-enter my iCloud password. And then my Watch started doing the same, about once a minute — with a little tap on the wrist each time.

- -

Obviously I did re-enter my password — and have done so a dozen or so times now — but it doesn’t seem to matter.

- -

So I stopped wearing my Watch and have switched to a mid-sixties Hamilton that my Dad gave me. (He had gotten it as a high school graduation present.)

- -

I’m no watch aficionado — but I do appreciate a good and attractive watch (which this is), and I appreciate even more an old watch that’s a family thing.

- -

Here’s the thing, though: the Apple Watch contains a hundred miracles of engineering and design, surely, but serious problems with software and services can turn even the most incredible hardware into something you just sit on your desk and ignore.

- -
-

On Sanders Governing

-

The Atlantic, Norm Ornstein:

- -

But is there any real evidence that there is a hidden “sleeper cell” of potential voters who are waiting for the signal to emerge and transform the electorate? No.

- -

Pure candidates on both sides of the spectrum often claim that their purity will bring in the checked-out voters, because they’re just waiting for a real conservative or a real liberal.

- -

It’s an enduring fairy tale with terrible consequences. To put faith in it is to lose to the other party.

- -
-

CocoaConf Podcast with Me

-

Cesare Rocchi interviewed me for the latest CocoaConf Podcast on life before the App Store.

- -

There was a life, by the way. It was fun! We could release software any time we wanted to.

- -
-

Archive

- -
- -
-
-Ads via The Deck - -
-
- - - - - - - - - diff --git a/Frameworks/FeedFinder/FeedFinderTests/Resources/sixcolors.html b/Frameworks/FeedFinder/FeedFinderTests/Resources/sixcolors.html deleted file mode 100644 index 48927c6fa..000000000 --- a/Frameworks/FeedFinder/FeedFinderTests/Resources/sixcolors.html +++ /dev/null @@ -1,1102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Six Colors: Apple, technology, and other stuff from Jason Snell and Friends - - - - - - - - - - - - - - - - -
- -
- six colors -
- -
- -
- -

- by Jason Snell & Dan Moren -

- -
- -
- - -
- -
- -
- - - - -
- - - - -
-

Become a subscriber!

- -

Six Colors Subscriptions - Support the site and receive exclusive monthly newsletters and weekly podcasts. -

- -
- - - - - - - - - - - -
- - - - - - -
-
-

Linked by Dan Moren

- -
- -
-

Transmission Bit Torrent client possibly infected with malware

- -

Some copies of Transmission, a popular OS X Bit Torrent client, have reportedly been infected with a ransomware program, according to security researchers Palo Alto Networks:

- -
-

The KeRanger application was signed with a valid Mac app development certificate; therefore, it was able to bypass Apple’s Gatekeeper protection. If a user installs the infected apps, an embedded executable file is run on the system. KeRanger then waits for for three days before connecting with command and control (C2) servers over the Tor anonymizer network. The malware then begins encrypting certain types of document and data files on the system. After completing the encryption process, KeRanger demands that victims pay one bitcoin (about $400) to a specific address to retrieve their files. Additionally, KeRanger appears to still be under active development and it seems the malware is also attempting to encrypt Time Machine backup files to prevent victims from recovering their back-up data.

-
- -

Oof. At least that 3-day waiting period gives a window for folks to remove the infected apps. I checked all three of my Macs, which all had the reportedly infected version, but none of them appeared to include the malware. It’s a good idea to do the same if you’re concerned. Instructions for checking are at the address above, and at Transmission’s website.

- - - -
-
-
- - - - -
- - - - - - - - - -
- - - - - - -
-
-
-

Podcast

- -
- -
- -

The Incomparable #290: Team Bucket -

- -

The Incomparable

-

The recently released game “Firewatch,” by Campo Santo and Panic, is the subject of discussion on this week’s episode of The Incomparable. This is a game that’s got a plot, but so much of the richness comes from characters and dialogue. Also, there are a lot of trees. Jason is joined by John Siracusa, Tiffany Arment, Serenity Caldwell, Tony Sindelar, and Brian Hamilton.

- - -
-
-
- - -
- - - - -
- - - - - - -
-
-

Linked by Jason Snell

- -
- -
-

A marvelous marble-based music machine

- -

Michael Rundle at Wired UK:

- -
-

The Wintergatan Marble Machine, built by Swedish musician Martin Molin and filmed by Hannes Knutsson, is a hand-made music box that powers a kick drum, bass, vibraphone and other instruments using a hand crank and 2,000 marbles.

-
- -

The video of it in operation is amazing.

- - - -
-
-
- - -
- - - - -
- -
- - -
- - - - -
- - - - - - -
-
-

Linked by Jason Snell

- -
- -
-

Simple automation

- -

I’m spending some time building some complex workflows in Keyboard Maestro—more on those in the future. But it’s worth reading Dr. Drang’s post on the benefits of even the simplest automation.

- - - -
-
-
- - -
- - - - -
- - - - - -
- -
-

By Jason Snell

- -
- -
-

Automate This: Connect to the Web with cURL

- -

One of the best utilities on the Mac is one you might not be familiar with, because it requires the use of Terminal. It’s cURL, and it’s a valuable part of my scripting, automation, and debugging toolbox.

- -

curl is a command-line utility that works kind of like a web browser. I use it mostly to download web content or ping web services. Using cURL for a lot of basic tasks is quite easy. Just type curl followed by a web address, and you’ll see that web page spewed across your Terminal window. type curl https://sixcolors.com/ > sixcolors.html and you’ll have dumped the contents of that URL to a file in your user folder.

- -

As a person who does a lot of podcast-related stuff, I am occasionally called upon to debug a podcast’s feed. Podcast feed files are XML files, and don’t display in a friendly way in a web browser. No problem — I use cURL to download the file and open it in my text editor of choice, BBEdit.

- -
curl http://feeds.theincomparable.com/tpk > tpk.rss ; bbedit tpk.rss
- -

This is the command I usually use — it’s actually two commands in one, separated by a semicolon. The first command downloads the RSS feed to a text file; the second uses the bbedit command-line utility1 to open the resulting file directly in BBEdit.

- -

You could also omit the BBEdit step and direct cURL to save the file to a more convenient location, like the Desktop:

- -
curl http://feeds.theincomparable.com/tpk > ~/Desktop/tpk.rss
- -

When I wanted to use IFTTT to automate some stuff in my house, I needed my computer to activate one of IFTTT’s “custom triggers” simply by loading a particular URL, in the format https://maker.ifttt.com/trigger/trigger-name-here/with/key/key-goes-here. In other words:

- -
curl https://maker.ifttt.com/trigger/mytrigger/with/key/this-is-my-key
- -

The app I’m using for this particular trigger can’t run Terminal commands itself, but it can launch apps. One great thing about terminal commands is that they’re easily integrated into AppleScript or Automator workflows. In this case, the “app” my app launches is this:

- -
do shell script "curl https://maker.ifttt.com/trigger/mytrigger/with/key/this-is-my-key"
- -

That’s it. With cURL and the AppleScript command “do shell script” (or the Automator equivalent, the Run Shell Script action), you can quickly and cleanly automate Web connections without using a web browser. And scripting aside, cURL is quite useful in downloading content from the Internet that you want to view in something other than a web browser2.

- -
-
-
    - -
  1. BBEdit ships with three different command-line tools! Pretty awesome. ↩

  2. - -
  3. As with most command-line software, there’s a lot more to cURL. Type man curl or visit the online documentation to see all the options.  ↩

  4. - -
-
- - - - - - - - - - - -
-
-
- - -
- - - - -
-
-
-

Dan Moren for Macworld

- -
- -
-

3 ways Apple could improve email ↦

- -

Despite all the many forms of communicating with people online—iMessage, Twitter, Facebook, Slack—email still reigns supreme for me. I conduct business via email, keep in touch with my family, send links to friends, and coordinate events. And yet, Apple’s approach to email has remained largely static for years.

- -

That’s not to say that the company hasn’t tried to integrate new features into the email experience. Hardly a release of iOS or OS X comes without some improvements to the Mail app. While some are more successful than others, overall our email has hardly been—I hesitate to even whisper the word—disrupted.

- -

Despite the surfeit of ways for us to communicate, I don’t think email is going away anytime soon. And while dealing with it may not be the most pleasant of tasks, a few changes might bring it up to date with the rest of our modern online experience.

- - -

Continue reading on Macworld ↦ - -

-
-
- - -
- - - - -
- - - - - - -
-
-

Linked by Jason Snell

- -
- -
-

San Bernardino DA: iPhone may hold “dormant cyber pathogen”

- -

David Kravets of Ars Technica, quoting Michael Ramos, the San Bernardino County District Attorney:

- -
-

“The seized iPhone may contain evidence that can only be found on the seized phone that it was used as a weapon to introduce a lying dormant cyber pathogen that endangers San Bernardino’s infrastructure,” according to a court filing

- -

Jonathan Zdziarski, a prominent iPhone forensics expert, said in a telephone interview that the district attorney is suggesting that a “magical unicorn might exist on this phone.”

-
- -

Michael Ramos may have watched too many episodes of “24”. I suspect he’s also a probationary member of the Golden Key Wizard Society. He can come to meetings on his magical unicorn.

- - - -
-
-
- - -
- - - - -
- - - - - - -
-
-

Linked by Jason Snell

- -
- -
-

Apple shareholders reject board diversity plan

- -

The Guardian:

- -
-

Apple shareholders have overwhelmingly rejected a proposal that would require the board of America’s largest company to adopt an “accelerated recruitment policy” for minorities among company leaders.

-
- -

This is the shareholder proposal that Apple opposed in January, formally failing. Apple opposed the proposal on the grounds that it was “unduly burdensome and not necessary because Apple has demonstrated to shareholders its commitment to inclusion and diversity.”

- - - -
-
-
- - -
- - - - -
- - - - - -
- -
-

By Jason Snell

- -
- -
-

Amazon Echo Dot and Sonos? Not… yet.

- -

-
Sonos Play:5 comes with a line-in jack.
-

- -

As Dan wrote about earlier today, Amazon has expanded the Echo family, and I’m intrigued by the $90 Echo Dot. It seems to be the original Amazon Echo, with most of its speaker technology sliced out, so it’s shorter and cheaper. Instead of having the better-quality speakers of the original, the Echo Dot is made to work in contexts where audio quality is less important (as a bedside clock radio, for example) or with external audio sources, such as Bluetooth speakers or any speaker that can use a standard headphone jack.

- -

amazon-echo-dot
Echo Dot can play out via a headphone jack. Buddies?

- -

As someone with a couple of Sonos speakers in my house, I immediately wondered if this might be the first step toward a joyous combination of Sonos’s whole-home audio system and Amazon Echo’s smart voice control. It might very well be, but Sonos and Amazon really need to work together if this is going to be a bountiful relationship.

- -

An esoteric, somewhat unsung Sonos feature could be helpful: If you’ve got a Sonos device with a line-in jack (such as a Play:5 speaker or a Connect), you can connect an external device like the Echo Dot and use it as an audio source. Most important is an esoteric feature called Line-In Autoplay, which will force a Sonos device to immediately switch to the line-in jack if it detects any audio being played by the device on the other end. Without this feature turned on, you have to manually switch a Sonos speaker to the line-in input before you can hear the audio.

- -

With a device like the Echo Dot (or an AirPort Express), you wouldn’t want to have to get out your phone and launch the Sonos app before you could even hear what was going on. You’d want to ask Alexa a question and hear the answer, even if that meant the music you listened to would be paused while the interaction went on. It looks like Sonos and the Dot can do that today.

- -

Still, it’s only a first step. Amazon’s Echo infrastructure currently has no support for Sonos speakers.1 If Sonos cut a deal with Amazon to allow you to control Sonos audio from the Echo, most of the problems here would vanish entirely. (You might not even need to attach the Echo Dot’s audio to your Sonos system at all, since Sonos already supports pretty much all the audio sources that the Echo supports.) I’d love to be able to voice control Sonos with an Echo or Echo Dot.

- -

If you’re someone who wants to use an Amazon Echo with a home stereo system or a really nice external speaker, the Echo Dot seems like it’s going to be a great addition. If you’ve already got a Sonos system, though, I don’t think the existence of the Echo Dot will help you much. But if Sonos and Amazon can agree to talk to each other, this could be the beginning of a beautiful friendship.

- -
-
-
    - -
  1. There’s a hack for this on GitHub if you want to play around with that. I don’t think I do. And there’s no official IFTTT support for Sonos, either. ↩

  2. - -
-
- - - - - - - - - - - -
-
-
- - -
- - - - -
- - - - - - -
-
-

Linked by Dan Moren

- -
- -
-

Apple Support now available via Twitter

- -

For those times when you just can’t make it to the Genius Bar, now you can tweet to get support, tips, and tricks from Apple.

- -

Cupertino has been incredibly strategic about its use of Twitter. Tim Cook, Phil Schiller, Eddy Cue, and other executives have certainly started using the platform more in the past few years, and there have long been accounts for the App Store and iTunes Trailers, and more recently Apple Music. But for all of that, there is still no official Apple Twitter account1.

- -

What’s most interesting about this to me is that it’s the first of Apple’s Twitter accounts that’s actually based on listening and responding to people. The rest, including Apple executives for the most part, are one-way experiences that focus on broadcasting information.

- -
-
-
    - -
  1. In fact, @apple is an account from 2011 that has never posted and yet has 37 thousand followers.  ↩

  2. - -
-
- - - -
-
-
- - -
- - - - -
-
-
-

Podcast

- -
- -
- -

The Rebound 75: Siriously? -

- -

The Rebound

-

It should have been a short show, really. It should have. But after Dan, John, and Lex discuss some developments in the Apple-FBI case—including the fact that yes, you can get C-SPAN online for free!—and then discuss the rumored upcoming Apple event, we launch into a discussion of the Apple Watch’s successes and failures as we approach its first anniversary. There may be some yelling. Happy 75th episode!

- - -
-
-
- - -
- - - - -
- - - - - - -
-
-

Linked by Dan Moren

- -
- -
-

Apple posts amicus briefs in FBI case

- -

As the Case of the Locked iPhone1 moves on to the next phase, Apple has posted a list of supporting amicus—or “friends of the court”—briefs to its website. Included in the list so far are the ACLU, a relative of the San Bernardino victims, an official of the Office of the United Nations High Commissioner of Human Rights, the App Association, and Access Now.

- -

Conspicuously absent at present are any other technology companies, though it’s still early. The next stage in the case is a hearing to be held before Magistrate Judge Sheri Pym on March 22 in Riverside, California, the day after Apple’s rumored to hold its next press event.

- -
-
-
    - -
  1. Worst Sherlock Holmes story ever.  ↩

  2. - -
-
- - - -
-
-
- - -
- - - - -
- - - - - - -
-
-

Linked by Dan Moren

- -
- -
-

Bustin’ makes me feel good

- -

Hey, it’s the first trailer for the Ghostbusters reboot with Kristen Wiig, Melissa McCarthy, Kate McKinnon, Leslie Jones, and Chris Hemsworth!

- -

- -

I kind of wish the titlecards didn’t lean on the old franchise, especially when it seems like this is a complete and utter reboot, but I guess that’s marketing for you.

- -

Also starring are Charles Dance (!!!), batter known as Tywin Lannister from Game of Thrones, and Michael K. Williams, aka Omar Little from The Wire. The whole thing is directed by Paul Feig (Bridesmaids) and comes out on July 15.

- - - -
-
-
- - -
- - - - -
- - - - - -
- -
-

By Dan Moren

- -
- -
-

The Amazon Echo family expands by two

- -

Meet Dot and Tap. No, they’re not lovable cartoon characters—they’re new additions to Amazon’s Echo family of smart, connected speakers.

- -

amazon-echo-dot
The Dot is essentially a small version of the existing Echo, just 1.5 inches tall, as opposed to the Echo’s 9.9 inches. From what I can tell, it has all of the features of the Echo, as well as two new tricks up its sleeve: it includes a standard 3.5mm audio output jack, letting you connect it to an existing set of speakers; and it can connect to Bluetooth speakers as well, so you can pipe music from online music sources—Prime Music, Spotify, Pandora—to better speakers. (The Dot includes its own internal speaker, but given the size difference, I’d guess it’s not as good as the Echo’s speaker, which itself wasn’t going to win any awards.) At $90, it’s half the price of the full blown Echo, but there is one catch: currently it’s only available to order via an Amazon Echo, thanks to apparently limited supplies.1 It ships at the end of March.

- -

amazon-tap

- -

The Tap is, as rumored, a smaller portable version of the Echo—6.2 inches tall and 2.6 inches in diameter—complete with a rechargeable battery and charging cradle (you can also charge it via micro-USB). Despite sharing most of its siblings’ capabilities, though, it lacks one significant feature: you can’t address it by saying “Alexa”; instead, like a pre-6s iPhone, you need to tap a button on the side to trigger the voice assistant. Amazon says the battery should be good for up to 9 hours of playback, and the Tap will even announce to you when its juice is running low. It also has a 3.5mm audio input port, if you don’t want to connect an audio source via Bluetooth. The Tap runs $130, plus another $20 if you want the Sling case that makes it look like a waterbottle. Like the Dot, it ships at the end of March.

- -

As my favorite gadget of 2015, I’ve been overwhelmingly positive about the Echo, and I’m intrigued to see what these new additions offer. Of the two, the Dot is probably the less exciting, although its lower price point is firmly within “impulse buy” territory, which could bring in new users who have been curious about the Echo. The portability of the Tap is interesting: at $130, it’s not cheap, but it doesn’t cost an arm and a leg more than comparable portable Bluetooth speakers (as Amazon’s product page is quick to note). I wonder if having to manually trigger Alexa will dull some of the appeal, but perhaps it’s better to consider this as a Bluetooth speaker with Alexa capability than an Echo you can tote around with you.

- -

I’m also pretty convinced that within the next year or two, there will be a portable Echo with the voice-activated Alexa prompt. Amazon has been extremely diligent about bringing new features to the Echo, and I’ve definitely gotten attached to the device. Seems like these new models provide a good opportunity for Amazon to spread the love.

- -
-
-
    - -
  1. To forestall questions: Yes, I ordered one. In the name of science, people!  ↩

  2. - -
-
- - - - - - - - - -

[Dan Moren is a freelance writer, podcaster, and former Macworld editor. You can email him at dan@sixcolors.com or find him on Twitter at @dmoren.]

- -
-
-
- - -
- - - - -
- - - - - -
- -
-

By Jason Snell

- -
- -
-

Quick Tip: Push notifications from Mac to Apple Watch

- -

Last month, reader Patrick M. wrote in with an interesting question:

- -
-

I was wondering if you knew of a way to easily push Mac notifications to an Apple Watch? I’ve been doing a lot of FCPX exports and typically leave my iMac while it completes. I’d love to be notified while I’m out when it’s done. The same goes for any number of time intensive apps or jobs I have my Mac do. Just thought you might have ran into something that might be a good solution.

-
- -

There was a time that I pushed notifications to my iPhone from my Mac, using Growl and the first iteration of the Boxcar app for iOS. After trying a few things, though, I don’t think the current implementation of Boxcar for iOS is reliable enough to use here.

- -

prowl -
A Mac notification, right on my Apple Watch.
-

- -

Instead, I found success with a combination of Growl ($4 from the Mac App Store and Prowl ($3 from the iOS App Store).

- -

Growl is a Mac utility that lets you send custom notifications from your Mac. In many ways it’s been subsumed by Notification Center, but it’s still got some skills—like the ability to trigger actions other than displaying an alert bubble—that OS X doesn’t offer by itself. The Prowl app comes with a Growl plug-in that allows you to set Growl to trigger a Prowl notification on your iPhone (and, yes, Apple Watch).

- -

Is this pretty? No. In fact, both apps are not particularly attractive, but they do the job. Once you sign up for a Prowl account, you can get an API key and paste that into the Prowl action within Growl, which connects your Mac to the Prowl app on your iPhone. Once that’s done, you can alert yourself on your watch whenever your Mac needs you.

- -

And since this is all done via the Internet, you don’t need to be near your Mac to be alerted about what it’s doing. I once got a Growl alert on my phone that a video encode had completed when I was at one of my daughter’s softball games. I like the idea that my Mac can reach out and find me if it needs me.

- -

Now, the app you want to notify you needs to support Growl for this to work. (I had to open HandBrake’s preferences and change its notification setting to Growl before it would work, for instance.) But once I did that, I was receiving notifications that my video encoding job had finished, right on my Apple Watch.1

- -

So, Patrick M.: Growl plus Prowl may be just what you’re looking for.

- -
-
-
    - -
  1. If you’re wanting to script other notifications, you could also consider Pushover, which—for the cost of a $5 in-app purchase—lets you send push notifications to your phone via web service. Thanks to TJ Luoma for the tip. ↩

  2. - -
-
- - - - - - - - - - - -
-
-
- - -
- - - - -
- - - - - -
- -
-

By Dan Moren

- -
- -
-

Automate This: Turn on your Xbox One from afar

- -

A few weeks ago, I wanted to download a really big file—the beta for the upcoming game The Division—to my Xbox One. Given how large it was—several gigabytes—I figured it would be best to do it while I was out of the house anyway.

- -

Using Xbox Live’s web-based marketplace, it’s pretty easy to queue up a download from anywhere, but the trick is that the Xbox has to be powered on in order to start the download. I spent a while trying to find a way to turn the Xbox One on remotely, including messing around with Microsoft’s Smart Glass app over my VPN and trying a Python script installed on my Mac mini, but ultimately had no luck.

- -

Do Button
IFTTT’s Do Button app
-Fool that I am, I didn’t realize until I got home that it was far, far easier than I’d thought. As I described in an earlier post, I’ve set up a Harmony Hub so that I can use my Amazon Echo to activate my various entertainment components, including the Xbox One. At first I was thinking through stupid ideas like triggering the Echo using speech synthesis via Terminal on one of my home apps, until I remembered that the Harmony Hub is hooked up via IFTT, so all I needed to do was trigger that particular recipe via the web or iOS app.

- -

I even took it a step further, thanks to IFTTT’s Do Button app which lets you create nice big buttons to easily initiate a recipe. (Do Button also has a Today widget for the phone and an Apple Watch app, which makes it even faster.)

- -

So now, when I want to start something downloading on the Xbox while I’m out of the house, all I need to do is reach for my phone or my Apple Watch, and I’m never more than a few taps away.

- - - - - - - - - -

[Dan Moren is a freelance writer, podcaster, and former Macworld editor. You can email him at dan@sixcolors.com or find him on Twitter at @dmoren.]

- -
-
-
- - -
- - - - -
-
-
-

Podcast

- -
- -
- -

Clockwise #126: Go into Space with Jerks -

- -

Clockwise

-

This week on our 30-minute run through four tech topics, Dan and Jason are joined by Andy Ihnatko and Brianna Wu to discuss choosing between convenience and privacy, our virtual-reality future, the viability of voice interfaces, and spending time in outer space.

- - -
-
-
- - -
- - - - -
-
-
-

Jason Snell for Macworld

- -
- -
-

Apple may be about to shake up its naming scheme ↦

- -

Apple’s general approach to naming its products is refreshing in an industry filled with products with complicated names and model numbers. Macs have model numbers, but nobody really uses them: I own an iPad Air 3 and a 2014 5K iMac and a 2012 11-inch MacBook Air, and between the model name, the release year, and maybe a screen size, that’s all any of us needs to know.

- -

Still, the ebb and flow of technology and fashion means that sometimes Apple needs to take a breath and adjust how it presents its products to the world. The PowerBook became the MacBook, the Power Mac became the Mac Pro, the MacBook Air appears to be diminished and headed for the west in favor of the new (adjectiveless) MacBook. So it goes.

- -

Which brings us to the report from 9to5Mac’s Mark Gurman that Apple is about to announce a new, updated iPad with the same 9.7-inch screen size as the iPad Air 2—but rather than calling it the iPad Air 3, Apple will consider it a smaller version of the iPad Pro.

- - -

Continue reading on Macworld ↦ - -

-
-
- - -
- - - - -
- - - - - - -
-
-

Linked by Jason Snell

- -
- -
-

‘Twitter Has Become a Park Filled With Bats and Perverts’

- -

Julieanne Smolkinski in New York Magazine:

- -
-

Let me try to explain how I see it. Twitter is like a beloved public park that used to be nice, but now has a rusty jungle gym, dozens of really persistent masturbators, and a nighttime bat problem. Eventually the Parks Department might rip up the jungle gym, and make some noise about fixing the other problems, because that’s what invisible administrators like Twitter staff and municipal recreation departments tend to do. But if the perverts and the bats got to be bad enough with no recourse, you’d probably just eventually stop going.

- -

(Additionally frustrating is that everybody is complaining about the safety issues at the park, and instead of addressing them, the city installs a crazy new slide. What? Nobody was calling for that. What about the perverts? What about the bats?)

-
- -

Every time Twitter launches a new feature, or discusses launching one, what I hear from people currently on Twitter is always a variation on, “What about the bats?”

- - - -
-
-
- - -
- - - - - - - - - - -
- -
- -
- -
- - - - - - - - - - - - - \ No newline at end of file diff --git a/Frameworks/FeedFinder/xcconfig/FeedFinderTests_target.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinderTests_target.xcconfig deleted file mode 100644 index c759ef8c6..000000000 --- a/Frameworks/FeedFinder/xcconfig/FeedFinderTests_target.xcconfig +++ /dev/null @@ -1,18 +0,0 @@ -ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks -INFOPLIST_FILE = FeedFinderTests/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinderTests -PRODUCT_NAME = $(TARGET_NAME) - - - - - - - - - - - - - diff --git a/Frameworks/FeedFinder/xcconfig/FeedFinder_project.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_project.xcconfig deleted file mode 100644 index 258ba13b6..000000000 --- a/Frameworks/FeedFinder/xcconfig/FeedFinder_project.xcconfig +++ /dev/null @@ -1,58 +0,0 @@ -CODE_SIGN_IDENTITY = -CODE_SIGN_STYLE = Automatic -DEVELOPMENT_TEAM = M8L2WTLA8W - -// See the notes in Evergreen_target.xcconfig on why the -// DeveloperSettings.xcconfig is #included here - -#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig" - -SDKROOT = macosx -MACOSX_DEPLOYMENT_TARGET = 10.13 -CLANG_ENABLE_OBJC_WEAK = YES -SWIFT_VERSION = 4.0 -COMBINE_HIDPI_IMAGES = YES - -COPY_PHASE_STRIP = NO -MACOSX_DEPLOYMENT_TARGET = 10.13 -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/FeedFinder/xcconfig/FeedFinder_project_debug.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_project_debug.xcconfig deleted file mode 100644 index 4480287e9..000000000 --- a/Frameworks/FeedFinder/xcconfig/FeedFinder_project_debug.xcconfig +++ /dev/null @@ -1,15 +0,0 @@ -#include "./FeedFinder_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/FeedFinder/xcconfig/FeedFinder_project_release.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_project_release.xcconfig deleted file mode 100644 index 4f6878e2a..000000000 --- a/Frameworks/FeedFinder/xcconfig/FeedFinder_project_release.xcconfig +++ /dev/null @@ -1,9 +0,0 @@ -#include "./FeedFinder_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/FeedFinder/xcconfig/FeedFinder_target.xcconfig b/Frameworks/FeedFinder/xcconfig/FeedFinder_target.xcconfig deleted file mode 100644 index 2cbf5f4fc..000000000 --- a/Frameworks/FeedFinder/xcconfig/FeedFinder_target.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ - -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 = FeedFinder/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.FeedFinder -PRODUCT_NAME = $(TARGET_NAME) - - diff --git a/Technotes/SubmoduleCheatSheet.md b/Technotes/SubmoduleCheatSheet.md index fc18d4962..45a703509 100644 --- a/Technotes/SubmoduleCheatSheet.md +++ b/Technotes/SubmoduleCheatSheet.md @@ -10,4 +10,6 @@ To add a submodule: To update a submodule — to get the latest changes: - TBD I surely wish I knew how + git submodule update + +I think. Not sure about the above. From 12de2ea155267c0896b5dcb267bf7298e4648ca4 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 23 Jun 2018 15:39:49 -0700 Subject: [PATCH 10/40] Update SubmoduleCheatSheet.md. --- Technotes/SubmoduleCheatSheet.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Technotes/SubmoduleCheatSheet.md b/Technotes/SubmoduleCheatSheet.md index 45a703509..38b908bb2 100644 --- a/Technotes/SubmoduleCheatSheet.md +++ b/Technotes/SubmoduleCheatSheet.md @@ -10,6 +10,7 @@ To add a submodule: To update a submodule — to get the latest changes: + git submodule init git submodule update I think. Not sure about the above. From 753ccf14dd894b3ded212870a5fd2f996a98bcbb Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 14 Jul 2018 12:32:11 -0700 Subject: [PATCH 11/40] Add note about updating Git submodules to their latest commits. --- Technotes/SubmoduleCheatSheet.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Technotes/SubmoduleCheatSheet.md b/Technotes/SubmoduleCheatSheet.md index 38b908bb2..6f1ce732b 100644 --- a/Technotes/SubmoduleCheatSheet.md +++ b/Technotes/SubmoduleCheatSheet.md @@ -1,6 +1,6 @@ # Git Submodules -Evergreen uses [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to include shared frameworks. At this writing (June 2018) they are DB5, RSCore, RSWeb, RSTree, and RSParser. +Evergreen uses [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to include shared frameworks. At this writing (June 2018) they are DB5, RSCore, RSDatabase, RSWeb, RSTree, and RSParser. To add a submodule: @@ -8,9 +8,7 @@ To add a submodule: (It’s unlikely you’ll need to do that. Adding a submodule is done super-rarely, if ever, and it’s Brent’s call.) -To update a submodule — to get the latest changes: +To update all submodules to their latest commits: - git submodule init - git submodule update + git submodule foreach git pull origin master -I think. Not sure about the above. From 49c44f183dfbf2caf1d625ee7b8381d69ca42f03 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 14 Jul 2018 14:43:54 -0700 Subject: [PATCH 12/40] Get Evergreen building. Switch to translucent sidebar. Trying to be a standard Mac app as much as possible, particularly so that supporting dark mode works properly. --- Evergreen/Base.lproj/MainWindow.storyboard | 20 +++++++++---------- .../AddFeed/AddFeedController.swift | 1 - submodules/DB5 | 2 +- submodules/RSDatabase | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Evergreen/Base.lproj/MainWindow.storyboard b/Evergreen/Base.lproj/MainWindow.storyboard index 18ce03396..b1f43efb1 100644 --- a/Evergreen/Base.lproj/MainWindow.storyboard +++ b/Evergreen/Base.lproj/MainWindow.storyboard @@ -1,7 +1,7 @@ - + - + @@ -265,21 +265,21 @@ - + - + - + - + - - + + @@ -296,7 +296,7 @@ - + @@ -314,7 +314,7 @@ - + diff --git a/Evergreen/MainWindow/AddFeed/AddFeedController.swift b/Evergreen/MainWindow/AddFeed/AddFeedController.swift index 7c79a7331..ff9eae87b 100644 --- a/Evergreen/MainWindow/AddFeed/AddFeedController.swift +++ b/Evergreen/MainWindow/AddFeed/AddFeedController.swift @@ -10,7 +10,6 @@ import AppKit import RSCore import RSTree import Data -import RSFeedFinder import Account import RSParser diff --git a/submodules/DB5 b/submodules/DB5 index 6b32b49be..1b20fde3a 160000 --- a/submodules/DB5 +++ b/submodules/DB5 @@ -1 +1 @@ -Subproject commit 6b32b49bed78535ae0e608a23edf04df5a9a0c70 +Subproject commit 1b20fde3a79dc6b81e7fcb63c81aee8add56e380 diff --git a/submodules/RSDatabase b/submodules/RSDatabase index 4e7358074..0c68ac274 160000 --- a/submodules/RSDatabase +++ b/submodules/RSDatabase @@ -1 +1 @@ -Subproject commit 4e7358074ed3c358ebfe3741a38f43e020665694 +Subproject commit 0c68ac2744f8115761a72a1f52a46cb5c0d4ec37 From ce0d2450b83ec8c5dee6bb9c612b3eb06ba39c47 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 15 Jul 2018 12:05:00 -0700 Subject: [PATCH 13/40] Get the app building with Xcode 10 beta 3. --- Evergreen/AppDelegate.swift | 2 +- Evergreen/Base.lproj/MainWindow.storyboard | 19 +++++++++---------- .../Data/Data.xcodeproj/project.pbxproj | 14 ++++++++------ .../Database.xcodeproj/project.pbxproj | 18 ++++++++++++------ 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/Evergreen/AppDelegate.swift b/Evergreen/AppDelegate.swift index 13c8fc80b..9b1850c7c 100644 --- a/Evergreen/AppDelegate.swift +++ b/Evergreen/AppDelegate.swift @@ -104,7 +104,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, func applicationDidFinishLaunching(_ note: Notification) { - appName = Bundle.main.infoDictionary!["CFBundleExecutable"]! as! String + appName = (Bundle.main.infoDictionary!["CFBundleExecutable"]! as! String) let isFirstRun = AppDefaults.shared.isFirstRun if isFirstRun { diff --git a/Evergreen/Base.lproj/MainWindow.storyboard b/Evergreen/Base.lproj/MainWindow.storyboard index b1f43efb1..855462a56 100644 --- a/Evergreen/Base.lproj/MainWindow.storyboard +++ b/Evergreen/Base.lproj/MainWindow.storyboard @@ -1,17 +1,16 @@ - + - - + + - - + @@ -211,7 +210,7 @@ - + @@ -275,14 +274,14 @@ - + - + @@ -361,7 +360,7 @@ - + @@ -548,7 +547,7 @@ - + diff --git a/Frameworks/Data/Data.xcodeproj/project.pbxproj b/Frameworks/Data/Data.xcodeproj/project.pbxproj index c6cd8a114..5ca9257a3 100644 --- a/Frameworks/Data/Data.xcodeproj/project.pbxproj +++ b/Frameworks/Data/Data.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405C91F1A8E4300DF0296 /* DatabaseID.swift */; }; 8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */; }; - 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 */; }; 844BEE7D1F0AB4C4004AB7CD /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */; }; @@ -17,7 +16,8 @@ 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 */; }; - 84C490F41F705D5F003131D2 /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C490F51F705D5F003131D2 /* RSWeb.framework */; }; + 848E3EB420FBCFAE0004B7ED /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EB320FBCFAE0004B7ED /* RSCore.framework */; }; + 848E3EB520FBCFB50004B7ED /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C490F51F705D5F003131D2 /* RSWeb.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -65,6 +65,7 @@ 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 = ""; }; 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; + 848E3EB320FBCFAE0004B7ED /* RSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84C490F51F705D5F003131D2 /* RSWeb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSWeb.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D511EEC420242DF400712EC3 /* DataTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DataTests_target.xcconfig; sourceTree = ""; }; D511EEC520242DF400712EC3 /* Data_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_project_debug.xcconfig; sourceTree = ""; }; @@ -83,8 +84,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84C490F41F705D5F003131D2 /* RSWeb.framework in Frameworks */, - 843079FA1F0AB57F00B4B7F7 /* RSCore.framework in Frameworks */, + 848E3EB520FBCFB50004B7ED /* RSWeb.framework in Frameworks */, + 848E3EB420FBCFAE0004B7ED /* RSCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -149,6 +150,7 @@ 844BEEA81F0AB520004AB7CD /* Frameworks */ = { isa = PBXGroup; children = ( + 848E3EB320FBCFAE0004B7ED /* RSCore.framework */, 84C490F51F705D5F003131D2 /* RSWeb.framework */, 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */, ); @@ -240,13 +242,13 @@ TargetAttributes = { 844BEE5A1F0AB3C8004AB7CD = { CreatedOnToolsVersion = 8.3.2; - DevelopmentTeam = 9C84TZ7Q6Z; + DevelopmentTeam = M8L2WTLA8W; LastSwiftMigration = 0830; ProvisioningStyle = Automatic; }; 844BEE631F0AB3C9004AB7CD = { CreatedOnToolsVersion = 8.3.2; - DevelopmentTeam = 9C84TZ7Q6Z; + DevelopmentTeam = M8L2WTLA8W; ProvisioningStyle = Automatic; }; }; diff --git a/Frameworks/Database/Database.xcodeproj/project.pbxproj b/Frameworks/Database/Database.xcodeproj/project.pbxproj index b4a290ffe..9f64b2590 100644 --- a/Frameworks/Database/Database.xcodeproj/project.pbxproj +++ b/Frameworks/Database/Database.xcodeproj/project.pbxproj @@ -20,16 +20,16 @@ 845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580751F0AF670003CCFA1 /* Article+Database.swift */; }; 8455807A1F0AF67D003CCFA1 /* ArticleStatus+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580791F0AF67D003CCFA1 /* ArticleStatus+Database.swift */; }; 8455807C1F0C0DBD003CCFA1 /* Attachment+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8455807B1F0C0DBD003CCFA1 /* Attachment+Database.swift */; }; - 846146271F0ABC7B00870CB3 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846146241F0ABC7400870CB3 /* RSParser.framework */; }; 846FB36B1F4A937B00EAB81D /* Feed+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846FB36A1F4A937B00EAB81D /* Feed+Database.swift */; }; 848AD2961F58A91E004FB0EC /* UnreadCountDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848AD2951F58A91E004FB0EC /* UnreadCountDictionary.swift */; }; - 84BB4BA21F119C5400858766 /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BB4B981F119C4900858766 /* RSCore.framework */; }; + 848E3EB920FBCFD20004B7ED /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EB820FBCFD20004B7ED /* RSCore.framework */; }; + 848E3EBB20FBCFD80004B7ED /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EBA20FBCFD80004B7ED /* RSParser.framework */; }; + 848E3EBD20FBCFDE0004B7ED /* RSDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EBC20FBCFDE0004B7ED /* RSDatabase.framework */; }; 84E156EA1F0AB80500F8CC05 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E156E91F0AB80500F8CC05 /* Database.swift */; }; 84E156EC1F0AB80E00F8CC05 /* ArticlesTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E156EB1F0AB80E00F8CC05 /* ArticlesTable.swift */; }; 84E156EE1F0AB81400F8CC05 /* StatusesTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E156ED1F0AB81400F8CC05 /* StatusesTable.swift */; }; 84E156F01F0AB81F00F8CC05 /* CreateStatements.sql in Resources */ = {isa = PBXBuildFile; fileRef = 84E156EF1F0AB81F00F8CC05 /* CreateStatements.sql */; }; 84E156FD1F0AB86100F8CC05 /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E156F81F0AB83600F8CC05 /* Data.framework */; }; - 84E1570C1F0AB8A500F8CC05 /* RSDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E157071F0AB89B00F8CC05 /* RSDatabase.framework */; }; 84F20F8F1F180D8700D8E682 /* AuthorsTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F20F8E1F180D8700D8E682 /* AuthorsTable.swift */; }; /* End PBXBuildFile section */ @@ -131,6 +131,9 @@ 8461461E1F0ABC7300870CB3 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = ../RSParser/RSParser.xcodeproj; sourceTree = ""; }; 846FB36A1F4A937B00EAB81D /* Feed+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Feed+Database.swift"; path = "Extensions/Feed+Database.swift"; sourceTree = ""; }; 848AD2951F58A91E004FB0EC /* UnreadCountDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadCountDictionary.swift; sourceTree = ""; }; + 848E3EB820FBCFD20004B7ED /* RSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 848E3EBA20FBCFD80004B7ED /* RSParser.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSParser.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 848E3EBC20FBCFDE0004B7ED /* RSDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84BB4B8F1F119C4900858766 /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; 84E156E81F0AB75600F8CC05 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 84E156E91F0AB80500F8CC05 /* Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = ""; }; @@ -153,9 +156,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84BB4BA21F119C5400858766 /* RSCore.framework in Frameworks */, - 846146271F0ABC7B00870CB3 /* RSParser.framework in Frameworks */, - 84E1570C1F0AB8A500F8CC05 /* RSDatabase.framework in Frameworks */, + 848E3EBD20FBCFDE0004B7ED /* RSDatabase.framework in Frameworks */, + 848E3EBB20FBCFD80004B7ED /* RSParser.framework in Frameworks */, + 848E3EB920FBCFD20004B7ED /* RSCore.framework in Frameworks */, 84E156FD1F0AB86100F8CC05 /* Data.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -257,6 +260,9 @@ 84E156FB1F0AB83A00F8CC05 /* Frameworks */ = { isa = PBXGroup; children = ( + 848E3EBC20FBCFDE0004B7ED /* RSDatabase.framework */, + 848E3EBA20FBCFD80004B7ED /* RSParser.framework */, + 848E3EB820FBCFD20004B7ED /* RSCore.framework */, 84E156F11F0AB83600F8CC05 /* Data.xcodeproj */, 84E157001F0AB89B00F8CC05 /* RSDatabase.xcodeproj */, 84BB4B8F1F119C4900858766 /* RSCore.xcodeproj */, From 73b85bdd9281b2ea714bf41b4994a74b012940ad Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 15 Jul 2018 12:06:41 -0700 Subject: [PATCH 14/40] Make sidebar status bar vibrant. Fix #369. --- .../Sidebar/SidebarStatusBarView.swift | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift b/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift index dbd4df147..e1dec5049 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift @@ -17,8 +17,6 @@ final class SidebarStatusBarView: NSView { @IBOutlet var progressIndicator: NSProgressIndicator! @IBOutlet var progressLabel: NSTextField! - private var didConfigureLayer = false - private var isAnimatingProgress = false { didSet { progressIndicator.isHidden = !isAnimatingProgress @@ -35,10 +33,6 @@ final class SidebarStatusBarView: NSView { return true } - override var wantsUpdateLayer: Bool { - return true - } - override func awakeFromNib() { progressIndicator.isHidden = true @@ -51,17 +45,6 @@ final class SidebarStatusBarView: NSView { NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil) } - override func updateLayer() { - - guard let layer = layer, !didConfigureLayer else { - return - } - - let color = NSColor(calibratedWhite: 0.96, alpha: 1.0) - layer.backgroundColor = color.cgColor - didConfigureLayer = true - } - @objc func updateUI() { guard let progress = progress else { From 2a37a90c59da7669dfad37de349ebba66130cd8f Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 15 Jul 2018 18:59:01 -0700 Subject: [PATCH 15/40] Add some dark mode notes. --- Technotes/DarkMode.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Technotes/DarkMode.md diff --git a/Technotes/DarkMode.md b/Technotes/DarkMode.md new file mode 100644 index 000000000..cf95cae43 --- /dev/null +++ b/Technotes/DarkMode.md @@ -0,0 +1,39 @@ +# Dark Mode + +https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface +https://developer.apple.com/videos/play/wwdc2018/210/ + +Accent colors +Can do preference for content — see Mail for example +linkColor — see if can use in web view +icons in sidebar should not be vibrant +Use opaque grayscale colors, not opacity, on top of vibrancy +Colors in asset catalogs + Specify for different appearances + High contrast colors +Dynamic system colors +Resolved at draw time +Pictures in asset catalogs +Template images + contentTintColor new API - NSImageView, NSButton +Render as template image thing in IB +controlAccentColor +color.withSystemEffect(.pressed) +Avoid nonsemantic materials +Semantic materials: popover, menu, sidebar, selection, titlebar, etc. +visualEffectView.material = .popover +Desktop tinted background: window background, underpage, content background +contentBackground default for collection views +Use NSAppearance to override inheritance +.aqua +.darkAqua +effectiveAppearance + +Advanced Dark Mode: + https://developer.apple.com/videos/play/wwdc2018/218/ + +Build with 10.14 SDK +NSAppearanceCustomization +NSView, NSWindow conforms +NSWindow.appearanceSource + From 2f137df4b00d8282649f13b9b3867124721093d3 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 17 Jul 2018 13:09:40 -0700 Subject: [PATCH 16/40] Use standard NSTableView grid for timeline. Fix #376. --- Evergreen/Base.lproj/MainWindow.storyboard | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Evergreen/Base.lproj/MainWindow.storyboard b/Evergreen/Base.lproj/MainWindow.storyboard index 855462a56..11abcbed6 100644 --- a/Evergreen/Base.lproj/MainWindow.storyboard +++ b/Evergreen/Base.lproj/MainWindow.storyboard @@ -1,9 +1,10 @@ - + - - + + + @@ -281,7 +282,7 @@ - + @@ -544,10 +545,11 @@ - - + + + - + @@ -763,12 +765,12 @@ - - - - - - - + + + + + + + From f8a2e7334fc2e974f74e07c1e253815fbde9f9c7 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 17 Jul 2018 18:01:17 -0700 Subject: [PATCH 17/40] Nuke the timeline grid after all. --- Evergreen/Base.lproj/MainWindow.storyboard | 34 ++++++++++------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/Evergreen/Base.lproj/MainWindow.storyboard b/Evergreen/Base.lproj/MainWindow.storyboard index 11abcbed6..d35def514 100644 --- a/Evergreen/Base.lproj/MainWindow.storyboard +++ b/Evergreen/Base.lproj/MainWindow.storyboard @@ -1,10 +1,9 @@ - + - - + + - @@ -282,7 +281,7 @@ - + @@ -352,11 +351,11 @@ - - + @@ -546,10 +545,9 @@ - - + @@ -581,13 +579,13 @@ - + - - + @@ -543,7 +543,6 @@ - @@ -565,7 +564,7 @@ - + @@ -579,6 +578,7 @@ + - + @@ -762,12 +762,12 @@ - - - - - - - + + + + + + + From 0c1fc37aa9b38855ca1d4ccde2b2e8d6f3ccae74 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 21 Jul 2018 19:55:07 -0700 Subject: [PATCH 27/40] Make progress on CSS for detail view for dark mode. --- .../MainWindow/Detail/ArticleRenderer.swift | 2 +- .../Detail/DetailViewController.swift | 34 +++++++++------- Evergreen/MainWindow/Detail/styleSheet.css | 39 ++++++++++++++----- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/Evergreen/MainWindow/Detail/ArticleRenderer.swift b/Evergreen/MainWindow/Detail/ArticleRenderer.swift index 58d846622..975cf26e4 100644 --- a/Evergreen/MainWindow/Detail/ArticleRenderer.swift +++ b/Evergreen/MainWindow/Detail/ArticleRenderer.swift @@ -453,7 +453,7 @@ class ArticleRenderer { """ - s += "\n\n\n\n" + s += "\n\n\n\n" s += RSMacroProcessor.renderedText(withTemplate: template(), substitutions: substitutions(), macroStart: "[[", macroEnd: "]]") diff --git a/Evergreen/MainWindow/Detail/DetailViewController.swift b/Evergreen/MainWindow/Detail/DetailViewController.swift index 5e0e70e9e..cf45c0804 100644 --- a/Evergreen/MainWindow/Detail/DetailViewController.swift +++ b/Evergreen/MainWindow/Detail/DetailViewController.swift @@ -249,11 +249,11 @@ final class DetailContainerView: NSView { weak var viewController: DetailViewController? = nil - private var didConfigureLayer = false - - override var wantsUpdateLayer: Bool { - return true - } +// private var didConfigureLayer = false +// +// override var wantsUpdateLayer: Bool { +// return true +// } var contentView: NSView? { didSet { @@ -278,17 +278,21 @@ final class DetailContainerView: NSView { viewController?.viewDidEndLiveResize() } - override func updateLayer() { - - guard !didConfigureLayer else { - return - } - if let layer = layer { - let color = appDelegate.currentTheme.color(forKey: "MainWindow.Detail.backgroundColor") - layer.backgroundColor = color.cgColor - didConfigureLayer = true - } + override func draw(_ dirtyRect: NSRect) { + NSColor.textBackgroundColor.setFill() + dirtyRect.fill() } +// override func updateLayer() { +// +// guard !didConfigureLayer else { +// return +// } +// if let layer = layer { +// let color = appDelegate.currentTheme.color(forKey: "MainWindow.Detail.backgroundColor") +// layer.backgroundColor = color.cgColor +// didConfigureLayer = true +// } +// } } // MARK: - diff --git a/Evergreen/MainWindow/Detail/styleSheet.css b/Evergreen/MainWindow/Detail/styleSheet.css index 8f636c4fe..966f25145 100644 --- a/Evergreen/MainWindow/Detail/styleSheet.css +++ b/Evergreen/MainWindow/Detail/styleSheet.css @@ -1,6 +1,4 @@ body { - color: #444; - background-color: white; margin-top: 20px; margin-bottom: 64px; margin-left: 64px; @@ -8,30 +6,53 @@ body { font-family: -apple-system; font-size: 18px; } + a { text-decoration: none; } -a, a:link, a:visited { - color: #416ED2; -} a:hover { text-decoration: underline; } - +.feedlink { + font-weight: bold; +} .headerTable { width: 100%; height: 68px; +} + +/* Light mode */ + +body.light { + color: -webkit-text; + background-color: -apple-system-text-background; +} + +body.light a, body.light a:link, body.light a:visited { + color: -apple-system-blue; +} +body.light .headerTable { border-bottom: 1px solid rgba(0, 0, 0, 0.1); } +/* Dark mode */ + +body.dark { + color: #d2d2d2; + background-color: #2d2d2d; +} +body.dark a, body.dark a:link, body.dark a:visited { + color: #4490e2; +} +body.dark .headerTable { + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + .header a:link, .header a:visited { color: rgba(0, 0, 0, 0.3); } .header { color: rgba(0, 0, 0, 0.3); } -.feedlink { - font-weight: bold; -} .feedlink a:link, .feedlink a:visited { color: rgba(0, 0, 0, 0.6); } From d6303ebead4731d577ff096dc065aacfcfa36698 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 21 Jul 2018 19:55:35 -0700 Subject: [PATCH 28/40] Submodule stuff? Git confuses me. --- submodules/DB5 | 2 +- submodules/RSDatabase | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/submodules/DB5 b/submodules/DB5 index 6b32b49be..1b20fde3a 160000 --- a/submodules/DB5 +++ b/submodules/DB5 @@ -1 +1 @@ -Subproject commit 6b32b49bed78535ae0e608a23edf04df5a9a0c70 +Subproject commit 1b20fde3a79dc6b81e7fcb63c81aee8add56e380 diff --git a/submodules/RSDatabase b/submodules/RSDatabase index 4e7358074..7da35125f 160000 --- a/submodules/RSDatabase +++ b/submodules/RSDatabase @@ -1 +1 @@ -Subproject commit 4e7358074ed3c358ebfe3741a38f43e020665694 +Subproject commit 7da35125ffb8b29f918797b0e5f38dd56551f9ed From 457bb729ab96826d965942e6665caa6c41df361b Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 22 Jul 2018 11:18:35 -0700 Subject: [PATCH 29/40] Remove some hard-coded white backgrounds. --- Evergreen/Base.lproj/MainWindow.storyboard | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/Evergreen/Base.lproj/MainWindow.storyboard b/Evergreen/Base.lproj/MainWindow.storyboard index 81f249637..095aef4d2 100644 --- a/Evergreen/Base.lproj/MainWindow.storyboard +++ b/Evergreen/Base.lproj/MainWindow.storyboard @@ -210,7 +210,7 @@ - + @@ -238,11 +238,6 @@ - - - - - @@ -599,11 +594,6 @@ - - - - - @@ -681,11 +671,6 @@ - - - - - From 2601cb11546a25e008229c2017233e355786c160 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 22 Jul 2018 19:39:01 -0700 Subject: [PATCH 30/40] Submodule stuff. --- submodules/DB5 | 2 +- submodules/RSDatabase | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/submodules/DB5 b/submodules/DB5 index 1b20fde3a..6b32b49be 160000 --- a/submodules/DB5 +++ b/submodules/DB5 @@ -1 +1 @@ -Subproject commit 1b20fde3a79dc6b81e7fcb63c81aee8add56e380 +Subproject commit 6b32b49bed78535ae0e608a23edf04df5a9a0c70 diff --git a/submodules/RSDatabase b/submodules/RSDatabase index 7da35125f..4e7358074 160000 --- a/submodules/RSDatabase +++ b/submodules/RSDatabase @@ -1 +1 @@ -Subproject commit 7da35125ffb8b29f918797b0e5f38dd56551f9ed +Subproject commit 4e7358074ed3c358ebfe3741a38f43e020665694 From 19bf197f020f4b46572447833804a9d7a5d8abe3 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Mon, 23 Jul 2018 15:30:42 -0700 Subject: [PATCH 31/40] Start FeedMetadata. --- Frameworks/Account/FeedMetadata.swift | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Frameworks/Account/FeedMetadata.swift diff --git a/Frameworks/Account/FeedMetadata.swift b/Frameworks/Account/FeedMetadata.swift new file mode 100644 index 000000000..ea57c536b --- /dev/null +++ b/Frameworks/Account/FeedMetadata.swift @@ -0,0 +1,9 @@ +// +// FeedMetadata.swift +// Account +// +// Created by Brent Simmons on 7/22/18. +// Copyright © 2018 Ranchero Software, LLC. All rights reserved. +// + +import Foundation From 83d0c726a14861a83cb56ffdb7fecebedc2d5842 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Mon, 23 Jul 2018 15:30:53 -0700 Subject: [PATCH 32/40] RSDatabase update. --- submodules/RSDatabase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/RSDatabase b/submodules/RSDatabase index 7da35125f..8a346eff6 160000 --- a/submodules/RSDatabase +++ b/submodules/RSDatabase @@ -1 +1 @@ -Subproject commit 7da35125ffb8b29f918797b0e5f38dd56551f9ed +Subproject commit 8a346eff6ad6a529c39b736ea802182b5edd3f5f From b7575c687c28a4e8a15f37076efa77279c1bd2cd Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Mon, 23 Jul 2018 18:29:08 -0700 Subject: [PATCH 33/40] Rename Data.framework to Articles.framework. Rename Database.framework to ArticlesDatabase.framework. --- Commands/DeleteFromSidebarCommand.swift | 2 +- Commands/MarkStatusCommand.swift | 2 +- Commands/SendToMarsEditCommand.swift | 2 +- Commands/SendToMicroBlogCommand.swift | 2 +- Evergreen.xcodeproj/project.pbxproj | 183 ++++++++---------- Evergreen/AppDelegate.swift | 2 +- Evergreen/AppNotifications.swift | 2 +- Evergreen/Data/ArticleUtilities.swift | 2 +- Evergreen/Data/SmallIconProvider.swift | 2 +- Evergreen/Extensions/Node-Extensions.swift | 2 +- Evergreen/Favicons/FaviconDownloader.swift | 2 +- Evergreen/FeedList/FeedListFolder.swift | 2 +- Evergreen/Images/AuthorAvatarDownloader.swift | 2 +- .../Images/FeaturedImageDownloader.swift | 2 +- Evergreen/Images/FeedIconDownloader.swift | 2 +- .../FeedInspectorViewController.swift | 2 +- .../AddFeed/AddFeedController.swift | 2 +- .../AddFeed/AddFeedWindowController.swift | 2 +- .../FolderTreeControllerDelegate.swift | 2 +- .../AddFolder/AddFolderWindowController.swift | 2 +- .../MainWindow/Detail/ArticleRenderer.swift | 2 +- .../Detail/DetailStatusBarView.swift | 2 +- .../Detail/DetailViewController.swift | 2 +- .../MainWindow/MainWindowController.swift | 2 +- .../Sidebar/FeedPasteboardWriter.swift | 2 +- .../Sidebar/SidebarOutlineDataSource.swift | 2 +- .../Sidebar/SidebarStatusBarView.swift | 2 +- .../SidebarTreeControllerDelegate.swift | 2 +- ...idebarViewController+ContextualMenus.swift | 2 +- .../Sidebar/SidebarViewController.swift | 2 +- .../MainWindow/Timeline/ArticleArray.swift | 2 +- .../Timeline/ArticlePasteboardWriter.swift | 2 +- .../Timeline/Cell/TimelineCellData.swift | 2 +- .../Cell/TimelineStringUtilities.swift | 2 +- ...melineViewController+ContextualMenus.swift | 2 +- .../Timeline/TimelineViewController.swift | 2 +- .../Scriptability/Account+Scriptability.swift | 2 +- .../AppDelegate+Scriptability.swift | 2 +- .../Scriptability/Article+Scriptability.swift | 2 +- .../Scriptability/Author+Scriptability.swift | 2 +- .../Scriptability/Feed+Scriptability.swift | 2 +- .../Scriptability/Folder+Scriptability.swift | 2 +- .../MainWindowController+Scriptability.swift | 2 +- .../NSApplication+Scriptability.swift | 2 +- Evergreen/SmartFeeds/PseudoFeed.swift | 2 +- Evergreen/SmartFeeds/SmartFeed.swift | 2 +- .../SmartFeeds/StarredFeedDelegate.swift | 2 +- Evergreen/SmartFeeds/TodayFeedDelegate.swift | 2 +- Evergreen/SmartFeeds/UnreadFeed.swift | 2 +- Frameworks/Account/Account.swift | 8 +- .../Account/Account.xcodeproj/project.pbxproj | 12 +- Frameworks/Account/AccountManager.swift | 2 +- Frameworks/Account/ArticleFetcher.swift | 2 +- Frameworks/Account/Container.swift | 2 +- Frameworks/Account/DataExtensions.swift | 2 +- Frameworks/Account/Folder.swift | 2 +- .../LocalAccount/LocalAccountRefresher.swift | 2 +- Frameworks/{Data => Articles}/Article.swift | 0 .../{Data => Articles}/ArticleStatus.swift | 0 .../Articles.xcodeproj}/project.pbxproj | 100 +++++----- .../contents.xcworkspacedata | 0 .../xcshareddata/xcschemes/Articles.xcscheme | 80 ++++++++ .../{Data => Articles}/Attachment.swift | 0 Frameworks/{Data => Articles}/Author.swift | 0 .../DataTests/DataTests.swift | 2 +- .../{Data => Articles}/DataTests/Info.plist | 0 .../{Data => Articles}/DatabaseID.swift | 0 Frameworks/{Data => Articles}/Feed.swift | 0 Frameworks/{Data => Articles}/Info.plist | 0 .../UnreadCountProvider.swift | 0 .../ArticlesDataTests_target.xcconfig} | 2 +- .../xcconfig/Articles_project.xcconfig} | 0 .../xcconfig/Articles_project_debug.xcconfig} | 2 +- .../Articles_project_release.xcconfig} | 2 +- .../xcconfig/Articles_target.xcconfig} | 2 +- .../ArticlesDatabase.swift} | 6 +- .../project.pbxproj | 94 +++++---- .../contents.xcworkspacedata | 0 .../ArticlesTable.swift | 2 +- .../AttachmentsTable.swift | 2 +- .../AuthorsTable.swift | 2 +- .../Constants.swift | 0 .../CreateStatements.sql | 0 .../DatabaseArticle.swift | 2 +- .../DatabaseObject+Database.swift | 2 +- .../DatabaseTests/ArticleChangesTests.swift | 2 +- .../DatabaseTests/DatabaseTests.swift | 2 +- .../DatabaseTests/Info.plist | 0 .../Extensions/Article+Database.swift | 2 +- .../Extensions/ArticleStatus+Database.swift | 2 +- .../Extensions/Attachment+Database.swift | 2 +- .../Extensions/Author+Database.swift | 2 +- .../Extensions/Feed+Database.swift | 2 +- .../Extensions/ParsedArticle+Database.swift | 2 +- .../{Database => ArticlesDatabase}/Info.plist | 0 .../RelatedObjectsMap+Database.swift | 2 +- .../StatusesTable.swift | 2 +- .../UnreadCountDictionary.swift | 2 +- .../ArticlesDatabaseTests_target.xcconfig} | 2 +- .../ArticlesDatabase_project.xcconfig} | 0 .../ArticlesDatabase_project_debug.xcconfig} | 2 +- ...ArticlesDatabase_project_release.xcconfig} | 2 +- .../ArticlesDatabase_target.xcconfig} | 2 +- Importers/DefaultFeedsImporter.swift | 2 +- 104 files changed, 354 insertions(+), 289 deletions(-) rename Frameworks/{Data => Articles}/Article.swift (100%) rename Frameworks/{Data => Articles}/ArticleStatus.swift (100%) rename Frameworks/{Data/Data.xcodeproj => Articles/Articles.xcodeproj}/project.pbxproj (76%) rename Frameworks/{Data/Data.xcodeproj => Articles/Articles.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (100%) create mode 100644 Frameworks/Articles/Articles.xcodeproj/xcshareddata/xcschemes/Articles.xcscheme rename Frameworks/{Data => Articles}/Attachment.swift (100%) rename Frameworks/{Data => Articles}/Author.swift (100%) rename Frameworks/{Data => Articles}/DataTests/DataTests.swift (97%) rename Frameworks/{Data => Articles}/DataTests/Info.plist (100%) rename Frameworks/{Data => Articles}/DatabaseID.swift (100%) rename Frameworks/{Data => Articles}/Feed.swift (100%) rename Frameworks/{Data => Articles}/Info.plist (100%) rename Frameworks/{Data => Articles}/UnreadCountProvider.swift (100%) rename Frameworks/{Data/xcconfig/DataTests_target.xcconfig => Articles/xcconfig/ArticlesDataTests_target.xcconfig} (79%) rename Frameworks/{Data/xcconfig/Data_project.xcconfig => Articles/xcconfig/Articles_project.xcconfig} (100%) rename Frameworks/{Data/xcconfig/Data_project_debug.xcconfig => Articles/xcconfig/Articles_project_debug.xcconfig} (88%) rename Frameworks/{Database/xcconfig/Database_project_release.xcconfig => Articles/xcconfig/Articles_project_release.xcconfig} (79%) rename Frameworks/{Data/xcconfig/Data_target.xcconfig => Articles/xcconfig/Articles_target.xcconfig} (88%) rename Frameworks/{Database/Database.swift => ArticlesDatabase/ArticlesDatabase.swift} (97%) rename Frameworks/{Database/Database.xcodeproj => ArticlesDatabase/ArticlesDatabase.xcodeproj}/project.pbxproj (84%) rename Frameworks/{Database/Database.xcodeproj => ArticlesDatabase/ArticlesDatabase.xcodeproj}/project.xcworkspace/contents.xcworkspacedata (100%) rename Frameworks/{Database => ArticlesDatabase}/ArticlesTable.swift (99%) rename Frameworks/{Database => ArticlesDatabase}/AttachmentsTable.swift (97%) rename Frameworks/{Database => ArticlesDatabase}/AuthorsTable.swift (98%) rename Frameworks/{Database => ArticlesDatabase}/Constants.swift (100%) rename Frameworks/{Database => ArticlesDatabase}/CreateStatements.sql (100%) rename Frameworks/{Database => ArticlesDatabase}/DatabaseArticle.swift (99%) rename Frameworks/{Database => ArticlesDatabase}/DatabaseObject+Database.swift (97%) rename Frameworks/{Database => ArticlesDatabase}/DatabaseTests/ArticleChangesTests.swift (86%) rename Frameworks/{Database => ArticlesDatabase}/DatabaseTests/DatabaseTests.swift (96%) rename Frameworks/{Database => ArticlesDatabase}/DatabaseTests/Info.plist (100%) rename Frameworks/{Database => ArticlesDatabase}/Extensions/Article+Database.swift (99%) rename Frameworks/{Database => ArticlesDatabase}/Extensions/ArticleStatus+Database.swift (98%) rename Frameworks/{Database => ArticlesDatabase}/Extensions/Attachment+Database.swift (99%) rename Frameworks/{Database => ArticlesDatabase}/Extensions/Author+Database.swift (99%) rename Frameworks/{Database => ArticlesDatabase}/Extensions/Feed+Database.swift (94%) rename Frameworks/{Database => ArticlesDatabase}/Extensions/ParsedArticle+Database.swift (96%) rename Frameworks/{Database => ArticlesDatabase}/Info.plist (100%) rename Frameworks/{Database => ArticlesDatabase}/RelatedObjectsMap+Database.swift (97%) rename Frameworks/{Database => ArticlesDatabase}/StatusesTable.swift (99%) rename Frameworks/{Database => ArticlesDatabase}/UnreadCountDictionary.swift (97%) rename Frameworks/{Database/xcconfig/DatabaseTests_target.xcconfig => ArticlesDatabase/xcconfig/ArticlesDatabaseTests_target.xcconfig} (78%) rename Frameworks/{Database/xcconfig/Database_project.xcconfig => ArticlesDatabase/xcconfig/ArticlesDatabase_project.xcconfig} (100%) rename Frameworks/{Database/xcconfig/Database_project_debug.xcconfig => ArticlesDatabase/xcconfig/ArticlesDatabase_project_debug.xcconfig} (87%) rename Frameworks/{Data/xcconfig/Data_project_release.xcconfig => ArticlesDatabase/xcconfig/ArticlesDatabase_project_release.xcconfig} (77%) rename Frameworks/{Database/xcconfig/Database_target.xcconfig => ArticlesDatabase/xcconfig/ArticlesDatabase_target.xcconfig} (88%) diff --git a/Commands/DeleteFromSidebarCommand.swift b/Commands/DeleteFromSidebarCommand.swift index a93bed08c..5c7e465bf 100644 --- a/Commands/DeleteFromSidebarCommand.swift +++ b/Commands/DeleteFromSidebarCommand.swift @@ -10,7 +10,7 @@ import Foundation import RSCore import RSTree import Account -import Data +import Articles final class DeleteFromSidebarCommand: UndoableCommand { diff --git a/Commands/MarkStatusCommand.swift b/Commands/MarkStatusCommand.swift index b3a655e85..abd7cda05 100644 --- a/Commands/MarkStatusCommand.swift +++ b/Commands/MarkStatusCommand.swift @@ -8,7 +8,7 @@ import Foundation import RSCore -import Data +import Articles // Mark articles read/unread, starred/unstarred, deleted/undeleted. diff --git a/Commands/SendToMarsEditCommand.swift b/Commands/SendToMarsEditCommand.swift index 364ce6787..bdad71d87 100644 --- a/Commands/SendToMarsEditCommand.swift +++ b/Commands/SendToMarsEditCommand.swift @@ -8,7 +8,7 @@ import AppKit import RSCore -import Data +import Articles final class SendToMarsEditCommand: SendToCommand { diff --git a/Commands/SendToMicroBlogCommand.swift b/Commands/SendToMicroBlogCommand.swift index c3b46e782..fd0c8870a 100644 --- a/Commands/SendToMicroBlogCommand.swift +++ b/Commands/SendToMicroBlogCommand.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import RSCore // Not undoable. diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index bb66c1263..9634a3b5e 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ 841ABA4E20145E7300980E11 /* NothingInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841ABA4D20145E7300980E11 /* NothingInspectorViewController.swift */; }; 841ABA5E20145E9200980E11 /* FolderInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841ABA5D20145E9200980E11 /* FolderInspectorViewController.swift */; }; 841ABA6020145EC100980E11 /* BuiltinSmartFeedInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841ABA5F20145EC100980E11 /* BuiltinSmartFeedInspectorViewController.swift */; }; + 841D4D6B2106B3ED00DD04E6 /* Articles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841D4D5B2106B3D600DD04E6 /* Articles.framework */; }; + 841D4D6C2106B3ED00DD04E6 /* Articles.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 841D4D5B2106B3D600DD04E6 /* Articles.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8426118A1FCB67AA0086A189 /* FeedIconDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842611891FCB67AA0086A189 /* FeedIconDownloader.swift */; }; 8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8426119D1FCB6ED40086A189 /* HTMLMetadataDownloader.swift */; }; 842611A01FCB72600086A189 /* FeaturedImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8426119F1FCB72600086A189 /* FeaturedImageDownloader.swift */; }; @@ -48,8 +50,6 @@ 845F52ED1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */; }; 846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; }; 846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 846E773A1F6EF5D700A165E2 /* Account.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 846E77411F6EF6A100A165E2 /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846E77211F6EF5D100A165E2 /* Database.framework */; }; - 846E77421F6EF6A100A165E2 /* Database.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 846E77211F6EF5D100A165E2 /* Database.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84702AA41FA27AC0006B8943 /* MarkStatusCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */; }; 8472058120142E8900AD578B /* FeedInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8472058020142E8900AD578B /* FeedInspectorViewController.swift */; }; 847FA121202BA34100BB56C8 /* SidebarContextualMenuDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847FA120202BA34100BB56C8 /* SidebarContextualMenuDelegate.swift */; }; @@ -114,8 +114,6 @@ 84B99C691FAE36B800ECDEDB /* FeedListFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C681FAE36B800ECDEDB /* FeedListFolder.swift */; }; 84B99C6B1FAE370B00ECDEDB /* FeedListFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C6A1FAE370B00ECDEDB /* FeedListFeed.swift */; }; 84B99C9D1FAE83C600ECDEDB /* DeleteFromSidebarCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B99C9C1FAE83C600ECDEDB /* DeleteFromSidebarCommand.swift */; }; - 84BB4B771F11753300858766 /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BB4B681F1174D400858766 /* Data.framework */; }; - 84BB4B781F11753300858766 /* Data.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84BB4B681F1174D400858766 /* Data.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84BBB12D20142A4700F054F5 /* Inspector.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84BBB12B20142A4700F054F5 /* Inspector.storyboard */; }; 84BBB12E20142A4700F054F5 /* InspectorWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BBB12C20142A4700F054F5 /* InspectorWindowController.swift */; }; 84C12A151FF5B0080009A267 /* FeedList.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84C12A141FF5B0080009A267 /* FeedList.storyboard */; }; @@ -221,19 +219,40 @@ remoteGlobalIDString = 840D617B2029031C009BC708; remoteInfo = "Evergreen-iOS"; }; - 846E77201F6EF5D100A165E2 /* PBXContainerItemProxy */ = { + 841D4D5A2106B3D600DD04E6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 846E77161F6EF5D000A165E2 /* Database.xcodeproj */; + containerPortal = 841D4D542106B3D500DD04E6 /* Articles.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 844BEE5B1F0AB3C8004AB7CD; + remoteInfo = Articles; + }; + 841D4D5C2106B3D600DD04E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841D4D542106B3D500DD04E6 /* Articles.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 844BEE641F0AB3C9004AB7CD; + remoteInfo = ArticlesTests; + }; + 841D4D672106B3E100DD04E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841D4D5E2106B3E100DD04E6 /* ArticlesDatabase.xcodeproj */; proxyType = 2; remoteGlobalIDString = 844BEE371F0AB3AA004AB7CD; - remoteInfo = Database; + remoteInfo = ArticlesDatabase; }; - 846E77221F6EF5D100A165E2 /* PBXContainerItemProxy */ = { + 841D4D692106B3E100DD04E6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 846E77161F6EF5D000A165E2 /* Database.xcodeproj */; + containerPortal = 841D4D5E2106B3E100DD04E6 /* ArticlesDatabase.xcodeproj */; proxyType = 2; remoteGlobalIDString = 844BEE401F0AB3AB004AB7CD; - remoteInfo = DatabaseTests; + remoteInfo = ArticlesDatabaseTests; + }; + 841D4D6D2106B3ED00DD04E6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 841D4D542106B3D500DD04E6 /* Articles.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 844BEE5A1F0AB3C8004AB7CD; + remoteInfo = Articles; }; 846E77391F6EF5D700A165E2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -256,13 +275,6 @@ remoteGlobalIDString = 848934F51F62484F00CEBD24; remoteInfo = Account; }; - 846E77431F6EF6A100A165E2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 846E77161F6EF5D000A165E2 /* Database.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 844BEE361F0AB3AA004AB7CD; - remoteInfo = Database; - }; 849C64721ED37A5D003D8FC0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 849C64581ED37A5D003D8FC0 /* Project object */; @@ -270,27 +282,6 @@ remoteGlobalIDString = 849C645F1ED37A5D003D8FC0; remoteInfo = Evergreen; }; - 84BB4B671F1174D400858766 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84BB4B611F1174D400858766 /* Data.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 844BEE5B1F0AB3C8004AB7CD; - remoteInfo = Data; - }; - 84BB4B691F1174D400858766 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84BB4B611F1174D400858766 /* Data.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 844BEE641F0AB3C9004AB7CD; - remoteInfo = DataTests; - }; - 84BB4B791F11753300858766 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 84BB4B611F1174D400858766 /* Data.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 844BEE5A1F0AB3C8004AB7CD; - remoteInfo = Data; - }; 84C37F2720DD8CCE00CA8CF5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */; @@ -448,15 +439,14 @@ dstSubfolderSpec = 10; files = ( 84C37FAA20DD8D9000CA8CF5 /* RSWeb.framework in Embed Frameworks */, - 84BB4B781F11753300858766 /* Data.framework in Embed Frameworks */, 84C37FC620DD8E1D00CA8CF5 /* RSDatabase.framework in Embed Frameworks */, 84C37FAE20DD8D9900CA8CF5 /* RSTree.framework in Embed Frameworks */, 84FB9A301EDCD6C4003D53B9 /* Sparkle.framework in Embed Frameworks */, 84C37FB220DD8DA100CA8CF5 /* DB5.framework in Embed Frameworks */, 84C37FB620DD8DBB00CA8CF5 /* RSParser.framework in Embed Frameworks */, - 846E77421F6EF6A100A165E2 /* Database.framework in Embed Frameworks */, 84C37FA620DD8D8400CA8CF5 /* RSCore.framework in Embed Frameworks */, 846E773E1F6EF67A00A165E2 /* Account.framework in Embed Frameworks */, + 841D4D6C2106B3ED00DD04E6 /* Articles.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -509,6 +499,8 @@ 841ABA4D20145E7300980E11 /* NothingInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NothingInspectorViewController.swift; sourceTree = ""; }; 841ABA5D20145E9200980E11 /* FolderInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderInspectorViewController.swift; sourceTree = ""; }; 841ABA5F20145EC100980E11 /* BuiltinSmartFeedInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuiltinSmartFeedInspectorViewController.swift; sourceTree = ""; }; + 841D4D542106B3D500DD04E6 /* Articles.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Articles.xcodeproj; path = Frameworks/Articles/Articles.xcodeproj; sourceTree = ""; }; + 841D4D5E2106B3E100DD04E6 /* ArticlesDatabase.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ArticlesDatabase.xcodeproj; path = Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj; sourceTree = ""; }; 842611891FCB67AA0086A189 /* FeedIconDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedIconDownloader.swift; sourceTree = ""; }; 8426119D1FCB6ED40086A189 /* HTMLMetadataDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTMLMetadataDownloader.swift; sourceTree = ""; }; 8426119F1FCB72600086A189 /* FeaturedImageDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedImageDownloader.swift; sourceTree = ""; }; @@ -536,7 +528,6 @@ 845EE7B01FC2366500854A1F /* StarredFeedDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarredFeedDelegate.swift; sourceTree = ""; }; 845EE7C01FC2488C00854A1F /* SmartFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartFeed.swift; sourceTree = ""; }; 845F52EC1FB2B9FC00C10BF0 /* FeedPasteboardWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedPasteboardWriter.swift; sourceTree = ""; }; - 846E77161F6EF5D000A165E2 /* Database.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Database.xcodeproj; path = Frameworks/Database/Database.xcodeproj; sourceTree = ""; }; 846E77301F6EF5D600A165E2 /* Account.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Account.xcodeproj; path = Frameworks/Account/Account.xcodeproj; sourceTree = ""; }; 84702AA31FA27AC0006B8943 /* MarkStatusCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkStatusCommand.swift; sourceTree = ""; }; 8472058020142E8900AD578B /* FeedInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedInspectorViewController.swift; sourceTree = ""; }; @@ -609,7 +600,6 @@ 84B99C681FAE36B800ECDEDB /* FeedListFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListFolder.swift; sourceTree = ""; }; 84B99C6A1FAE370B00ECDEDB /* FeedListFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedListFeed.swift; sourceTree = ""; }; 84B99C9C1FAE83C600ECDEDB /* DeleteFromSidebarCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteFromSidebarCommand.swift; sourceTree = ""; }; - 84BB4B611F1174D400858766 /* Data.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Data.xcodeproj; path = Frameworks/Data/Data.xcodeproj; sourceTree = ""; }; 84BBB12B20142A4700F054F5 /* Inspector.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Inspector.storyboard; sourceTree = ""; }; 84BBB12C20142A4700F054F5 /* InspectorWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InspectorWindowController.swift; sourceTree = ""; }; 84C12A141FF5B0080009A267 /* FeedList.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = FeedList.storyboard; sourceTree = ""; }; @@ -710,15 +700,14 @@ buildActionMask = 2147483647; files = ( 84C37FA920DD8D9000CA8CF5 /* RSWeb.framework in Frameworks */, - 84BB4B771F11753300858766 /* Data.framework in Frameworks */, 84C37FC520DD8E1D00CA8CF5 /* RSDatabase.framework in Frameworks */, 84C37FAD20DD8D9900CA8CF5 /* RSTree.framework in Frameworks */, - 846E77411F6EF6A100A165E2 /* Database.framework in Frameworks */, 84C37FB120DD8DA100CA8CF5 /* DB5.framework in Frameworks */, 84C37FB520DD8DBB00CA8CF5 /* RSParser.framework in Frameworks */, 846E773D1F6EF67A00A165E2 /* Account.framework in Frameworks */, 84C37FA520DD8D8400CA8CF5 /* RSCore.framework in Frameworks */, 84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */, + 841D4D6B2106B3ED00DD04E6 /* Articles.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -764,6 +753,24 @@ path = "Evergreen-iOSUITests"; sourceTree = ""; }; + 841D4D552106B3D500DD04E6 /* Products */ = { + isa = PBXGroup; + children = ( + 841D4D5B2106B3D600DD04E6 /* Articles.framework */, + 841D4D5D2106B3D600DD04E6 /* ArticlesTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 841D4D5F2106B3E100DD04E6 /* Products */ = { + isa = PBXGroup; + children = ( + 841D4D682106B3E100DD04E6 /* ArticlesDatabase.framework */, + 841D4D6A2106B3E100DD04E6 /* ArticlesDatabaseTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; 8426119C1FCB6ED40086A189 /* HTMLMetadata */ = { isa = PBXGroup; children = ( @@ -860,15 +867,6 @@ path = Cell; sourceTree = ""; }; - 846E77171F6EF5D000A165E2 /* Products */ = { - isa = PBXGroup; - children = ( - 846E77211F6EF5D100A165E2 /* Database.framework */, - 846E77231F6EF5D100A165E2 /* DatabaseTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; 846E77311F6EF5D600A165E2 /* Products */ = { isa = PBXGroup; children = ( @@ -1100,8 +1098,8 @@ D5907CDA2002F084005947E5 /* xcconfig */, 849C64611ED37A5D003D8FC0 /* Products */, 846E77301F6EF5D600A165E2 /* Account.xcodeproj */, - 84BB4B611F1174D400858766 /* Data.xcodeproj */, - 846E77161F6EF5D000A165E2 /* Database.xcodeproj */, + 841D4D542106B3D500DD04E6 /* Articles.xcodeproj */, + 841D4D5E2106B3E100DD04E6 /* ArticlesDatabase.xcodeproj */, 84C37F2220DD8CCD00CA8CF5 /* DB5.xcodeproj */, 84C37F7A20DD8CF200CA8CF5 /* RSCore.xcodeproj */, 84C37FB920DD8E0C00CA8CF5 /* RSDatabase.xcodeproj */, @@ -1152,15 +1150,6 @@ path = Evergreen/Dinosaurs; sourceTree = ""; }; - 84BB4B621F1174D400858766 /* Products */ = { - isa = PBXGroup; - children = ( - 84BB4B681F1174D400858766 /* Data.framework */, - 84BB4B6A1F1174D400858766 /* DataTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; 84BBB12A20142A4700F054F5 /* Inspector */ = { isa = PBXGroup; children = ( @@ -1438,15 +1427,14 @@ buildRules = ( ); dependencies = ( - 84BB4B7A1F11753300858766 /* PBXTargetDependency */, 846E77401F6EF67A00A165E2 /* PBXTargetDependency */, - 846E77441F6EF6A100A165E2 /* PBXTargetDependency */, 84C37FA820DD8D8400CA8CF5 /* PBXTargetDependency */, 84C37FAC20DD8D9000CA8CF5 /* PBXTargetDependency */, 84C37FB020DD8D9900CA8CF5 /* PBXTargetDependency */, 84C37FB420DD8DA100CA8CF5 /* PBXTargetDependency */, 84C37FB820DD8DBB00CA8CF5 /* PBXTargetDependency */, 84C37FC820DD8E1D00CA8CF5 /* PBXTargetDependency */, + 841D4D6E2106B3ED00DD04E6 /* PBXTargetDependency */, ); name = Evergreen; productName = Evergreen; @@ -1529,12 +1517,12 @@ ProjectRef = 846E77301F6EF5D600A165E2 /* Account.xcodeproj */; }, { - ProductGroup = 84BB4B621F1174D400858766 /* Products */; - ProjectRef = 84BB4B611F1174D400858766 /* Data.xcodeproj */; + ProductGroup = 841D4D552106B3D500DD04E6 /* Products */; + ProjectRef = 841D4D542106B3D500DD04E6 /* Articles.xcodeproj */; }, { - ProductGroup = 846E77171F6EF5D000A165E2 /* Products */; - ProjectRef = 846E77161F6EF5D000A165E2 /* Database.xcodeproj */; + ProductGroup = 841D4D5F2106B3E100DD04E6 /* Products */; + ProjectRef = 841D4D5E2106B3E100DD04E6 /* ArticlesDatabase.xcodeproj */; }, { ProductGroup = 84C37F2320DD8CCD00CA8CF5 /* Products */; @@ -1573,18 +1561,32 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - 846E77211F6EF5D100A165E2 /* Database.framework */ = { + 841D4D5B2106B3D600DD04E6 /* Articles.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = Database.framework; - remoteRef = 846E77201F6EF5D100A165E2 /* PBXContainerItemProxy */; + path = Articles.framework; + remoteRef = 841D4D5A2106B3D600DD04E6 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 846E77231F6EF5D100A165E2 /* DatabaseTests.xctest */ = { + 841D4D5D2106B3D600DD04E6 /* ArticlesTests.xctest */ = { isa = PBXReferenceProxy; fileType = wrapper.cfbundle; - path = DatabaseTests.xctest; - remoteRef = 846E77221F6EF5D100A165E2 /* PBXContainerItemProxy */; + path = ArticlesTests.xctest; + remoteRef = 841D4D5C2106B3D600DD04E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841D4D682106B3E100DD04E6 /* ArticlesDatabase.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = ArticlesDatabase.framework; + remoteRef = 841D4D672106B3E100DD04E6 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 841D4D6A2106B3E100DD04E6 /* ArticlesDatabaseTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = ArticlesDatabaseTests.xctest; + remoteRef = 841D4D692106B3E100DD04E6 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 846E773A1F6EF5D700A165E2 /* Account.framework */ = { @@ -1601,20 +1603,6 @@ remoteRef = 846E773B1F6EF5D700A165E2 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 84BB4B681F1174D400858766 /* Data.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = Data.framework; - remoteRef = 84BB4B671F1174D400858766 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 84BB4B6A1F1174D400858766 /* DataTests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = DataTests.xctest; - remoteRef = 84BB4B691F1174D400858766 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 84C37F2820DD8CCE00CA8CF5 /* DB5.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -1987,26 +1975,21 @@ target = 840D617B2029031C009BC708 /* Evergreen-iOS */; targetProxy = 840D619D2029031E009BC708 /* PBXContainerItemProxy */; }; + 841D4D6E2106B3ED00DD04E6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Articles; + targetProxy = 841D4D6D2106B3ED00DD04E6 /* PBXContainerItemProxy */; + }; 846E77401F6EF67A00A165E2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Account; targetProxy = 846E773F1F6EF67A00A165E2 /* PBXContainerItemProxy */; }; - 846E77441F6EF6A100A165E2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Database; - targetProxy = 846E77431F6EF6A100A165E2 /* PBXContainerItemProxy */; - }; 849C64731ED37A5D003D8FC0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 849C645F1ED37A5D003D8FC0 /* Evergreen */; targetProxy = 849C64721ED37A5D003D8FC0 /* PBXContainerItemProxy */; }; - 84BB4B7A1F11753300858766 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = Data; - targetProxy = 84BB4B791F11753300858766 /* PBXContainerItemProxy */; - }; 84C37FA820DD8D8400CA8CF5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = RSCore; diff --git a/Evergreen/AppDelegate.swift b/Evergreen/AppDelegate.swift index 9b1850c7c..29324770c 100644 --- a/Evergreen/AppDelegate.swift +++ b/Evergreen/AppDelegate.swift @@ -8,7 +8,7 @@ import AppKit import DB5 -import Data +import Articles import RSTree import RSWeb import Account diff --git a/Evergreen/AppNotifications.swift b/Evergreen/AppNotifications.swift index 5ea7cac55..3eaaacf70 100644 --- a/Evergreen/AppNotifications.swift +++ b/Evergreen/AppNotifications.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles extension Notification.Name { diff --git a/Evergreen/Data/ArticleUtilities.swift b/Evergreen/Data/ArticleUtilities.swift index c34b22731..4277d22a9 100644 --- a/Evergreen/Data/ArticleUtilities.swift +++ b/Evergreen/Data/ArticleUtilities.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import Account // These handle multiple accounts. diff --git a/Evergreen/Data/SmallIconProvider.swift b/Evergreen/Data/SmallIconProvider.swift index a602c359c..4878290f9 100644 --- a/Evergreen/Data/SmallIconProvider.swift +++ b/Evergreen/Data/SmallIconProvider.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import Account protocol SmallIconProvider { diff --git a/Evergreen/Extensions/Node-Extensions.swift b/Evergreen/Extensions/Node-Extensions.swift index 362250c54..14839f8e9 100644 --- a/Evergreen/Extensions/Node-Extensions.swift +++ b/Evergreen/Extensions/Node-Extensions.swift @@ -8,7 +8,7 @@ import Foundation import RSTree -import Data +import Articles import RSCore extension Array where Element == Node { diff --git a/Evergreen/Favicons/FaviconDownloader.swift b/Evergreen/Favicons/FaviconDownloader.swift index 8ad2e00a1..a217543b9 100644 --- a/Evergreen/Favicons/FaviconDownloader.swift +++ b/Evergreen/Favicons/FaviconDownloader.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import RSCore extension Notification.Name { diff --git a/Evergreen/FeedList/FeedListFolder.swift b/Evergreen/FeedList/FeedListFolder.swift index ec02eff26..5a3689680 100644 --- a/Evergreen/FeedList/FeedListFolder.swift +++ b/Evergreen/FeedList/FeedListFolder.swift @@ -8,7 +8,7 @@ import Foundation import RSCore -import Data +import Articles final class FeedListFolder: Hashable, DisplayNameProvider { diff --git a/Evergreen/Images/AuthorAvatarDownloader.swift b/Evergreen/Images/AuthorAvatarDownloader.swift index d3d5f5c4c..c739becd2 100644 --- a/Evergreen/Images/AuthorAvatarDownloader.swift +++ b/Evergreen/Images/AuthorAvatarDownloader.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles extension Notification.Name { diff --git a/Evergreen/Images/FeaturedImageDownloader.swift b/Evergreen/Images/FeaturedImageDownloader.swift index f81b5c654..db32e940a 100644 --- a/Evergreen/Images/FeaturedImageDownloader.swift +++ b/Evergreen/Images/FeaturedImageDownloader.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import RSParser final class FeaturedImageDownloader { diff --git a/Evergreen/Images/FeedIconDownloader.swift b/Evergreen/Images/FeedIconDownloader.swift index ccf6fee46..ced3a560a 100644 --- a/Evergreen/Images/FeedIconDownloader.swift +++ b/Evergreen/Images/FeedIconDownloader.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import RSWeb import RSParser diff --git a/Evergreen/Inspector/FeedInspectorViewController.swift b/Evergreen/Inspector/FeedInspectorViewController.swift index b112fb4bd..48faa1316 100644 --- a/Evergreen/Inspector/FeedInspectorViewController.swift +++ b/Evergreen/Inspector/FeedInspectorViewController.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import DB5 final class FeedInspectorViewController: NSViewController, Inspector { diff --git a/Evergreen/MainWindow/AddFeed/AddFeedController.swift b/Evergreen/MainWindow/AddFeed/AddFeedController.swift index ff9eae87b..aef73a9c0 100644 --- a/Evergreen/MainWindow/AddFeed/AddFeedController.swift +++ b/Evergreen/MainWindow/AddFeed/AddFeedController.swift @@ -9,7 +9,7 @@ import AppKit import RSCore import RSTree -import Data +import Articles import Account import RSParser diff --git a/Evergreen/MainWindow/AddFeed/AddFeedWindowController.swift b/Evergreen/MainWindow/AddFeed/AddFeedWindowController.swift index 9b838e785..e67616878 100644 --- a/Evergreen/MainWindow/AddFeed/AddFeedWindowController.swift +++ b/Evergreen/MainWindow/AddFeed/AddFeedWindowController.swift @@ -9,7 +9,7 @@ import AppKit import RSCore import RSTree -import Data +import Articles import Account protocol AddFeedWindowControllerDelegate: class { diff --git a/Evergreen/MainWindow/AddFeed/FolderTreeControllerDelegate.swift b/Evergreen/MainWindow/AddFeed/FolderTreeControllerDelegate.swift index 471d441ec..20c00e245 100644 --- a/Evergreen/MainWindow/AddFeed/FolderTreeControllerDelegate.swift +++ b/Evergreen/MainWindow/AddFeed/FolderTreeControllerDelegate.swift @@ -9,7 +9,7 @@ import Foundation import RSCore import RSTree -import Data +import Articles import Account final class FolderTreeControllerDelegate: TreeControllerDelegate { diff --git a/Evergreen/MainWindow/AddFolder/AddFolderWindowController.swift b/Evergreen/MainWindow/AddFolder/AddFolderWindowController.swift index 8737dd3a7..e529b0431 100644 --- a/Evergreen/MainWindow/AddFolder/AddFolderWindowController.swift +++ b/Evergreen/MainWindow/AddFolder/AddFolderWindowController.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import Account class AddFolderWindowController : NSWindowController { diff --git a/Evergreen/MainWindow/Detail/ArticleRenderer.swift b/Evergreen/MainWindow/Detail/ArticleRenderer.swift index 975cf26e4..51f1fd451 100644 --- a/Evergreen/MainWindow/Detail/ArticleRenderer.swift +++ b/Evergreen/MainWindow/Detail/ArticleRenderer.swift @@ -8,7 +8,7 @@ import Foundation import RSCore -import Data +import Articles var cachedStyleString = "" var cachedTemplate = "" diff --git a/Evergreen/MainWindow/Detail/DetailStatusBarView.swift b/Evergreen/MainWindow/Detail/DetailStatusBarView.swift index 9b13a2ac3..96514ed9b 100644 --- a/Evergreen/MainWindow/Detail/DetailStatusBarView.swift +++ b/Evergreen/MainWindow/Detail/DetailStatusBarView.swift @@ -8,7 +8,7 @@ import AppKit import DB5 -import Data +import Articles final class DetailStatusBarView: NSView { diff --git a/Evergreen/MainWindow/Detail/DetailViewController.swift b/Evergreen/MainWindow/Detail/DetailViewController.swift index cf45c0804..ffcb21be7 100644 --- a/Evergreen/MainWindow/Detail/DetailViewController.swift +++ b/Evergreen/MainWindow/Detail/DetailViewController.swift @@ -9,7 +9,7 @@ import Foundation import WebKit import RSCore -import Data +import Articles import RSWeb final class DetailViewController: NSViewController, WKUIDelegate { diff --git a/Evergreen/MainWindow/MainWindowController.swift b/Evergreen/MainWindow/MainWindowController.swift index 46c20420f..3a517eb17 100644 --- a/Evergreen/MainWindow/MainWindowController.swift +++ b/Evergreen/MainWindow/MainWindowController.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import Account import RSCore diff --git a/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift b/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift index 80369f621..4fcf1abad 100644 --- a/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift +++ b/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import RSCore extension Feed: PasteboardWriterOwner { diff --git a/Evergreen/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Evergreen/MainWindow/Sidebar/SidebarOutlineDataSource.swift index 844eba921..6748b65ef 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -8,7 +8,7 @@ import AppKit import RSTree -import Data +import Articles import RSCore @objc final class SidebarOutlineDataSource: NSObject, NSOutlineViewDataSource { diff --git a/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift b/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift index e1dec5049..efda7544a 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarStatusBarView.swift @@ -8,7 +8,7 @@ import AppKit import RSCore -import Data +import Articles import RSWeb import Account diff --git a/Evergreen/MainWindow/Sidebar/SidebarTreeControllerDelegate.swift b/Evergreen/MainWindow/Sidebar/SidebarTreeControllerDelegate.swift index 7ed314adf..e183bcc0e 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarTreeControllerDelegate.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarTreeControllerDelegate.swift @@ -8,7 +8,7 @@ import Foundation import RSTree -import Data +import Articles import Account final class SidebarTreeControllerDelegate: TreeControllerDelegate { diff --git a/Evergreen/MainWindow/Sidebar/SidebarViewController+ContextualMenus.swift b/Evergreen/MainWindow/Sidebar/SidebarViewController+ContextualMenus.swift index 133c6c30e..46761bb34 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarViewController+ContextualMenus.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarViewController+ContextualMenus.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import Account import RSCore diff --git a/Evergreen/MainWindow/Sidebar/SidebarViewController.swift b/Evergreen/MainWindow/Sidebar/SidebarViewController.swift index 051d828f1..876c57478 100644 --- a/Evergreen/MainWindow/Sidebar/SidebarViewController.swift +++ b/Evergreen/MainWindow/Sidebar/SidebarViewController.swift @@ -8,7 +8,7 @@ import AppKit import RSTree -import Data +import Articles import Account import RSCore diff --git a/Evergreen/MainWindow/Timeline/ArticleArray.swift b/Evergreen/MainWindow/Timeline/ArticleArray.swift index 67192fb94..dabf18e55 100644 --- a/Evergreen/MainWindow/Timeline/ArticleArray.swift +++ b/Evergreen/MainWindow/Timeline/ArticleArray.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles typealias ArticleArray = [Article] diff --git a/Evergreen/MainWindow/Timeline/ArticlePasteboardWriter.swift b/Evergreen/MainWindow/Timeline/ArticlePasteboardWriter.swift index a34d5147c..3f8ee88b1 100644 --- a/Evergreen/MainWindow/Timeline/ArticlePasteboardWriter.swift +++ b/Evergreen/MainWindow/Timeline/ArticlePasteboardWriter.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import RSCore extension Article: PasteboardWriterOwner { diff --git a/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift b/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift index c063859be..7fcada1da 100644 --- a/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift +++ b/Evergreen/MainWindow/Timeline/Cell/TimelineCellData.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles struct TimelineCellData { diff --git a/Evergreen/MainWindow/Timeline/Cell/TimelineStringUtilities.swift b/Evergreen/MainWindow/Timeline/Cell/TimelineStringUtilities.swift index 0d09d1a99..aab2b723f 100644 --- a/Evergreen/MainWindow/Timeline/Cell/TimelineStringUtilities.swift +++ b/Evergreen/MainWindow/Timeline/Cell/TimelineStringUtilities.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import RSParser // TODO: Don’t make all this at top level. diff --git a/Evergreen/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift b/Evergreen/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift index c1a99b904..08fe3aa6a 100644 --- a/Evergreen/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift +++ b/Evergreen/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift @@ -7,7 +7,7 @@ // import AppKit -import Data +import Articles import Account extension TimelineViewController { diff --git a/Evergreen/MainWindow/Timeline/TimelineViewController.swift b/Evergreen/MainWindow/Timeline/TimelineViewController.swift index a870518ef..5dd1049f5 100644 --- a/Evergreen/MainWindow/Timeline/TimelineViewController.swift +++ b/Evergreen/MainWindow/Timeline/TimelineViewController.swift @@ -8,7 +8,7 @@ import Foundation import RSCore -import Data +import Articles import Account class TimelineViewController: NSViewController, UndoableCommandRunner { diff --git a/Evergreen/Scriptability/Account+Scriptability.swift b/Evergreen/Scriptability/Account+Scriptability.swift index 8162288ed..479cb481a 100644 --- a/Evergreen/Scriptability/Account+Scriptability.swift +++ b/Evergreen/Scriptability/Account+Scriptability.swift @@ -8,7 +8,7 @@ import AppKit import Account -import Data +import Articles import RSCore @objc(ScriptableAccount) diff --git a/Evergreen/Scriptability/AppDelegate+Scriptability.swift b/Evergreen/Scriptability/AppDelegate+Scriptability.swift index 7b9bd1011..1d865eb9e 100644 --- a/Evergreen/Scriptability/AppDelegate+Scriptability.swift +++ b/Evergreen/Scriptability/AppDelegate+Scriptability.swift @@ -17,7 +17,7 @@ */ import Foundation -import Data +import Articles protocol AppDelegateAppleEvents { func installAppleEventHandlers() diff --git a/Evergreen/Scriptability/Article+Scriptability.swift b/Evergreen/Scriptability/Article+Scriptability.swift index 8dece707d..42f025943 100644 --- a/Evergreen/Scriptability/Article+Scriptability.swift +++ b/Evergreen/Scriptability/Article+Scriptability.swift @@ -8,7 +8,7 @@ import Foundation import Account -import Data +import Articles @objc(ScriptableArticle) class ScriptableArticle: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer { diff --git a/Evergreen/Scriptability/Author+Scriptability.swift b/Evergreen/Scriptability/Author+Scriptability.swift index 7c9f7fcc7..3c60f2c9a 100644 --- a/Evergreen/Scriptability/Author+Scriptability.swift +++ b/Evergreen/Scriptability/Author+Scriptability.swift @@ -8,7 +8,7 @@ import Foundation import Account -import Data +import Articles @objc(ScriptableAuthor) class ScriptableAuthor: NSObject, UniqueIdScriptingObject { diff --git a/Evergreen/Scriptability/Feed+Scriptability.swift b/Evergreen/Scriptability/Feed+Scriptability.swift index c863111be..d493b85e7 100644 --- a/Evergreen/Scriptability/Feed+Scriptability.swift +++ b/Evergreen/Scriptability/Feed+Scriptability.swift @@ -9,7 +9,7 @@ import Foundation import RSParser import Account -import Data +import Articles @objc(ScriptableFeed) class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer{ diff --git a/Evergreen/Scriptability/Folder+Scriptability.swift b/Evergreen/Scriptability/Folder+Scriptability.swift index 0034fa5fc..454e4901e 100644 --- a/Evergreen/Scriptability/Folder+Scriptability.swift +++ b/Evergreen/Scriptability/Folder+Scriptability.swift @@ -8,7 +8,7 @@ import Foundation import Account -import Data +import Articles import RSCore @objc(ScriptableFolder) diff --git a/Evergreen/Scriptability/MainWindowController+Scriptability.swift b/Evergreen/Scriptability/MainWindowController+Scriptability.swift index 02664e2fb..baf392228 100644 --- a/Evergreen/Scriptability/MainWindowController+Scriptability.swift +++ b/Evergreen/Scriptability/MainWindowController+Scriptability.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles protocol ScriptingMainWindowController { var scriptingCurrentArticle: Article? { get } diff --git a/Evergreen/Scriptability/NSApplication+Scriptability.swift b/Evergreen/Scriptability/NSApplication+Scriptability.swift index fbe52ea33..d339cb557 100644 --- a/Evergreen/Scriptability/NSApplication+Scriptability.swift +++ b/Evergreen/Scriptability/NSApplication+Scriptability.swift @@ -8,7 +8,7 @@ import AppKit import Account -import Data +import Articles extension NSApplication : ScriptingObjectContainer { diff --git a/Evergreen/SmartFeeds/PseudoFeed.swift b/Evergreen/SmartFeeds/PseudoFeed.swift index 19098fef6..8cb907e89 100644 --- a/Evergreen/SmartFeeds/PseudoFeed.swift +++ b/Evergreen/SmartFeeds/PseudoFeed.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import RSCore protocol PseudoFeed: class, DisplayNameProvider, UnreadCountProvider, SmallIconProvider, PasteboardWriterOwner { diff --git a/Evergreen/SmartFeeds/SmartFeed.swift b/Evergreen/SmartFeeds/SmartFeed.swift index c7bfa7623..fd5b9d0ab 100644 --- a/Evergreen/SmartFeeds/SmartFeed.swift +++ b/Evergreen/SmartFeeds/SmartFeed.swift @@ -8,7 +8,7 @@ import Foundation import RSCore -import Data +import Articles import Account protocol SmartFeedDelegate: DisplayNameProvider, ArticleFetcher { diff --git a/Evergreen/SmartFeeds/StarredFeedDelegate.swift b/Evergreen/SmartFeeds/StarredFeedDelegate.swift index 9d2f3bc2f..c0dd37fa9 100644 --- a/Evergreen/SmartFeeds/StarredFeedDelegate.swift +++ b/Evergreen/SmartFeeds/StarredFeedDelegate.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import Account diff --git a/Evergreen/SmartFeeds/TodayFeedDelegate.swift b/Evergreen/SmartFeeds/TodayFeedDelegate.swift index 9e74bca7c..ba5c1e5e8 100644 --- a/Evergreen/SmartFeeds/TodayFeedDelegate.swift +++ b/Evergreen/SmartFeeds/TodayFeedDelegate.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import Account struct TodayFeedDelegate: SmartFeedDelegate { diff --git a/Evergreen/SmartFeeds/UnreadFeed.swift b/Evergreen/SmartFeeds/UnreadFeed.swift index 98c69bb68..707c4ae40 100644 --- a/Evergreen/SmartFeeds/UnreadFeed.swift +++ b/Evergreen/SmartFeeds/UnreadFeed.swift @@ -8,7 +8,7 @@ import AppKit import Account -import Data +import Articles // This just shows the global unread count, which appDelegate already has. Easy. diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index aaf252c50..78efda534 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -8,9 +8,9 @@ import Foundation import RSCore -import Data +import Articles import RSParser -import Database +import ArticlesDatabase import RSWeb public extension Notification.Name { @@ -53,7 +53,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, var idToFeedDictionary = [String: Feed]() let settingsFile: String let dataFolder: String - let database: Database + let database: ArticlesDatabase let delegate: AccountDelegate var username: String? static let saveQueue = CoalescingQueue(name: "Account Save Queue", interval: 1.0) @@ -109,7 +109,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, self.hashValue = accountID.hashValue let databaseFilePath = (dataFolder as NSString).appendingPathComponent("DB.sqlite3") - self.database = Database(databaseFilePath: databaseFilePath, accountID: accountID) + self.database = ArticlesDatabase(databaseFilePath: databaseFilePath, accountID: accountID) NotificationCenter.default.addObserver(self, selector: #selector(downloadProgressDidChange(_:)), name: .DownloadProgressDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(unreadCountDidChange(_:)), name: .UnreadCountDidChange, object: nil) diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index 41d7dbda3..c638acb16 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -7,16 +7,16 @@ objects = { /* Begin PBXBuildFile section */ - 841973FD1F6DD1B7006346C4 /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973E51F6DD195006346C4 /* Data.framework */; }; 841973FE1F6DD1BC006346C4 /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973EF1F6DD19E006346C4 /* RSCore.framework */; }; 841973FF1F6DD1C5006346C4 /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841973FA1F6DD1AC006346C4 /* RSParser.framework */; }; 841974011F6DD1EC006346C4 /* Folder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974001F6DD1EC006346C4 /* Folder.swift */; }; 841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841974241F6DDCE4006346C4 /* AccountDelegate.swift */; }; + 841D4D702106B40400DD04E6 /* ArticlesDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841D4D6F2106B40400DD04E6 /* ArticlesDatabase.framework */; }; + 841D4D722106B40A00DD04E6 /* Articles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841D4D712106B40A00DD04E6 /* Articles.framework */; }; 84245C7F1FDDD2580074AFBB /* FeedbinAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84245C7E1FDDD2580074AFBB /* FeedbinAccountDelegate.swift */; }; 84245C811FDDD42A0074AFBB /* Feedbin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84245C801FDDD42A0074AFBB /* Feedbin.swift */; }; 84245C831FDDD8160074AFBB /* FeedbinGetSubscriptionsDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84245C821FDDD8160074AFBB /* FeedbinGetSubscriptionsDelegate.swift */; }; 84245C851FDDD8CB0074AFBB /* FeedbinSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84245C841FDDD8CB0074AFBB /* FeedbinSubscription.swift */; }; - 8469F8171F6DD0AD0084783E /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8401A17D1F6DC388002B1BE2 /* Database.framework */; }; 8469F81C1F6DD15E0084783E /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935101F62486800CEBD24 /* Account.swift */; }; 846E77451F6EF9B900A165E2 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419740D1F6DD25F006346C4 /* Container.swift */; }; 846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */; }; @@ -114,6 +114,8 @@ 841974241F6DDCE4006346C4 /* AccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDelegate.swift; sourceTree = ""; }; 8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountDelegate.swift; sourceTree = ""; }; 8419742D1F6DDE96006346C4 /* LocalAccountRefresher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalAccountRefresher.swift; sourceTree = ""; }; + 841D4D6F2106B40400DD04E6 /* ArticlesDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ArticlesDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 841D4D712106B40A00DD04E6 /* Articles.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Articles.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84245C7E1FDDD2580074AFBB /* FeedbinAccountDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbinAccountDelegate.swift; sourceTree = ""; }; 84245C801FDDD42A0074AFBB /* Feedbin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Feedbin.swift; sourceTree = ""; }; 84245C821FDDD8160074AFBB /* FeedbinGetSubscriptionsDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinGetSubscriptionsDelegate.swift; sourceTree = ""; }; @@ -142,10 +144,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 841D4D722106B40A00DD04E6 /* Articles.framework in Frameworks */, + 841D4D702106B40400DD04E6 /* ArticlesDatabase.framework in Frameworks */, 841973FE1F6DD1BC006346C4 /* RSCore.framework in Frameworks */, 841973FF1F6DD1C5006346C4 /* RSParser.framework in Frameworks */, - 841973FD1F6DD1B7006346C4 /* Data.framework in Frameworks */, - 8469F8171F6DD0AD0084783E /* Database.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -221,6 +223,8 @@ 8469F80F1F6DC3C10084783E /* Frameworks */ = { isa = PBXGroup; children = ( + 841D4D712106B40A00DD04E6 /* Articles.framework */, + 841D4D6F2106B40400DD04E6 /* ArticlesDatabase.framework */, 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */, 841973DF1F6DD194006346C4 /* Data.xcodeproj */, 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */, diff --git a/Frameworks/Account/AccountManager.swift b/Frameworks/Account/AccountManager.swift index 724a2fa50..48388a157 100644 --- a/Frameworks/Account/AccountManager.swift +++ b/Frameworks/Account/AccountManager.swift @@ -8,7 +8,7 @@ import Foundation import RSCore -import Data +import Articles let AccountsDidChangeNotification = "AccountsDidChangeNotification" diff --git a/Frameworks/Account/ArticleFetcher.swift b/Frameworks/Account/ArticleFetcher.swift index 0b8188b03..725d897b3 100644 --- a/Frameworks/Account/ArticleFetcher.swift +++ b/Frameworks/Account/ArticleFetcher.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles public protocol ArticleFetcher { diff --git a/Frameworks/Account/Container.swift b/Frameworks/Account/Container.swift index 344e785a7..68307dca3 100644 --- a/Frameworks/Account/Container.swift +++ b/Frameworks/Account/Container.swift @@ -9,7 +9,7 @@ import Foundation import RSCore -import Data +import Articles extension Notification.Name { diff --git a/Frameworks/Account/DataExtensions.swift b/Frameworks/Account/DataExtensions.swift index 2721c724e..0bce67963 100644 --- a/Frameworks/Account/DataExtensions.swift +++ b/Frameworks/Account/DataExtensions.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import RSParser public extension Notification.Name { diff --git a/Frameworks/Account/Folder.swift b/Frameworks/Account/Folder.swift index 8bf9b756c..74bd696ed 100644 --- a/Frameworks/Account/Folder.swift +++ b/Frameworks/Account/Folder.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import RSCore public final class Folder: DisplayNameProvider, Container, UnreadCountProvider, Hashable { diff --git a/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift b/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift index 933ffff3b..618093110 100644 --- a/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift +++ b/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift @@ -10,7 +10,7 @@ import Foundation import RSCore import RSParser import RSWeb -import Data +import Articles final class LocalAccountRefresher { diff --git a/Frameworks/Data/Article.swift b/Frameworks/Articles/Article.swift similarity index 100% rename from Frameworks/Data/Article.swift rename to Frameworks/Articles/Article.swift diff --git a/Frameworks/Data/ArticleStatus.swift b/Frameworks/Articles/ArticleStatus.swift similarity index 100% rename from Frameworks/Data/ArticleStatus.swift rename to Frameworks/Articles/ArticleStatus.swift diff --git a/Frameworks/Data/Data.xcodeproj/project.pbxproj b/Frameworks/Articles/Articles.xcodeproj/project.pbxproj similarity index 76% rename from Frameworks/Data/Data.xcodeproj/project.pbxproj rename to Frameworks/Articles/Articles.xcodeproj/project.pbxproj index 5ca9257a3..93b66224d 100644 --- a/Frameworks/Data/Data.xcodeproj/project.pbxproj +++ b/Frameworks/Articles/Articles.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405C91F1A8E4300DF0296 /* DatabaseID.swift */; }; 8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */; }; - 844BEE651F0AB3C9004AB7CD /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE5B1F0AB3C8004AB7CD /* Data.framework */; }; + 844BEE651F0AB3C9004AB7CD /* Articles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE5B1F0AB3C8004AB7CD /* Articles.framework */; }; 844BEE6A1F0AB3C9004AB7CD /* DataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE691F0AB3C9004AB7CD /* DataTests.swift */; }; 844BEE7D1F0AB4C4004AB7CD /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */; }; 844BEE7F1F0AB4CA004AB7CD /* Article.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE7E1F0AB4CA004AB7CD /* Article.swift */; }; @@ -54,8 +54,8 @@ /* Begin PBXFileReference section */ 840405C91F1A8E4300DF0296 /* DatabaseID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseID.swift; sourceTree = ""; }; 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadCountProvider.swift; sourceTree = ""; }; - 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; }; + 844BEE5B1F0AB3C8004AB7CD /* Articles.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Articles.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 844BEE641F0AB3C9004AB7CD /* ArticlesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ArticlesTests.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 = ""; }; @@ -67,16 +67,11 @@ 844BEE9C1F0AB512004AB7CD /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; 848E3EB320FBCFAE0004B7ED /* RSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84C490F51F705D5F003131D2 /* RSWeb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSWeb.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D511EEC420242DF400712EC3 /* DataTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DataTests_target.xcconfig; sourceTree = ""; }; - D511EEC520242DF400712EC3 /* Data_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_project_debug.xcconfig; sourceTree = ""; }; - D511EEC620242DF400712EC3 /* Data_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_project.xcconfig; sourceTree = ""; }; - D511EEC720242DF400712EC3 /* Data_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_target.xcconfig; sourceTree = ""; }; - D511EEC820242DF400712EC3 /* Data_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_project_release.xcconfig; sourceTree = ""; }; - D511EEE020242DFB00712EC3 /* DataTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DataTests_target.xcconfig; sourceTree = ""; }; - D511EEE120242DFB00712EC3 /* Data_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_project_debug.xcconfig; sourceTree = ""; }; - D511EEE220242DFB00712EC3 /* Data_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_project.xcconfig; sourceTree = ""; }; - D511EEE320242DFB00712EC3 /* Data_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_target.xcconfig; sourceTree = ""; }; - D511EEE420242DFB00712EC3 /* Data_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Data_project_release.xcconfig; sourceTree = ""; }; + D511EEE020242DFB00712EC3 /* ArticlesDataTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ArticlesDataTests_target.xcconfig; sourceTree = ""; }; + D511EEE120242DFB00712EC3 /* Articles_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Articles_project_debug.xcconfig; sourceTree = ""; }; + D511EEE220242DFB00712EC3 /* Articles_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Articles_project.xcconfig; sourceTree = ""; }; + D511EEE320242DFB00712EC3 /* Articles_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Articles_target.xcconfig; sourceTree = ""; }; + D511EEE420242DFB00712EC3 /* Articles_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Articles_project_release.xcconfig; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -93,7 +88,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 844BEE651F0AB3C9004AB7CD /* Data.framework in Frameworks */, + 844BEE651F0AB3C9004AB7CD /* Articles.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -103,7 +98,6 @@ 844BEE511F0AB3C8004AB7CD = { isa = PBXGroup; children = ( - D511EEC320242DF400712EC3 /* xcconfig */, 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */, 844BEE7E1F0AB4CA004AB7CD /* Article.swift */, 844BEE801F0AB4D0004AB7CD /* Author.swift */, @@ -122,8 +116,8 @@ 844BEE5C1F0AB3C8004AB7CD /* Products */ = { isa = PBXGroup; children = ( - 844BEE5B1F0AB3C8004AB7CD /* Data.framework */, - 844BEE641F0AB3C9004AB7CD /* DataTests.xctest */, + 844BEE5B1F0AB3C8004AB7CD /* Articles.framework */, + 844BEE641F0AB3C9004AB7CD /* ArticlesTests.xctest */, ); name = Products; sourceTree = ""; @@ -157,26 +151,14 @@ name = Frameworks; sourceTree = ""; }; - D511EEC320242DF400712EC3 /* xcconfig */ = { - isa = PBXGroup; - children = ( - D511EEC420242DF400712EC3 /* DataTests_target.xcconfig */, - D511EEC520242DF400712EC3 /* Data_project_debug.xcconfig */, - D511EEC620242DF400712EC3 /* Data_project.xcconfig */, - D511EEC720242DF400712EC3 /* Data_target.xcconfig */, - D511EEC820242DF400712EC3 /* Data_project_release.xcconfig */, - ); - path = xcconfig; - sourceTree = ""; - }; D511EEE520242DFB00712EC3 /* xcconfig */ = { isa = PBXGroup; children = ( - D511EEE220242DFB00712EC3 /* Data_project.xcconfig */, - D511EEE120242DFB00712EC3 /* Data_project_debug.xcconfig */, - D511EEE420242DFB00712EC3 /* Data_project_release.xcconfig */, - D511EEE320242DFB00712EC3 /* Data_target.xcconfig */, - D511EEE020242DFB00712EC3 /* DataTests_target.xcconfig */, + D511EEE220242DFB00712EC3 /* Articles_project.xcconfig */, + D511EEE120242DFB00712EC3 /* Articles_project_debug.xcconfig */, + D511EEE420242DFB00712EC3 /* Articles_project_release.xcconfig */, + D511EEE320242DFB00712EC3 /* Articles_target.xcconfig */, + D511EEE020242DFB00712EC3 /* ArticlesDataTests_target.xcconfig */, ); path = xcconfig; sourceTree = ""; @@ -194,9 +176,9 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 844BEE5A1F0AB3C8004AB7CD /* Data */ = { + 844BEE5A1F0AB3C8004AB7CD /* Articles */ = { isa = PBXNativeTarget; - buildConfigurationList = 844BEE6F1F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "Data" */; + buildConfigurationList = 844BEE6F1F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "Articles" */; buildPhases = ( 844BEE561F0AB3C8004AB7CD /* Sources */, 844BEE571F0AB3C8004AB7CD /* Frameworks */, @@ -207,14 +189,14 @@ ); dependencies = ( ); - name = Data; + name = Articles; productName = Data; - productReference = 844BEE5B1F0AB3C8004AB7CD /* Data.framework */; + productReference = 844BEE5B1F0AB3C8004AB7CD /* Articles.framework */; productType = "com.apple.product-type.framework"; }; - 844BEE631F0AB3C9004AB7CD /* DataTests */ = { + 844BEE631F0AB3C9004AB7CD /* ArticlesTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 844BEE721F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "DataTests" */; + buildConfigurationList = 844BEE721F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "ArticlesTests" */; buildPhases = ( 844BEE601F0AB3C9004AB7CD /* Sources */, 844BEE611F0AB3C9004AB7CD /* Frameworks */, @@ -225,9 +207,9 @@ dependencies = ( 844BEE671F0AB3C9004AB7CD /* PBXTargetDependency */, ); - name = DataTests; + name = ArticlesTests; productName = DataTests; - productReference = 844BEE641F0AB3C9004AB7CD /* DataTests.xctest */; + productReference = 844BEE641F0AB3C9004AB7CD /* ArticlesTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -253,7 +235,7 @@ }; }; }; - buildConfigurationList = 844BEE551F0AB3C8004AB7CD /* Build configuration list for PBXProject "Data" */; + buildConfigurationList = 844BEE551F0AB3C8004AB7CD /* Build configuration list for PBXProject "Articles" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -271,8 +253,8 @@ ); projectRoot = ""; targets = ( - 844BEE5A1F0AB3C8004AB7CD /* Data */, - 844BEE631F0AB3C9004AB7CD /* DataTests */, + 844BEE5A1F0AB3C8004AB7CD /* Articles */, + 844BEE631F0AB3C9004AB7CD /* ArticlesTests */, ); }; /* End PBXProject section */ @@ -346,7 +328,7 @@ /* Begin PBXTargetDependency section */ 844BEE671F0AB3C9004AB7CD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 844BEE5A1F0AB3C8004AB7CD /* Data */; + target = 844BEE5A1F0AB3C8004AB7CD /* Articles */; targetProxy = 844BEE661F0AB3C9004AB7CD /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -354,50 +336,58 @@ /* Begin XCBuildConfiguration section */ 844BEE6D1F0AB3C9004AB7CD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEC520242DF400712EC3 /* Data_project_debug.xcconfig */; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + SWIFT_VERSION = 4.2; }; name = Debug; }; 844BEE6E1F0AB3C9004AB7CD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEC820242DF400712EC3 /* Data_project_release.xcconfig */; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + SWIFT_VERSION = 4.2; }; name = Release; }; 844BEE701F0AB3C9004AB7CD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEC720242DF400712EC3 /* Data_target.xcconfig */; buildSettings = { + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Articles; + PRODUCT_NAME = Articles; }; name = Debug; }; 844BEE711F0AB3C9004AB7CD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEC720242DF400712EC3 /* Data_target.xcconfig */; buildSettings = { + INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Articles; + PRODUCT_NAME = Articles; }; name = Release; }; 844BEE731F0AB3C9004AB7CD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEC420242DF400712EC3 /* DataTests_target.xcconfig */; buildSettings = { + PRODUCT_NAME = ArticlesTests; }; name = Debug; }; 844BEE741F0AB3C9004AB7CD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEC420242DF400712EC3 /* DataTests_target.xcconfig */; buildSettings = { + PRODUCT_NAME = ArticlesTests; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 844BEE551F0AB3C8004AB7CD /* Build configuration list for PBXProject "Data" */ = { + 844BEE551F0AB3C8004AB7CD /* Build configuration list for PBXProject "Articles" */ = { isa = XCConfigurationList; buildConfigurations = ( 844BEE6D1F0AB3C9004AB7CD /* Debug */, @@ -406,7 +396,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 844BEE6F1F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "Data" */ = { + 844BEE6F1F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "Articles" */ = { isa = XCConfigurationList; buildConfigurations = ( 844BEE701F0AB3C9004AB7CD /* Debug */, @@ -415,7 +405,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 844BEE721F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "DataTests" */ = { + 844BEE721F0AB3C9004AB7CD /* Build configuration list for PBXNativeTarget "ArticlesTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 844BEE731F0AB3C9004AB7CD /* Debug */, diff --git a/Frameworks/Data/Data.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/Articles/Articles.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Frameworks/Data/Data.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Frameworks/Articles/Articles.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Frameworks/Articles/Articles.xcodeproj/xcshareddata/xcschemes/Articles.xcscheme b/Frameworks/Articles/Articles.xcodeproj/xcshareddata/xcschemes/Articles.xcscheme new file mode 100644 index 000000000..6b2d49b2a --- /dev/null +++ b/Frameworks/Articles/Articles.xcodeproj/xcshareddata/xcschemes/Articles.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Frameworks/Data/Attachment.swift b/Frameworks/Articles/Attachment.swift similarity index 100% rename from Frameworks/Data/Attachment.swift rename to Frameworks/Articles/Attachment.swift diff --git a/Frameworks/Data/Author.swift b/Frameworks/Articles/Author.swift similarity index 100% rename from Frameworks/Data/Author.swift rename to Frameworks/Articles/Author.swift diff --git a/Frameworks/Data/DataTests/DataTests.swift b/Frameworks/Articles/DataTests/DataTests.swift similarity index 97% rename from Frameworks/Data/DataTests/DataTests.swift rename to Frameworks/Articles/DataTests/DataTests.swift index 3560bfcb7..d7d9bdc27 100644 --- a/Frameworks/Data/DataTests/DataTests.swift +++ b/Frameworks/Articles/DataTests/DataTests.swift @@ -7,7 +7,7 @@ // import XCTest -@testable import Data +@testable import Articles class DataTests: XCTestCase { diff --git a/Frameworks/Data/DataTests/Info.plist b/Frameworks/Articles/DataTests/Info.plist similarity index 100% rename from Frameworks/Data/DataTests/Info.plist rename to Frameworks/Articles/DataTests/Info.plist diff --git a/Frameworks/Data/DatabaseID.swift b/Frameworks/Articles/DatabaseID.swift similarity index 100% rename from Frameworks/Data/DatabaseID.swift rename to Frameworks/Articles/DatabaseID.swift diff --git a/Frameworks/Data/Feed.swift b/Frameworks/Articles/Feed.swift similarity index 100% rename from Frameworks/Data/Feed.swift rename to Frameworks/Articles/Feed.swift diff --git a/Frameworks/Data/Info.plist b/Frameworks/Articles/Info.plist similarity index 100% rename from Frameworks/Data/Info.plist rename to Frameworks/Articles/Info.plist diff --git a/Frameworks/Data/UnreadCountProvider.swift b/Frameworks/Articles/UnreadCountProvider.swift similarity index 100% rename from Frameworks/Data/UnreadCountProvider.swift rename to Frameworks/Articles/UnreadCountProvider.swift diff --git a/Frameworks/Data/xcconfig/DataTests_target.xcconfig b/Frameworks/Articles/xcconfig/ArticlesDataTests_target.xcconfig similarity index 79% rename from Frameworks/Data/xcconfig/DataTests_target.xcconfig rename to Frameworks/Articles/xcconfig/ArticlesDataTests_target.xcconfig index 3eb9f511f..ee5484e64 100644 --- a/Frameworks/Data/xcconfig/DataTests_target.xcconfig +++ b/Frameworks/Articles/xcconfig/ArticlesDataTests_target.xcconfig @@ -1,7 +1,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks INFOPLIST_FILE = DataTests/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DataTests +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.ArticlesDataTests PRODUCT_NAME = $(TARGET_NAME) diff --git a/Frameworks/Data/xcconfig/Data_project.xcconfig b/Frameworks/Articles/xcconfig/Articles_project.xcconfig similarity index 100% rename from Frameworks/Data/xcconfig/Data_project.xcconfig rename to Frameworks/Articles/xcconfig/Articles_project.xcconfig diff --git a/Frameworks/Data/xcconfig/Data_project_debug.xcconfig b/Frameworks/Articles/xcconfig/Articles_project_debug.xcconfig similarity index 88% rename from Frameworks/Data/xcconfig/Data_project_debug.xcconfig rename to Frameworks/Articles/xcconfig/Articles_project_debug.xcconfig index 8763d0f0c..e3b0dad0a 100644 --- a/Frameworks/Data/xcconfig/Data_project_debug.xcconfig +++ b/Frameworks/Articles/xcconfig/Articles_project_debug.xcconfig @@ -1,4 +1,4 @@ -#include "./Data_project.xcconfig" +#include "./ArticlesData_project.xcconfig" DEBUG_INFORMATION_FORMAT = dwarf ENABLE_TESTABILITY = YES diff --git a/Frameworks/Database/xcconfig/Database_project_release.xcconfig b/Frameworks/Articles/xcconfig/Articles_project_release.xcconfig similarity index 79% rename from Frameworks/Database/xcconfig/Database_project_release.xcconfig rename to Frameworks/Articles/xcconfig/Articles_project_release.xcconfig index f28860d07..5af43130c 100644 --- a/Frameworks/Database/xcconfig/Database_project_release.xcconfig +++ b/Frameworks/Articles/xcconfig/Articles_project_release.xcconfig @@ -1,4 +1,4 @@ -#include "./Database_project.xcconfig" +#include "./ArticlesData_project.xcconfig" DEBUG_INFORMATION_FORMAT = dwarf-with-dsym ENABLE_NS_ASSERTIONS = NO diff --git a/Frameworks/Data/xcconfig/Data_target.xcconfig b/Frameworks/Articles/xcconfig/Articles_target.xcconfig similarity index 88% rename from Frameworks/Data/xcconfig/Data_target.xcconfig rename to Frameworks/Articles/xcconfig/Articles_target.xcconfig index ce6d1fb99..65ad26d4b 100644 --- a/Frameworks/Data/xcconfig/Data_target.xcconfig +++ b/Frameworks/Articles/xcconfig/Articles_target.xcconfig @@ -8,7 +8,7 @@ LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_pa DEFINES_MODULE = YES FRAMEWORK_VERSION = A INFOPLIST_FILE = Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Data +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Articles PRODUCT_NAME = $(TARGET_NAME) CLANG_ENABLE_MODULES = YES diff --git a/Frameworks/Database/Database.swift b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift similarity index 97% rename from Frameworks/Database/Database.swift rename to Frameworks/ArticlesDatabase/ArticlesDatabase.swift index 3fc0624aa..83c4a55f1 100644 --- a/Frameworks/Database/Database.swift +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift @@ -1,5 +1,5 @@ // -// Database.swift +// ArticlesDatabase.swift // Evergreen // // Created by Brent Simmons on 7/20/15. @@ -10,7 +10,7 @@ import Foundation import RSCore import RSDatabase import RSParser -import Data +import Articles // This file and UnreadCountDictionary are the entirety of the public API for Database.framework. // Everything else is implementation. @@ -19,7 +19,7 @@ public typealias ArticleResultBlock = (Set
) -> Void public typealias UnreadCountCompletionBlock = (UnreadCountDictionary) -> Void public typealias UpdateArticlesWithFeedCompletionBlock = (Set
?, Set
?) -> Void //newArticles, updatedArticles -public final class Database { +public final class ArticlesDatabase { private let accountID: String private let articlesTable: ArticlesTable diff --git a/Frameworks/Database/Database.xcodeproj/project.pbxproj b/Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.pbxproj similarity index 84% rename from Frameworks/Database/Database.xcodeproj/project.pbxproj rename to Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.pbxproj index 9f64b2590..e4e66fd8c 100644 --- a/Frameworks/Database/Database.xcodeproj/project.pbxproj +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.pbxproj @@ -8,13 +8,14 @@ /* Begin PBXBuildFile section */ 840405CF1F1A963700DF0296 /* AttachmentsTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405CE1F1A963700DF0296 /* AttachmentsTable.swift */; }; + 841D4D742106B59F00DD04E6 /* Articles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 841D4D732106B59F00DD04E6 /* Articles.framework */; }; 84288A001F6A3C4400395871 /* DatabaseObject+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842889FF1F6A3C4400395871 /* DatabaseObject+Database.swift */; }; 84288A021F6A3D8000395871 /* RelatedObjectsMap+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84288A011F6A3D8000395871 /* RelatedObjectsMap+Database.swift */; }; 843577161F744FC800F460AE /* DatabaseArticle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843577151F744FC800F460AE /* DatabaseArticle.swift */; }; 843577221F749C6200F460AE /* ArticleChangesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843577211F749C6200F460AE /* ArticleChangesTests.swift */; }; 843702C31F70D15D00B18807 /* ParsedArticle+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843702C21F70D15D00B18807 /* ParsedArticle+Database.swift */; }; 843CB9961F34174100EE6581 /* Author+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F20F901F1810DD00D8E682 /* Author+Database.swift */; }; - 844BEE411F0AB3AB004AB7CD /* Database.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE371F0AB3AA004AB7CD /* Database.framework */; }; + 844BEE411F0AB3AB004AB7CD /* ArticlesDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE371F0AB3AA004AB7CD /* ArticlesDatabase.framework */; }; 844BEE461F0AB3AB004AB7CD /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE451F0AB3AB004AB7CD /* DatabaseTests.swift */; }; 845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580661F0AEBCD003CCFA1 /* Constants.swift */; }; 845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580751F0AF670003CCFA1 /* Article+Database.swift */; }; @@ -25,11 +26,10 @@ 848E3EB920FBCFD20004B7ED /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EB820FBCFD20004B7ED /* RSCore.framework */; }; 848E3EBB20FBCFD80004B7ED /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EBA20FBCFD80004B7ED /* RSParser.framework */; }; 848E3EBD20FBCFDE0004B7ED /* RSDatabase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EBC20FBCFDE0004B7ED /* RSDatabase.framework */; }; - 84E156EA1F0AB80500F8CC05 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E156E91F0AB80500F8CC05 /* Database.swift */; }; + 84E156EA1F0AB80500F8CC05 /* ArticlesDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E156E91F0AB80500F8CC05 /* ArticlesDatabase.swift */; }; 84E156EC1F0AB80E00F8CC05 /* ArticlesTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E156EB1F0AB80E00F8CC05 /* ArticlesTable.swift */; }; 84E156EE1F0AB81400F8CC05 /* StatusesTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E156ED1F0AB81400F8CC05 /* StatusesTable.swift */; }; 84E156F01F0AB81F00F8CC05 /* CreateStatements.sql in Resources */ = {isa = PBXBuildFile; fileRef = 84E156EF1F0AB81F00F8CC05 /* CreateStatements.sql */; }; - 84E156FD1F0AB86100F8CC05 /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E156F81F0AB83600F8CC05 /* Data.framework */; }; 84F20F8F1F180D8700D8E682 /* AuthorsTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F20F8E1F180D8700D8E682 /* AuthorsTable.swift */; }; /* End PBXBuildFile section */ @@ -115,13 +115,14 @@ /* Begin PBXFileReference section */ 840405CE1F1A963700DF0296 /* AttachmentsTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentsTable.swift; sourceTree = ""; }; + 841D4D732106B59F00DD04E6 /* Articles.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Articles.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 842889FF1F6A3C4400395871 /* DatabaseObject+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DatabaseObject+Database.swift"; sourceTree = ""; }; 84288A011F6A3D8000395871 /* RelatedObjectsMap+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RelatedObjectsMap+Database.swift"; sourceTree = ""; }; 843577151F744FC800F460AE /* DatabaseArticle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseArticle.swift; sourceTree = ""; }; 843577211F749C6200F460AE /* ArticleChangesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleChangesTests.swift; sourceTree = ""; }; 843702C21F70D15D00B18807 /* ParsedArticle+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "ParsedArticle+Database.swift"; path = "Extensions/ParsedArticle+Database.swift"; sourceTree = ""; }; - 844BEE371F0AB3AA004AB7CD /* Database.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Database.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DatabaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 844BEE371F0AB3AA004AB7CD /* ArticlesDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ArticlesDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 844BEE401F0AB3AB004AB7CD /* ArticlesDatabaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ArticlesDatabaseTests.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 = ""; }; 845580661F0AEBCD003CCFA1 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; @@ -136,7 +137,7 @@ 848E3EBC20FBCFDE0004B7ED /* RSDatabase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSDatabase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 84BB4B8F1F119C4900858766 /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; 84E156E81F0AB75600F8CC05 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 84E156E91F0AB80500F8CC05 /* Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = ""; }; + 84E156E91F0AB80500F8CC05 /* ArticlesDatabase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticlesDatabase.swift; sourceTree = ""; }; 84E156EB1F0AB80E00F8CC05 /* ArticlesTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticlesTable.swift; sourceTree = ""; }; 84E156ED1F0AB81400F8CC05 /* StatusesTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusesTable.swift; sourceTree = ""; }; 84E156EF1F0AB81F00F8CC05 /* CreateStatements.sql */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CreateStatements.sql; sourceTree = ""; }; @@ -144,11 +145,11 @@ 84E157001F0AB89B00F8CC05 /* RSDatabase.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSDatabase.xcodeproj; path = ../RSDatabase/RSDatabase.xcodeproj; sourceTree = ""; }; 84F20F8E1F180D8700D8E682 /* AuthorsTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorsTable.swift; sourceTree = ""; }; 84F20F901F1810DD00D8E682 /* Author+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Author+Database.swift"; path = "Extensions/Author+Database.swift"; sourceTree = ""; }; - D511EEE720242E0800712EC3 /* DatabaseTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DatabaseTests_target.xcconfig; sourceTree = ""; }; - D511EEE820242E0800712EC3 /* Database_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Database_target.xcconfig; sourceTree = ""; }; - D511EEE920242E0800712EC3 /* Database_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Database_project.xcconfig; sourceTree = ""; }; - D511EEEA20242E0800712EC3 /* Database_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Database_project_debug.xcconfig; sourceTree = ""; }; - D511EEEB20242E0800712EC3 /* Database_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Database_project_release.xcconfig; sourceTree = ""; }; + D511EEE720242E0800712EC3 /* ArticlesDatabaseTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ArticlesDatabaseTests_target.xcconfig; sourceTree = ""; }; + D511EEE820242E0800712EC3 /* ArticlesDatabase_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ArticlesDatabase_target.xcconfig; sourceTree = ""; }; + D511EEE920242E0800712EC3 /* ArticlesDatabase_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ArticlesDatabase_project.xcconfig; sourceTree = ""; }; + D511EEEA20242E0800712EC3 /* ArticlesDatabase_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ArticlesDatabase_project_debug.xcconfig; sourceTree = ""; }; + D511EEEB20242E0800712EC3 /* ArticlesDatabase_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = ArticlesDatabase_project_release.xcconfig; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -156,10 +157,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 841D4D742106B59F00DD04E6 /* Articles.framework in Frameworks */, 848E3EBD20FBCFDE0004B7ED /* RSDatabase.framework in Frameworks */, 848E3EBB20FBCFD80004B7ED /* RSParser.framework in Frameworks */, 848E3EB920FBCFD20004B7ED /* RSCore.framework in Frameworks */, - 84E156FD1F0AB86100F8CC05 /* Data.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -167,7 +168,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 844BEE411F0AB3AB004AB7CD /* Database.framework in Frameworks */, + 844BEE411F0AB3AB004AB7CD /* ArticlesDatabase.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -177,7 +178,7 @@ 844BEE2D1F0AB3AA004AB7CD = { isa = PBXGroup; children = ( - 84E156E91F0AB80500F8CC05 /* Database.swift */, + 84E156E91F0AB80500F8CC05 /* ArticlesDatabase.swift */, 848AD2951F58A91E004FB0EC /* UnreadCountDictionary.swift */, 845580661F0AEBCD003CCFA1 /* Constants.swift */, 84E156EB1F0AB80E00F8CC05 /* ArticlesTable.swift */, @@ -198,8 +199,8 @@ 844BEE381F0AB3AA004AB7CD /* Products */ = { isa = PBXGroup; children = ( - 844BEE371F0AB3AA004AB7CD /* Database.framework */, - 844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */, + 844BEE371F0AB3AA004AB7CD /* ArticlesDatabase.framework */, + 844BEE401F0AB3AB004AB7CD /* ArticlesDatabaseTests.xctest */, ); name = Products; sourceTree = ""; @@ -260,6 +261,7 @@ 84E156FB1F0AB83A00F8CC05 /* Frameworks */ = { isa = PBXGroup; children = ( + 841D4D732106B59F00DD04E6 /* Articles.framework */, 848E3EBC20FBCFDE0004B7ED /* RSDatabase.framework */, 848E3EBA20FBCFD80004B7ED /* RSParser.framework */, 848E3EB820FBCFD20004B7ED /* RSCore.framework */, @@ -284,11 +286,11 @@ D511EEE620242E0800712EC3 /* xcconfig */ = { isa = PBXGroup; children = ( - D511EEE720242E0800712EC3 /* DatabaseTests_target.xcconfig */, - D511EEE820242E0800712EC3 /* Database_target.xcconfig */, - D511EEE920242E0800712EC3 /* Database_project.xcconfig */, - D511EEEA20242E0800712EC3 /* Database_project_debug.xcconfig */, - D511EEEB20242E0800712EC3 /* Database_project_release.xcconfig */, + D511EEE720242E0800712EC3 /* ArticlesDatabaseTests_target.xcconfig */, + D511EEE820242E0800712EC3 /* ArticlesDatabase_target.xcconfig */, + D511EEE920242E0800712EC3 /* ArticlesDatabase_project.xcconfig */, + D511EEEA20242E0800712EC3 /* ArticlesDatabase_project_debug.xcconfig */, + D511EEEB20242E0800712EC3 /* ArticlesDatabase_project_release.xcconfig */, ); path = xcconfig; sourceTree = ""; @@ -306,9 +308,9 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 844BEE361F0AB3AA004AB7CD /* Database */ = { + 844BEE361F0AB3AA004AB7CD /* ArticlesDatabase */ = { isa = PBXNativeTarget; - buildConfigurationList = 844BEE4B1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "Database" */; + buildConfigurationList = 844BEE4B1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "ArticlesDatabase" */; buildPhases = ( 844BEE321F0AB3AA004AB7CD /* Sources */, 844BEE331F0AB3AA004AB7CD /* Frameworks */, @@ -319,14 +321,14 @@ ); dependencies = ( ); - name = Database; + name = ArticlesDatabase; productName = Database; - productReference = 844BEE371F0AB3AA004AB7CD /* Database.framework */; + productReference = 844BEE371F0AB3AA004AB7CD /* ArticlesDatabase.framework */; productType = "com.apple.product-type.framework"; }; - 844BEE3F1F0AB3AB004AB7CD /* DatabaseTests */ = { + 844BEE3F1F0AB3AB004AB7CD /* ArticlesDatabaseTests */ = { isa = PBXNativeTarget; - buildConfigurationList = 844BEE4E1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "DatabaseTests" */; + buildConfigurationList = 844BEE4E1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "ArticlesDatabaseTests" */; buildPhases = ( 844BEE3C1F0AB3AB004AB7CD /* Sources */, 844BEE3D1F0AB3AB004AB7CD /* Frameworks */, @@ -337,9 +339,9 @@ dependencies = ( 844BEE431F0AB3AB004AB7CD /* PBXTargetDependency */, ); - name = DatabaseTests; + name = ArticlesDatabaseTests; productName = DatabaseTests; - productReference = 844BEE401F0AB3AB004AB7CD /* DatabaseTests.xctest */; + productReference = 844BEE401F0AB3AB004AB7CD /* ArticlesDatabaseTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -365,7 +367,7 @@ }; }; }; - buildConfigurationList = 844BEE311F0AB3AA004AB7CD /* Build configuration list for PBXProject "Database" */; + buildConfigurationList = 844BEE311F0AB3AA004AB7CD /* Build configuration list for PBXProject "ArticlesDatabase" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -395,8 +397,8 @@ ); projectRoot = ""; targets = ( - 844BEE361F0AB3AA004AB7CD /* Database */, - 844BEE3F1F0AB3AB004AB7CD /* DatabaseTests */, + 844BEE361F0AB3AA004AB7CD /* ArticlesDatabase */, + 844BEE3F1F0AB3AB004AB7CD /* ArticlesDatabaseTests */, ); }; /* End PBXProject section */ @@ -512,7 +514,7 @@ 843702C31F70D15D00B18807 /* ParsedArticle+Database.swift in Sources */, 84E156EC1F0AB80E00F8CC05 /* ArticlesTable.swift in Sources */, 84E156EE1F0AB81400F8CC05 /* StatusesTable.swift in Sources */, - 84E156EA1F0AB80500F8CC05 /* Database.swift in Sources */, + 84E156EA1F0AB80500F8CC05 /* ArticlesDatabase.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -530,7 +532,7 @@ /* Begin PBXTargetDependency section */ 844BEE431F0AB3AB004AB7CD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 844BEE361F0AB3AA004AB7CD /* Database */; + target = 844BEE361F0AB3AA004AB7CD /* ArticlesDatabase */; targetProxy = 844BEE421F0AB3AB004AB7CD /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -538,7 +540,7 @@ /* Begin XCBuildConfiguration section */ 844BEE491F0AB3AB004AB7CD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEEA20242E0800712EC3 /* Database_project_debug.xcconfig */; + baseConfigurationReference = D511EEEA20242E0800712EC3 /* ArticlesDatabase_project_debug.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; @@ -547,7 +549,7 @@ }; 844BEE4A1F0AB3AB004AB7CD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEEB20242E0800712EC3 /* Database_project_release.xcconfig */; + baseConfigurationReference = D511EEEB20242E0800712EC3 /* ArticlesDatabase_project_release.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = "-"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; @@ -556,36 +558,42 @@ }; 844BEE4C1F0AB3AB004AB7CD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEE820242E0800712EC3 /* Database_target.xcconfig */; + baseConfigurationReference = D511EEE820242E0800712EC3 /* ArticlesDatabase_target.xcconfig */; buildSettings = { + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.ArticlesDatabase; + PRODUCT_NAME = ArticlesDatabase; }; name = Debug; }; 844BEE4D1F0AB3AB004AB7CD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEE820242E0800712EC3 /* Database_target.xcconfig */; + baseConfigurationReference = D511EEE820242E0800712EC3 /* ArticlesDatabase_target.xcconfig */; buildSettings = { + PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.ArticlesDatabase; + PRODUCT_NAME = ArticlesDatabase; }; name = Release; }; 844BEE4F1F0AB3AB004AB7CD /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEE720242E0800712EC3 /* DatabaseTests_target.xcconfig */; + baseConfigurationReference = D511EEE720242E0800712EC3 /* ArticlesDatabaseTests_target.xcconfig */; buildSettings = { + PRODUCT_NAME = ArticlesDatabaseTests; }; name = Debug; }; 844BEE501F0AB3AB004AB7CD /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D511EEE720242E0800712EC3 /* DatabaseTests_target.xcconfig */; + baseConfigurationReference = D511EEE720242E0800712EC3 /* ArticlesDatabaseTests_target.xcconfig */; buildSettings = { + PRODUCT_NAME = ArticlesDatabaseTests; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 844BEE311F0AB3AA004AB7CD /* Build configuration list for PBXProject "Database" */ = { + 844BEE311F0AB3AA004AB7CD /* Build configuration list for PBXProject "ArticlesDatabase" */ = { isa = XCConfigurationList; buildConfigurations = ( 844BEE491F0AB3AB004AB7CD /* Debug */, @@ -594,7 +602,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 844BEE4B1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "Database" */ = { + 844BEE4B1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "ArticlesDatabase" */ = { isa = XCConfigurationList; buildConfigurations = ( 844BEE4C1F0AB3AB004AB7CD /* Debug */, @@ -603,7 +611,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 844BEE4E1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "DatabaseTests" */ = { + 844BEE4E1F0AB3AB004AB7CD /* Build configuration list for PBXNativeTarget "ArticlesDatabaseTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 844BEE4F1F0AB3AB004AB7CD /* Debug */, diff --git a/Frameworks/Database/Database.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Frameworks/Database/Database.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Frameworks/Database/ArticlesTable.swift b/Frameworks/ArticlesDatabase/ArticlesTable.swift similarity index 99% rename from Frameworks/Database/ArticlesTable.swift rename to Frameworks/ArticlesDatabase/ArticlesTable.swift index ea251ab70..c743bd1cb 100644 --- a/Frameworks/Database/ArticlesTable.swift +++ b/Frameworks/ArticlesDatabase/ArticlesTable.swift @@ -10,7 +10,7 @@ import Foundation import RSCore import RSDatabase import RSParser -import Data +import Articles final class ArticlesTable: DatabaseTable { diff --git a/Frameworks/Database/AttachmentsTable.swift b/Frameworks/ArticlesDatabase/AttachmentsTable.swift similarity index 97% rename from Frameworks/Database/AttachmentsTable.swift rename to Frameworks/ArticlesDatabase/AttachmentsTable.swift index 122d06aef..f243c9a76 100644 --- a/Frameworks/Database/AttachmentsTable.swift +++ b/Frameworks/ArticlesDatabase/AttachmentsTable.swift @@ -8,7 +8,7 @@ import Foundation import RSDatabase -import Data +import Articles final class AttachmentsTable: DatabaseRelatedObjectsTable { diff --git a/Frameworks/Database/AuthorsTable.swift b/Frameworks/ArticlesDatabase/AuthorsTable.swift similarity index 98% rename from Frameworks/Database/AuthorsTable.swift rename to Frameworks/ArticlesDatabase/AuthorsTable.swift index 01836753f..8d041f927 100644 --- a/Frameworks/Database/AuthorsTable.swift +++ b/Frameworks/ArticlesDatabase/AuthorsTable.swift @@ -8,7 +8,7 @@ import Foundation import RSDatabase -import Data +import Articles // article->authors is a many-to-many relationship. // There’s a lookup table relating authorID and articleID. diff --git a/Frameworks/Database/Constants.swift b/Frameworks/ArticlesDatabase/Constants.swift similarity index 100% rename from Frameworks/Database/Constants.swift rename to Frameworks/ArticlesDatabase/Constants.swift diff --git a/Frameworks/Database/CreateStatements.sql b/Frameworks/ArticlesDatabase/CreateStatements.sql similarity index 100% rename from Frameworks/Database/CreateStatements.sql rename to Frameworks/ArticlesDatabase/CreateStatements.sql diff --git a/Frameworks/Database/DatabaseArticle.swift b/Frameworks/ArticlesDatabase/DatabaseArticle.swift similarity index 99% rename from Frameworks/Database/DatabaseArticle.swift rename to Frameworks/ArticlesDatabase/DatabaseArticle.swift index 3156cc188..c6239589d 100644 --- a/Frameworks/Database/DatabaseArticle.swift +++ b/Frameworks/ArticlesDatabase/DatabaseArticle.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles // Intermediate representation of an Article. Doesn’t include related objects. // Used by ArticlesTable as part of fetching articles. diff --git a/Frameworks/Database/DatabaseObject+Database.swift b/Frameworks/ArticlesDatabase/DatabaseObject+Database.swift similarity index 97% rename from Frameworks/Database/DatabaseObject+Database.swift rename to Frameworks/ArticlesDatabase/DatabaseObject+Database.swift index 4a9bbf55f..0d9c3d8e1 100644 --- a/Frameworks/Database/DatabaseObject+Database.swift +++ b/Frameworks/ArticlesDatabase/DatabaseObject+Database.swift @@ -8,7 +8,7 @@ import Foundation import RSDatabase -import Data +import Articles extension Array where Element == DatabaseObject { diff --git a/Frameworks/Database/DatabaseTests/ArticleChangesTests.swift b/Frameworks/ArticlesDatabase/DatabaseTests/ArticleChangesTests.swift similarity index 86% rename from Frameworks/Database/DatabaseTests/ArticleChangesTests.swift rename to Frameworks/ArticlesDatabase/DatabaseTests/ArticleChangesTests.swift index 75bac0931..2848cba63 100644 --- a/Frameworks/Database/DatabaseTests/ArticleChangesTests.swift +++ b/Frameworks/ArticlesDatabase/DatabaseTests/ArticleChangesTests.swift @@ -7,7 +7,7 @@ // import XCTest -@testable import Database +@testable import ArticlesDatabase class ArticleChangesTests: XCTestCase { diff --git a/Frameworks/Database/DatabaseTests/DatabaseTests.swift b/Frameworks/ArticlesDatabase/DatabaseTests/DatabaseTests.swift similarity index 96% rename from Frameworks/Database/DatabaseTests/DatabaseTests.swift rename to Frameworks/ArticlesDatabase/DatabaseTests/DatabaseTests.swift index 036317c2b..53d697cb2 100644 --- a/Frameworks/Database/DatabaseTests/DatabaseTests.swift +++ b/Frameworks/ArticlesDatabase/DatabaseTests/DatabaseTests.swift @@ -7,7 +7,7 @@ // import XCTest -@testable import Database +@testable import ArticlesDatabase class DatabaseTests: XCTestCase { diff --git a/Frameworks/Database/DatabaseTests/Info.plist b/Frameworks/ArticlesDatabase/DatabaseTests/Info.plist similarity index 100% rename from Frameworks/Database/DatabaseTests/Info.plist rename to Frameworks/ArticlesDatabase/DatabaseTests/Info.plist diff --git a/Frameworks/Database/Extensions/Article+Database.swift b/Frameworks/ArticlesDatabase/Extensions/Article+Database.swift similarity index 99% rename from Frameworks/Database/Extensions/Article+Database.swift rename to Frameworks/ArticlesDatabase/Extensions/Article+Database.swift index 8d3d0e8b4..6a6217bd7 100644 --- a/Frameworks/Database/Extensions/Article+Database.swift +++ b/Frameworks/ArticlesDatabase/Extensions/Article+Database.swift @@ -8,7 +8,7 @@ import Foundation import RSDatabase -import Data +import Articles import RSParser extension Article { diff --git a/Frameworks/Database/Extensions/ArticleStatus+Database.swift b/Frameworks/ArticlesDatabase/Extensions/ArticleStatus+Database.swift similarity index 98% rename from Frameworks/Database/Extensions/ArticleStatus+Database.swift rename to Frameworks/ArticlesDatabase/Extensions/ArticleStatus+Database.swift index 728b41b5f..079611ec6 100644 --- a/Frameworks/Database/Extensions/ArticleStatus+Database.swift +++ b/Frameworks/ArticlesDatabase/Extensions/ArticleStatus+Database.swift @@ -8,7 +8,7 @@ import Foundation import RSDatabase -import Data +import Articles extension ArticleStatus { diff --git a/Frameworks/Database/Extensions/Attachment+Database.swift b/Frameworks/ArticlesDatabase/Extensions/Attachment+Database.swift similarity index 99% rename from Frameworks/Database/Extensions/Attachment+Database.swift rename to Frameworks/ArticlesDatabase/Extensions/Attachment+Database.swift index 3540dc824..a1a0ce1aa 100644 --- a/Frameworks/Database/Extensions/Attachment+Database.swift +++ b/Frameworks/ArticlesDatabase/Extensions/Attachment+Database.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import RSDatabase import RSParser diff --git a/Frameworks/Database/Extensions/Author+Database.swift b/Frameworks/ArticlesDatabase/Extensions/Author+Database.swift similarity index 99% rename from Frameworks/Database/Extensions/Author+Database.swift rename to Frameworks/ArticlesDatabase/Extensions/Author+Database.swift index a885e81cc..8ae1839a2 100644 --- a/Frameworks/Database/Extensions/Author+Database.swift +++ b/Frameworks/ArticlesDatabase/Extensions/Author+Database.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import RSDatabase import RSParser diff --git a/Frameworks/Database/Extensions/Feed+Database.swift b/Frameworks/ArticlesDatabase/Extensions/Feed+Database.swift similarity index 94% rename from Frameworks/Database/Extensions/Feed+Database.swift rename to Frameworks/ArticlesDatabase/Extensions/Feed+Database.swift index 581304278..f56feecfe 100644 --- a/Frameworks/Database/Extensions/Feed+Database.swift +++ b/Frameworks/ArticlesDatabase/Extensions/Feed+Database.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles extension Set where Element == Feed { diff --git a/Frameworks/Database/Extensions/ParsedArticle+Database.swift b/Frameworks/ArticlesDatabase/Extensions/ParsedArticle+Database.swift similarity index 96% rename from Frameworks/Database/Extensions/ParsedArticle+Database.swift rename to Frameworks/ArticlesDatabase/Extensions/ParsedArticle+Database.swift index d232e4b79..d89f707ab 100644 --- a/Frameworks/Database/Extensions/ParsedArticle+Database.swift +++ b/Frameworks/ArticlesDatabase/Extensions/ParsedArticle+Database.swift @@ -8,7 +8,7 @@ import Foundation import RSParser -import Data +import Articles extension ParsedItem { diff --git a/Frameworks/Database/Info.plist b/Frameworks/ArticlesDatabase/Info.plist similarity index 100% rename from Frameworks/Database/Info.plist rename to Frameworks/ArticlesDatabase/Info.plist diff --git a/Frameworks/Database/RelatedObjectsMap+Database.swift b/Frameworks/ArticlesDatabase/RelatedObjectsMap+Database.swift similarity index 97% rename from Frameworks/Database/RelatedObjectsMap+Database.swift rename to Frameworks/ArticlesDatabase/RelatedObjectsMap+Database.swift index 74f39b4ce..09a78b807 100644 --- a/Frameworks/Database/RelatedObjectsMap+Database.swift +++ b/Frameworks/ArticlesDatabase/RelatedObjectsMap+Database.swift @@ -8,7 +8,7 @@ import Foundation import RSDatabase -import Data +import Articles extension RelatedObjectsMap { diff --git a/Frameworks/Database/StatusesTable.swift b/Frameworks/ArticlesDatabase/StatusesTable.swift similarity index 99% rename from Frameworks/Database/StatusesTable.swift rename to Frameworks/ArticlesDatabase/StatusesTable.swift index a5ab9eb75..8f5318a18 100644 --- a/Frameworks/Database/StatusesTable.swift +++ b/Frameworks/ArticlesDatabase/StatusesTable.swift @@ -9,7 +9,7 @@ import Foundation import RSCore import RSDatabase -import Data +import Articles // Article->ArticleStatus is a to-one relationship. // diff --git a/Frameworks/Database/UnreadCountDictionary.swift b/Frameworks/ArticlesDatabase/UnreadCountDictionary.swift similarity index 97% rename from Frameworks/Database/UnreadCountDictionary.swift rename to Frameworks/ArticlesDatabase/UnreadCountDictionary.swift index a467ec009..702f7c32d 100644 --- a/Frameworks/Database/UnreadCountDictionary.swift +++ b/Frameworks/ArticlesDatabase/UnreadCountDictionary.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles public struct UnreadCountDictionary { diff --git a/Frameworks/Database/xcconfig/DatabaseTests_target.xcconfig b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabaseTests_target.xcconfig similarity index 78% rename from Frameworks/Database/xcconfig/DatabaseTests_target.xcconfig rename to Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabaseTests_target.xcconfig index cf6b48da7..d56b73b8f 100644 --- a/Frameworks/Database/xcconfig/DatabaseTests_target.xcconfig +++ b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabaseTests_target.xcconfig @@ -1,7 +1,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks INFOPLIST_FILE = DatabaseTests/Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.DatabaseTests +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.ArticlesDatabaseTests PRODUCT_NAME = $(TARGET_NAME) diff --git a/Frameworks/Database/xcconfig/Database_project.xcconfig b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project.xcconfig similarity index 100% rename from Frameworks/Database/xcconfig/Database_project.xcconfig rename to Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project.xcconfig diff --git a/Frameworks/Database/xcconfig/Database_project_debug.xcconfig b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project_debug.xcconfig similarity index 87% rename from Frameworks/Database/xcconfig/Database_project_debug.xcconfig rename to Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project_debug.xcconfig index cef316083..a5f5e3fa2 100644 --- a/Frameworks/Database/xcconfig/Database_project_debug.xcconfig +++ b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project_debug.xcconfig @@ -1,4 +1,4 @@ -#include "./Database_project.xcconfig" +#include "./ArticlesDatabase_project.xcconfig" DEBUG_INFORMATION_FORMAT = dwarf ENABLE_TESTABILITY = YES diff --git a/Frameworks/Data/xcconfig/Data_project_release.xcconfig b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project_release.xcconfig similarity index 77% rename from Frameworks/Data/xcconfig/Data_project_release.xcconfig rename to Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project_release.xcconfig index 07867d541..e81a65a29 100644 --- a/Frameworks/Data/xcconfig/Data_project_release.xcconfig +++ b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_project_release.xcconfig @@ -1,4 +1,4 @@ -#include "./Data_project.xcconfig" +#include "./ArticlesDatabase_project.xcconfig" DEBUG_INFORMATION_FORMAT = dwarf-with-dsym ENABLE_NS_ASSERTIONS = NO diff --git a/Frameworks/Database/xcconfig/Database_target.xcconfig b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_target.xcconfig similarity index 88% rename from Frameworks/Database/xcconfig/Database_target.xcconfig rename to Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_target.xcconfig index 3c1e45c05..7152d0233 100644 --- a/Frameworks/Database/xcconfig/Database_target.xcconfig +++ b/Frameworks/ArticlesDatabase/xcconfig/ArticlesDatabase_target.xcconfig @@ -10,7 +10,7 @@ LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_pa DEFINES_MODULE = YES FRAMEWORK_VERSION = A INFOPLIST_FILE = Info.plist -PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Database +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.ArticlesDatabase PRODUCT_NAME = $(TARGET_NAME) CLANG_ENABLE_MODULES = YES diff --git a/Importers/DefaultFeedsImporter.swift b/Importers/DefaultFeedsImporter.swift index 2d57a93ce..d1ba7404e 100644 --- a/Importers/DefaultFeedsImporter.swift +++ b/Importers/DefaultFeedsImporter.swift @@ -7,7 +7,7 @@ // import Foundation -import Data +import Articles import Account import RSCore From fc338d537112a1a2d33f332a68cc9324a31b73b6 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 28 Jul 2018 12:16:14 -0700 Subject: [PATCH 34/40] Move Feed from Articles.framework to Account.framework. --- Evergreen/Favicons/FaviconDownloader.swift | 1 + Evergreen/Images/FeedIconDownloader.swift | 1 + .../FeedInspectorViewController.swift | 1 + .../MainWindow/Detail/ArticleRenderer.swift | 1 + .../Sidebar/FeedPasteboardWriter.swift | 1 + Evergreen/SmartFeeds/PseudoFeed.swift | 1 + Frameworks/Account/Account.swift | 22 +++++------ .../Account/Account.xcodeproj/project.pbxproj | 12 ++++++ Frameworks/{Articles => Account}/Feed.swift | 8 ++++ .../UnreadCountProvider.swift | 0 .../Articles.xcodeproj/project.pbxproj | 10 ----- Frameworks/Articles/Author.swift | 5 +-- .../ArticlesDatabase/ArticlesDatabase.swift | 36 +++++++++--------- .../project.pbxproj | 4 -- .../ArticlesDatabase/ArticlesTable.swift | 37 ++++++++----------- .../Extensions/Feed+Database.swift | 18 --------- .../UnreadCountDictionary.swift | 6 +-- 17 files changed, 73 insertions(+), 91 deletions(-) rename Frameworks/{Articles => Account}/Feed.swift (97%) rename Frameworks/{Articles => Account}/UnreadCountProvider.swift (100%) delete mode 100644 Frameworks/ArticlesDatabase/Extensions/Feed+Database.swift diff --git a/Evergreen/Favicons/FaviconDownloader.swift b/Evergreen/Favicons/FaviconDownloader.swift index a217543b9..c15232502 100644 --- a/Evergreen/Favicons/FaviconDownloader.swift +++ b/Evergreen/Favicons/FaviconDownloader.swift @@ -8,6 +8,7 @@ import AppKit import Articles +import Account import RSCore extension Notification.Name { diff --git a/Evergreen/Images/FeedIconDownloader.swift b/Evergreen/Images/FeedIconDownloader.swift index ced3a560a..2707c985b 100644 --- a/Evergreen/Images/FeedIconDownloader.swift +++ b/Evergreen/Images/FeedIconDownloader.swift @@ -8,6 +8,7 @@ import AppKit import Articles +import Account import RSWeb import RSParser diff --git a/Evergreen/Inspector/FeedInspectorViewController.swift b/Evergreen/Inspector/FeedInspectorViewController.swift index 48faa1316..5ca6c7ea2 100644 --- a/Evergreen/Inspector/FeedInspectorViewController.swift +++ b/Evergreen/Inspector/FeedInspectorViewController.swift @@ -8,6 +8,7 @@ import AppKit import Articles +import Account import DB5 final class FeedInspectorViewController: NSViewController, Inspector { diff --git a/Evergreen/MainWindow/Detail/ArticleRenderer.swift b/Evergreen/MainWindow/Detail/ArticleRenderer.swift index 51f1fd451..7975bde63 100644 --- a/Evergreen/MainWindow/Detail/ArticleRenderer.swift +++ b/Evergreen/MainWindow/Detail/ArticleRenderer.swift @@ -9,6 +9,7 @@ import Foundation import RSCore import Articles +import Account var cachedStyleString = "" var cachedTemplate = "" diff --git a/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift b/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift index 4fcf1abad..03a945b29 100644 --- a/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift +++ b/Evergreen/MainWindow/Sidebar/FeedPasteboardWriter.swift @@ -8,6 +8,7 @@ import AppKit import Articles +import Account import RSCore extension Feed: PasteboardWriterOwner { diff --git a/Evergreen/SmartFeeds/PseudoFeed.swift b/Evergreen/SmartFeeds/PseudoFeed.swift index 8cb907e89..c5b781bc8 100644 --- a/Evergreen/SmartFeeds/PseudoFeed.swift +++ b/Evergreen/SmartFeeds/PseudoFeed.swift @@ -8,6 +8,7 @@ import Foundation import Articles +import Account import RSCore protocol PseudoFeed: class, DisplayNameProvider, UnreadCountProvider, SmallIconProvider, PasteboardWriterOwner { diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 78efda534..b5f198220 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -140,7 +140,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, feed.takeSettings(from: parsedFeed) - database.update(feed: feed, parsedFeed: parsedFeed) { (newArticles, updatedArticles) in + database.update(feedID: feed.feedID, parsedFeed: parsedFeed) { (newArticles, updatedArticles) in var userInfo = [String: Any]() if let newArticles = newArticles, !newArticles.isEmpty { @@ -302,10 +302,10 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, return } - database.fetchUnreadCounts(for: feeds) { (unreadCountDictionary) in + database.fetchUnreadCounts(for: feeds.feedIDs()) { (unreadCountDictionary) in for feed in feeds { - if let unreadCount = unreadCountDictionary[feed] { + if let unreadCount = unreadCountDictionary[feed.feedID] { feed.unreadCount = unreadCount } } @@ -314,14 +314,14 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public func fetchArticles(for feed: Feed) -> Set
{ - let articles = database.fetchArticles(for: feed) + let articles = database.fetchArticles(for: feed.feedID) validateUnreadCount(feed, articles) return articles } public func fetchUnreadArticles(for feed: Feed) -> Set
{ - let articles = database.fetchUnreadArticles(for: Set([feed])) + let articles = database.fetchUnreadArticles(for: Set([feed.feedID])) validateUnreadCount(feed, articles) return articles } @@ -339,19 +339,19 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public func fetchUnreadArticles(forContainer container: Container) -> Set
{ let feeds = container.flattenedFeeds() - let articles = database.fetchUnreadArticles(for: feeds) + let articles = database.fetchUnreadArticles(for: feeds.feedIDs()) feeds.forEach { validateUnreadCount($0, articles) } return articles } public func fetchTodayArticles() -> Set
{ - return database.fetchTodayArticles(for: flattenedFeeds()) + return database.fetchTodayArticles(for: flattenedFeeds().feedIDs()) } public func fetchStarredArticles() -> Set
{ - return database.fetchStarredArticles(for: flattenedFeeds()) + return database.fetchStarredArticles(for: flattenedFeeds().feedIDs()) } private func validateUnreadCount(_ feed: Feed, _ articles: Set
) { @@ -372,12 +372,12 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public func fetchUnreadCountForToday(_ callback: @escaping (Int) -> Void) { let startOfToday = NSCalendar.startOfToday() - database.fetchUnreadCount(for: flattenedFeeds(), since: startOfToday, callback: callback) + database.fetchUnreadCount(for: flattenedFeeds().feedIDs(), since: startOfToday, callback: callback) } public func fetchUnreadCountForStarredArticles(_ callback: @escaping (Int) -> Void) { - database.fetchStarredAndUnreadCount(for: flattenedFeeds(), callback: callback) + database.fetchStarredAndUnreadCount(for: flattenedFeeds().feedIDs(), callback: callback) } public func markEverywhereAsRead() { @@ -680,7 +680,7 @@ private extension Account { // When the unread count is zero, it won’t appear in unreadCountDictionary. - if let unreadCount = unreadCountDictionary[feed] { + if let unreadCount = unreadCountDictionary[feed.feedID] { feed.unreadCount = unreadCount } else { diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index c638acb16..f4960f843 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -17,6 +17,9 @@ 84245C811FDDD42A0074AFBB /* Feedbin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84245C801FDDD42A0074AFBB /* Feedbin.swift */; }; 84245C831FDDD8160074AFBB /* FeedbinGetSubscriptionsDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84245C821FDDD8160074AFBB /* FeedbinGetSubscriptionsDelegate.swift */; }; 84245C851FDDD8CB0074AFBB /* FeedbinSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84245C841FDDD8CB0074AFBB /* FeedbinSubscription.swift */; }; + 844B297D2106C7EC004020B3 /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B297C2106C7EC004020B3 /* Feed.swift */; }; + 844B297F210CE37E004020B3 /* UnreadCountProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844B297E210CE37E004020B3 /* UnreadCountProvider.swift */; }; + 844B2981210CE3BF004020B3 /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844B2980210CE3BF004020B3 /* RSWeb.framework */; }; 8469F81C1F6DD15E0084783E /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848935101F62486800CEBD24 /* Account.swift */; }; 846E77451F6EF9B900A165E2 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419740D1F6DD25F006346C4 /* Container.swift */; }; 846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419742C1F6DDE84006346C4 /* LocalAccountDelegate.swift */; }; @@ -120,6 +123,9 @@ 84245C801FDDD42A0074AFBB /* Feedbin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Feedbin.swift; sourceTree = ""; }; 84245C821FDDD8160074AFBB /* FeedbinGetSubscriptionsDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinGetSubscriptionsDelegate.swift; sourceTree = ""; }; 84245C841FDDD8CB0074AFBB /* FeedbinSubscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinSubscription.swift; sourceTree = ""; }; + 844B297C2106C7EC004020B3 /* Feed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = ""; }; + 844B297E210CE37E004020B3 /* UnreadCountProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnreadCountProvider.swift; sourceTree = ""; }; + 844B2980210CE3BF004020B3 /* RSWeb.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSWeb.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 846E77531F6F00E300A165E2 /* AccountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = ""; }; 848934F61F62484F00CEBD24 /* Account.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Account.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 848934FA1F62484F00CEBD24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -144,6 +150,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 844B2981210CE3BF004020B3 /* RSWeb.framework in Frameworks */, 841D4D722106B40A00DD04E6 /* Articles.framework in Frameworks */, 841D4D702106B40400DD04E6 /* ArticlesDatabase.framework in Frameworks */, 841973FE1F6DD1BC006346C4 /* RSCore.framework in Frameworks */, @@ -223,6 +230,7 @@ 8469F80F1F6DC3C10084783E /* Frameworks */ = { isa = PBXGroup; children = ( + 844B2980210CE3BF004020B3 /* RSWeb.framework */, 841D4D712106B40A00DD04E6 /* Articles.framework */, 841D4D6F2106B40400DD04E6 /* ArticlesDatabase.framework */, 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */, @@ -240,6 +248,8 @@ 848935101F62486800CEBD24 /* Account.swift */, 841974241F6DDCE4006346C4 /* AccountDelegate.swift */, 841974001F6DD1EC006346C4 /* Folder.swift */, + 844B297C2106C7EC004020B3 /* Feed.swift */, + 844B297E210CE37E004020B3 /* UnreadCountProvider.swift */, 84B99C9E1FAE8D3200ECDEDB /* ContainerPath.swift */, 84C365491F899F3B001EC85C /* CombinedRefreshProgress.swift */, 84C8B3F31F89DE430053CCA6 /* DataExtensions.swift */, @@ -487,12 +497,14 @@ 84245C7F1FDDD2580074AFBB /* FeedbinAccountDelegate.swift in Sources */, 841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */, 846E77541F6F00E300A165E2 /* AccountManager.swift in Sources */, + 844B297D2106C7EC004020B3 /* Feed.swift in Sources */, 84B99C9F1FAE8D3200ECDEDB /* ContainerPath.swift in Sources */, 846E77501F6EF9C400A165E2 /* LocalAccountRefresher.swift in Sources */, 84245C811FDDD42A0074AFBB /* Feedbin.swift in Sources */, 84CAD7161FDF2E22000F0755 /* FeedbinArticle.swift in Sources */, 841974011F6DD1EC006346C4 /* Folder.swift in Sources */, 846E774F1F6EF9C000A165E2 /* LocalAccountDelegate.swift in Sources */, + 844B297F210CE37E004020B3 /* UnreadCountProvider.swift in Sources */, 84245C851FDDD8CB0074AFBB /* FeedbinSubscription.swift in Sources */, 84245C831FDDD8160074AFBB /* FeedbinGetSubscriptionsDelegate.swift in Sources */, ); diff --git a/Frameworks/Articles/Feed.swift b/Frameworks/Account/Feed.swift similarity index 97% rename from Frameworks/Articles/Feed.swift rename to Frameworks/Account/Feed.swift index 41e83cce8..aa0cabb8b 100644 --- a/Frameworks/Articles/Feed.swift +++ b/Frameworks/Account/Feed.swift @@ -9,6 +9,7 @@ import Foundation import RSCore import RSWeb +import Articles public final class Feed: DisplayNameProvider, UnreadCountProvider, Hashable { @@ -189,3 +190,10 @@ extension Feed: OPMLRepresentable { } } +extension Set where Element == Feed { + + func feedIDs() -> Set { + + return Set(map { $0.feedID }) + } +} diff --git a/Frameworks/Articles/UnreadCountProvider.swift b/Frameworks/Account/UnreadCountProvider.swift similarity index 100% rename from Frameworks/Articles/UnreadCountProvider.swift rename to Frameworks/Account/UnreadCountProvider.swift diff --git a/Frameworks/Articles/Articles.xcodeproj/project.pbxproj b/Frameworks/Articles/Articles.xcodeproj/project.pbxproj index 93b66224d..e626d849b 100644 --- a/Frameworks/Articles/Articles.xcodeproj/project.pbxproj +++ b/Frameworks/Articles/Articles.xcodeproj/project.pbxproj @@ -8,16 +8,13 @@ /* Begin PBXBuildFile section */ 840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840405C91F1A8E4300DF0296 /* DatabaseID.swift */; }; - 8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */; }; 844BEE651F0AB3C9004AB7CD /* Articles.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844BEE5B1F0AB3C8004AB7CD /* Articles.framework */; }; 844BEE6A1F0AB3C9004AB7CD /* DataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BEE691F0AB3C9004AB7CD /* DataTests.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 */; }; 848E3EB420FBCFAE0004B7ED /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EB320FBCFAE0004B7ED /* RSCore.framework */; }; - 848E3EB520FBCFB50004B7ED /* RSWeb.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C490F51F705D5F003131D2 /* RSWeb.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -53,13 +50,11 @@ /* Begin PBXFileReference section */ 840405C91F1A8E4300DF0296 /* DatabaseID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseID.swift; sourceTree = ""; }; - 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadCountProvider.swift; sourceTree = ""; }; 844BEE5B1F0AB3C8004AB7CD /* Articles.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Articles.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 844BEE641F0AB3C9004AB7CD /* ArticlesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ArticlesTests.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 = ""; }; - 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 = ""; }; @@ -79,7 +74,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 848E3EB520FBCFB50004B7ED /* RSWeb.framework in Frameworks */, 848E3EB420FBCFAE0004B7ED /* RSCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -98,13 +92,11 @@ 844BEE511F0AB3C8004AB7CD = { isa = PBXGroup; children = ( - 844BEE7C1F0AB4C4004AB7CD /* Feed.swift */, 844BEE7E1F0AB4CA004AB7CD /* Article.swift */, 844BEE801F0AB4D0004AB7CD /* Author.swift */, 844BEE821F0AB4D6004AB7CD /* Attachment.swift */, 844BEE841F0AB4DB004AB7CD /* ArticleStatus.swift */, 840405C91F1A8E4300DF0296 /* DatabaseID.swift */, - 8419741B1F6DD613006346C4 /* UnreadCountProvider.swift */, 844BEE761F0AB444004AB7CD /* Info.plist */, 844BEE681F0AB3C9004AB7CD /* DataTests */, 844BEE5C1F0AB3C8004AB7CD /* Products */, @@ -306,9 +298,7 @@ buildActionMask = 2147483647; files = ( 844BEE7F1F0AB4CA004AB7CD /* Article.swift in Sources */, - 844BEE7D1F0AB4C4004AB7CD /* Feed.swift in Sources */, 844BEE831F0AB4D6004AB7CD /* Attachment.swift in Sources */, - 8419741C1F6DD613006346C4 /* UnreadCountProvider.swift in Sources */, 844BEE811F0AB4D0004AB7CD /* Author.swift in Sources */, 840405CA1F1A8E4300DF0296 /* DatabaseID.swift in Sources */, 844BEE851F0AB4DB004AB7CD /* ArticleStatus.swift in Sources */, diff --git a/Frameworks/Articles/Author.swift b/Frameworks/Articles/Author.swift index df25a8741..29118d679 100644 --- a/Frameworks/Articles/Author.swift +++ b/Frameworks/Articles/Author.swift @@ -7,7 +7,6 @@ // import Foundation -import RSCore public struct Author: Hashable { @@ -82,7 +81,7 @@ public struct Author: Hashable { return lhs.hashValue == rhs.hashValue && lhs.authorID == rhs.authorID } - static func authorsWithDiskArray(_ diskArray: [[String: Any]]) -> Set? { + public static func authorsWithDiskArray(_ diskArray: [[String: Any]]) -> Set? { let authors = diskArray.compactMap { Author(dictionary: $0) } return authors.isEmpty ? nil : Set(authors) @@ -91,7 +90,7 @@ public struct Author: Hashable { extension Set where Element == Author { - func diskArray() -> [[String: Any]]? { + public func diskArray() -> [[String: Any]]? { if self.isEmpty { return nil diff --git a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift index 83c4a55f1..9d35fb56b 100644 --- a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift @@ -42,46 +42,46 @@ public final class ArticlesDatabase { // MARK: - Fetching Articles - public func fetchArticles(for feed: Feed) -> Set
{ + public func fetchArticles(for feedID: String) -> Set
{ - return articlesTable.fetchArticles(feed) + return articlesTable.fetchArticles(feedID) } - public func fetchArticlesAsync(for feed: Feed, _ resultBlock: @escaping ArticleResultBlock) { + public func fetchArticlesAsync(for feedID: String, _ resultBlock: @escaping ArticleResultBlock) { - articlesTable.fetchArticlesAsync(feed, withLimits: true, resultBlock) + articlesTable.fetchArticlesAsync(feedID, withLimits: true, resultBlock) } - public func fetchUnreadArticles(for feeds: Set) -> Set
{ + public func fetchUnreadArticles(for feedIDs: Set) -> Set
{ - return articlesTable.fetchUnreadArticles(for: feeds) + return articlesTable.fetchUnreadArticles(for: feedIDs) } - public func fetchTodayArticles(for feeds: Set) -> Set
{ + public func fetchTodayArticles(for feedIDs: Set) -> Set
{ - return articlesTable.fetchTodayArticles(for: feeds) + return articlesTable.fetchTodayArticles(for: feedIDs) } - public func fetchStarredArticles(for feeds: Set) -> Set
{ + public func fetchStarredArticles(for feedIDs: Set) -> Set
{ - return articlesTable.fetchStarredArticles(for: feeds) + return articlesTable.fetchStarredArticles(for: feedIDs) } // MARK: - Unread Counts - public func fetchUnreadCounts(for feeds: Set, _ completion: @escaping UnreadCountCompletionBlock) { + public func fetchUnreadCounts(for feedIDs: Set, _ completion: @escaping UnreadCountCompletionBlock) { - articlesTable.fetchUnreadCounts(feeds, completion) + articlesTable.fetchUnreadCounts(feedIDs, completion) } - public func fetchUnreadCount(for feeds: Set, since: Date, callback: @escaping (Int) -> Void) { + public func fetchUnreadCount(for feedIDs: Set, since: Date, callback: @escaping (Int) -> Void) { - articlesTable.fetchUnreadCount(feeds, since, callback) + articlesTable.fetchUnreadCount(feedIDs, since, callback) } - public func fetchStarredAndUnreadCount(for feeds: Set, callback: @escaping (Int) -> Void) { + public func fetchStarredAndUnreadCount(for feedIDs: Set, callback: @escaping (Int) -> Void) { - articlesTable.fetchStarredAndUnreadCount(feeds, callback) + articlesTable.fetchStarredAndUnreadCount(feedIDs, callback) } public func fetchAllNonZeroUnreadCounts(_ completion: @escaping UnreadCountCompletionBlock) { @@ -91,9 +91,9 @@ public final class ArticlesDatabase { // MARK: - Saving and Updating Articles - public func update(feed: Feed, parsedFeed: ParsedFeed, completion: @escaping UpdateArticlesWithFeedCompletionBlock) { + public func update(feedID: String, parsedFeed: ParsedFeed, completion: @escaping UpdateArticlesWithFeedCompletionBlock) { - return articlesTable.update(feed, parsedFeed, completion) + return articlesTable.update(feedID, parsedFeed, completion) } // MARK: - Status diff --git a/Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.pbxproj b/Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.pbxproj index e4e66fd8c..cb6c91d03 100644 --- a/Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.pbxproj +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.xcodeproj/project.pbxproj @@ -21,7 +21,6 @@ 845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580751F0AF670003CCFA1 /* Article+Database.swift */; }; 8455807A1F0AF67D003CCFA1 /* ArticleStatus+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845580791F0AF67D003CCFA1 /* ArticleStatus+Database.swift */; }; 8455807C1F0C0DBD003CCFA1 /* Attachment+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8455807B1F0C0DBD003CCFA1 /* Attachment+Database.swift */; }; - 846FB36B1F4A937B00EAB81D /* Feed+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846FB36A1F4A937B00EAB81D /* Feed+Database.swift */; }; 848AD2961F58A91E004FB0EC /* UnreadCountDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 848AD2951F58A91E004FB0EC /* UnreadCountDictionary.swift */; }; 848E3EB920FBCFD20004B7ED /* RSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EB820FBCFD20004B7ED /* RSCore.framework */; }; 848E3EBB20FBCFD80004B7ED /* RSParser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 848E3EBA20FBCFD80004B7ED /* RSParser.framework */; }; @@ -130,7 +129,6 @@ 845580791F0AF67D003CCFA1 /* ArticleStatus+Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "ArticleStatus+Database.swift"; path = "Extensions/ArticleStatus+Database.swift"; sourceTree = ""; }; 8455807B1F0C0DBD003CCFA1 /* Attachment+Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Attachment+Database.swift"; path = "Extensions/Attachment+Database.swift"; sourceTree = ""; }; 8461461E1F0ABC7300870CB3 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = ../RSParser/RSParser.xcodeproj; sourceTree = ""; }; - 846FB36A1F4A937B00EAB81D /* Feed+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Feed+Database.swift"; path = "Extensions/Feed+Database.swift"; sourceTree = ""; }; 848AD2951F58A91E004FB0EC /* UnreadCountDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadCountDictionary.swift; sourceTree = ""; }; 848E3EB820FBCFD20004B7ED /* RSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 848E3EBA20FBCFD80004B7ED /* RSParser.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RSParser.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -227,7 +225,6 @@ 8461462A1F0AC44100870CB3 /* Extensions */ = { isa = PBXGroup; children = ( - 846FB36A1F4A937B00EAB81D /* Feed+Database.swift */, 845580751F0AF670003CCFA1 /* Article+Database.swift */, 843702C21F70D15D00B18807 /* ParsedArticle+Database.swift */, 845580791F0AF67D003CCFA1 /* ArticleStatus+Database.swift */, @@ -500,7 +497,6 @@ buildActionMask = 2147483647; files = ( 845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */, - 846FB36B1F4A937B00EAB81D /* Feed+Database.swift in Sources */, 843CB9961F34174100EE6581 /* Author+Database.swift in Sources */, 848AD2961F58A91E004FB0EC /* UnreadCountDictionary.swift in Sources */, 845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */, diff --git a/Frameworks/ArticlesDatabase/ArticlesTable.swift b/Frameworks/ArticlesDatabase/ArticlesTable.swift index c743bd1cb..ea403b884 100644 --- a/Frameworks/ArticlesDatabase/ArticlesTable.swift +++ b/Frameworks/ArticlesDatabase/ArticlesTable.swift @@ -41,9 +41,8 @@ final class ArticlesTable: DatabaseTable { // MARK: Fetching - func fetchArticles(_ feed: Feed) -> Set
{ + func fetchArticles(_ feedID: String) -> Set
{ - let feedID = feed.feedID var articles = Set
() queue.fetchSync { (database) in @@ -53,9 +52,7 @@ final class ArticlesTable: DatabaseTable { return articles } - func fetchArticlesAsync(_ feed: Feed, withLimits: Bool, _ resultBlock: @escaping ArticleResultBlock) { - - let feedID = feed.feedID + func fetchArticlesAsync(_ feedID: String, withLimits: Bool, _ resultBlock: @escaping ArticleResultBlock) { queue.fetch { (database) in @@ -67,24 +64,24 @@ final class ArticlesTable: DatabaseTable { } } - func fetchUnreadArticles(for feeds: Set) -> Set
{ + func fetchUnreadArticles(for feedIDs: Set) -> Set
{ - return fetchUnreadArticles(feeds.feedIDs()) + return fetchUnreadArticles(feedIDs) } - public func fetchTodayArticles(for feeds: Set) -> Set
{ + public func fetchTodayArticles(for feedIDs: Set) -> Set
{ - return fetchTodayArticles(feeds.feedIDs()) + return fetchTodayArticles(feedIDs) } - public func fetchStarredArticles(for feeds: Set) -> Set
{ + public func fetchStarredArticles(for feedIDs: Set) -> Set
{ - return fetchStarredArticles(feeds.feedIDs()) + return fetchStarredArticles(feedIDs) } // MARK: Updating - func update(_ feed: Feed, _ parsedFeed: ParsedFeed, _ completion: @escaping UpdateArticlesWithFeedCompletionBlock) { + func update(_ feedID: String, _ parsedFeed: ParsedFeed, _ completion: @escaping UpdateArticlesWithFeedCompletionBlock) { if parsedFeed.items.isEmpty { completion(nil, nil) @@ -99,7 +96,6 @@ final class ArticlesTable: DatabaseTable { // 6. Create array of updated Articles and save what’s changed. // 7. Call back with new and updated Articles. - let feedID = feed.feedID let articleIDs = Set(parsedFeed.items.map { $0.articleID }) self.queue.update { (database) in @@ -131,14 +127,13 @@ final class ArticlesTable: DatabaseTable { // MARK: Unread Counts - func fetchUnreadCounts(_ feeds: Set, _ completion: @escaping UnreadCountCompletionBlock) { + func fetchUnreadCounts(_ feedIDs: Set, _ completion: @escaping UnreadCountCompletionBlock) { - if feeds.isEmpty { + if feedIDs.isEmpty { completion(UnreadCountDictionary()) return } - let feedIDs = feeds.feedIDs() var unreadCountDictionary = UnreadCountDictionary() queue.fetch { (database) in @@ -153,16 +148,15 @@ final class ArticlesTable: DatabaseTable { } } - func fetchUnreadCount(_ feeds: Set, _ since: Date, _ callback: @escaping (Int) -> Void) { + func fetchUnreadCount(_ feedIDs: Set, _ since: Date, _ callback: @escaping (Int) -> Void) { // Get unread count for today, for instance. - if feeds.isEmpty { + if feedIDs.isEmpty { callback(0) return } - let feedIDs = feeds.feedIDs() queue.fetch { (database) in let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! @@ -211,14 +205,13 @@ final class ArticlesTable: DatabaseTable { } } - func fetchStarredAndUnreadCount(_ feeds: Set, _ callback: @escaping (Int) -> Void) { + func fetchStarredAndUnreadCount(_ feedIDs: Set, _ callback: @escaping (Int) -> Void) { - if feeds.isEmpty { + if feedIDs.isEmpty { callback(0) return } - let feedIDs = feeds.feedIDs() queue.fetch { (database) in let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))! diff --git a/Frameworks/ArticlesDatabase/Extensions/Feed+Database.swift b/Frameworks/ArticlesDatabase/Extensions/Feed+Database.swift deleted file mode 100644 index f56feecfe..000000000 --- a/Frameworks/ArticlesDatabase/Extensions/Feed+Database.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// Feed+Database.swift -// Database -// -// Created by Brent Simmons on 8/20/17. -// Copyright © 2017 Ranchero Software. All rights reserved. -// - -import Foundation -import Articles - -extension Set where Element == Feed { - - func feedIDs() -> Set { - - return Set(map { $0.feedID }) - } -} diff --git a/Frameworks/ArticlesDatabase/UnreadCountDictionary.swift b/Frameworks/ArticlesDatabase/UnreadCountDictionary.swift index 702f7c32d..02a9e432e 100644 --- a/Frameworks/ArticlesDatabase/UnreadCountDictionary.swift +++ b/Frameworks/ArticlesDatabase/UnreadCountDictionary.swift @@ -17,7 +17,7 @@ public struct UnreadCountDictionary { return dictionary.count < 1 } - subscript(_ feedID: String) -> Int? { + public subscript(_ feedID: String) -> Int? { get { return dictionary[feedID] } @@ -25,8 +25,4 @@ public struct UnreadCountDictionary { dictionary[feedID] = newValue } } - - public subscript(_ feed: Feed) -> Int? { - return dictionary[feed.feedID] - } } From 85aaa68f7b02df783be52e2c35a34bb3c8b17d61 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 28 Jul 2018 17:27:26 -0700 Subject: [PATCH 35/40] Delete unused TimelineHeaderView. --- Evergreen.xcodeproj/project.pbxproj | 4 -- Evergreen/Base.lproj/MainWindow.storyboard | 65 ------------------- .../Timeline/TimelineHeaderView.swift | 30 --------- 3 files changed, 99 deletions(-) delete mode 100644 Evergreen/MainWindow/Timeline/TimelineHeaderView.swift diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index 9634a3b5e..1fb3875b7 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 840D618B2029031D009BC708 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 840D61892029031D009BC708 /* LaunchScreen.storyboard */; }; 840D61962029031D009BC708 /* Evergreen_iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840D61952029031D009BC708 /* Evergreen_iOSTests.swift */; }; 840D61A12029031E009BC708 /* Evergreen_iOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840D61A02029031E009BC708 /* Evergreen_iOSUITests.swift */; }; - 8414AD251FCF5A1E00955102 /* TimelineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8414AD241FCF5A1E00955102 /* TimelineHeaderView.swift */; }; 84162A152038C12C00035290 /* MarkCommandValidationStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84162A142038C12C00035290 /* MarkCommandValidationStatus.swift */; }; 84162A252038C1E000035290 /* TimelineDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84162A242038C1E000035290 /* TimelineDataSource.swift */; }; 841ABA4E20145E7300980E11 /* NothingInspectorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841ABA4D20145E7300980E11 /* NothingInspectorViewController.swift */; }; @@ -493,7 +492,6 @@ 840D619C2029031D009BC708 /* Evergreen-iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Evergreen-iOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 840D61A02029031E009BC708 /* Evergreen_iOSUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Evergreen_iOSUITests.swift; sourceTree = ""; }; 840D61A22029031E009BC708 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8414AD241FCF5A1E00955102 /* TimelineHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineHeaderView.swift; sourceTree = ""; }; 84162A142038C12C00035290 /* MarkCommandValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkCommandValidationStatus.swift; sourceTree = ""; }; 84162A242038C1E000035290 /* TimelineDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineDataSource.swift; sourceTree = ""; }; 841ABA4D20145E7300980E11 /* NothingInspectorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NothingInspectorViewController.swift; sourceTree = ""; }; @@ -964,7 +962,6 @@ 849A976A1ED9EBC8007D329B /* TimelineTableView.swift */, 844B5B6C1FEA282400C7C76A /* Keyboard */, 84E95D231FB1087500552D99 /* ArticlePasteboardWriter.swift */, - 8414AD241FCF5A1E00955102 /* TimelineHeaderView.swift */, 84AAF2BE202CF684004A0BC4 /* TimelineContextualMenuDelegate.swift */, 849A976F1ED9EC04007D329B /* Cell */, ); @@ -1928,7 +1925,6 @@ D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */, 84E850861FCB60CE0072EA88 /* AuthorAvatarDownloader.swift in Sources */, 84E185B3203B74E500F69BFA /* SingleLineTextFieldSizer.swift in Sources */, - 8414AD251FCF5A1E00955102 /* TimelineHeaderView.swift in Sources */, 849EE71F20391DF20082A1EA /* MainWindowToolbarDelegate.swift in Sources */, 849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */, 849A97761ED9EC04007D329B /* TimelineCellAppearance.swift in Sources */, diff --git a/Evergreen/Base.lproj/MainWindow.storyboard b/Evergreen/Base.lproj/MainWindow.storyboard index 095aef4d2..b101c9960 100644 --- a/Evergreen/Base.lproj/MainWindow.storyboard +++ b/Evergreen/Base.lproj/MainWindow.storyboard @@ -468,67 +468,6 @@ - @@ -586,12 +525,9 @@ - - - @@ -744,7 +680,6 @@ - diff --git a/Evergreen/MainWindow/Timeline/TimelineHeaderView.swift b/Evergreen/MainWindow/Timeline/TimelineHeaderView.swift deleted file mode 100644 index 80d0a7539..000000000 --- a/Evergreen/MainWindow/Timeline/TimelineHeaderView.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// TimelineHeaderView.swift -// Evergreen -// -// Created by Brent Simmons on 11/29/17. -// Copyright © 2017 Ranchero Software. All rights reserved. -// - -import AppKit - -final class TimelineHeaderView: NSView { - - private var didConfigureLayer = false - - override var wantsUpdateLayer: Bool { - return true - } - - override func updateLayer() { - - guard !didConfigureLayer else { - return - } - if let layer = layer { - let color = appDelegate.currentTheme.color(forKey: "MainWindow.Timeline.header.backgroundColor") - layer.backgroundColor = color.cgColor - didConfigureLayer = true - } - } -} From b16112ad569d6c668842073beaa9ed84b4661add Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 28 Jul 2018 17:30:12 -0700 Subject: [PATCH 36/40] Remove deleted frameworks from Account. --- .../Account/Account.xcodeproj/project.pbxproj | 86 ------------------- 1 file changed, 86 deletions(-) diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index f4960f843..17b177e6b 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -35,34 +35,6 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 8401A17C1F6DC388002B1BE2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 844BEE371F0AB3AA004AB7CD; - remoteInfo = Database; - }; - 8401A17E1F6DC388002B1BE2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 844BEE401F0AB3AB004AB7CD; - remoteInfo = DatabaseTests; - }; - 841973E41F6DD195006346C4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 841973DF1F6DD194006346C4 /* Data.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 844BEE5B1F0AB3C8004AB7CD; - remoteInfo = Data; - }; - 841973E61F6DD195006346C4 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 841973DF1F6DD194006346C4 /* Data.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 844BEE641F0AB3C9004AB7CD; - remoteInfo = DataTests; - }; 841973EE1F6DD19E006346C4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */; @@ -108,8 +80,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Database.xcodeproj; path = ../Database/Database.xcodeproj; sourceTree = ""; }; - 841973DF1F6DD194006346C4 /* Data.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Data.xcodeproj; path = ../Data/Data.xcodeproj; sourceTree = ""; }; 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSCore.xcodeproj; path = ../RSCore/RSCore.xcodeproj; sourceTree = ""; }; 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RSParser.xcodeproj; path = ../RSParser/RSParser.xcodeproj; sourceTree = ""; }; 841974001F6DD1EC006346C4 /* Folder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = ""; }; @@ -169,24 +139,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8401A1731F6DC387002B1BE2 /* Products */ = { - isa = PBXGroup; - children = ( - 8401A17D1F6DC388002B1BE2 /* Database.framework */, - 8401A17F1F6DC388002B1BE2 /* DatabaseTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 841973E01F6DD194006346C4 /* Products */ = { - isa = PBXGroup; - children = ( - 841973E51F6DD195006346C4 /* Data.framework */, - 841973E71F6DD195006346C4 /* DataTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; 841973E91F6DD19E006346C4 /* Products */ = { isa = PBXGroup; children = ( @@ -233,8 +185,6 @@ 844B2980210CE3BF004020B3 /* RSWeb.framework */, 841D4D712106B40A00DD04E6 /* Articles.framework */, 841D4D6F2106B40400DD04E6 /* ArticlesDatabase.framework */, - 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */, - 841973DF1F6DD194006346C4 /* Data.xcodeproj */, 841973F41F6DD1AC006346C4 /* RSParser.xcodeproj */, 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */, ); @@ -376,14 +326,6 @@ productRefGroup = 848934F71F62484F00CEBD24 /* Products */; projectDirPath = ""; projectReferences = ( - { - ProductGroup = 841973E01F6DD194006346C4 /* Products */; - ProjectRef = 841973DF1F6DD194006346C4 /* Data.xcodeproj */; - }, - { - ProductGroup = 8401A1731F6DC387002B1BE2 /* Products */; - ProjectRef = 8401A1721F6DC387002B1BE2 /* Database.xcodeproj */; - }, { ProductGroup = 841973E91F6DD19E006346C4 /* Products */; ProjectRef = 841973E81F6DD19E006346C4 /* RSCore.xcodeproj */; @@ -402,34 +344,6 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - 8401A17D1F6DC388002B1BE2 /* Database.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = Database.framework; - remoteRef = 8401A17C1F6DC388002B1BE2 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 8401A17F1F6DC388002B1BE2 /* DatabaseTests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = DatabaseTests.xctest; - remoteRef = 8401A17E1F6DC388002B1BE2 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 841973E51F6DD195006346C4 /* Data.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = Data.framework; - remoteRef = 841973E41F6DD195006346C4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 841973E71F6DD195006346C4 /* DataTests.xctest */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = DataTests.xctest; - remoteRef = 841973E61F6DD195006346C4 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; 841973EF1F6DD19E006346C4 /* RSCore.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; From 1feb6cadb89e3f23033202d5c9723bc770108e59 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 28 Jul 2018 17:38:35 -0700 Subject: [PATCH 37/40] Include RSCore update. --- submodules/RSCore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/RSCore b/submodules/RSCore index 43e3f0a07..d4d76ec67 160000 --- a/submodules/RSCore +++ b/submodules/RSCore @@ -1 +1 @@ -Subproject commit 43e3f0a07aed5d3ffa3bec341625e3d743d3f568 +Subproject commit d4d76ec675078457fe1cef1b9dd7ea2ff932942e From d01163b6d45347f155fabfecd106dde970d3087e Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Wed, 8 Aug 2018 22:33:47 -0700 Subject: [PATCH 38/40] Update RSDatabase. --- submodules/RSDatabase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/RSDatabase b/submodules/RSDatabase index 8a346eff6..61a63064a 160000 --- a/submodules/RSDatabase +++ b/submodules/RSDatabase @@ -1 +1 @@ -Subproject commit 8a346eff6ad6a529c39b736ea802182b5edd3f5f +Subproject commit 61a63064a54578c8c72b84f3756b72a651a3bf16 From 6fa34df300e2cb908806828e71a07ff2afbd6adf Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 18 Aug 2018 11:04:28 -0700 Subject: [PATCH 39/40] Add note about what to do with submodules on first checkout. --- Technotes/SubmoduleCheatSheet.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Technotes/SubmoduleCheatSheet.md b/Technotes/SubmoduleCheatSheet.md index 6f1ce732b..e6c62a52d 100644 --- a/Technotes/SubmoduleCheatSheet.md +++ b/Technotes/SubmoduleCheatSheet.md @@ -2,6 +2,12 @@ Evergreen uses [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) to include shared frameworks. At this writing (June 2018) they are DB5, RSCore, RSDatabase, RSWeb, RSTree, and RSParser. +After your first checkout: + + git submodule init + git submodule update + + To add a submodule: git submodule add https://github.com/username/path From 61a390a947bf4f609e42d6a5f5d0f47a9fb36706 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 18 Aug 2018 11:15:24 -0700 Subject: [PATCH 40/40] Unbreak the build. I think. --- Evergreen/MainWindow/Timeline/Cell/UnreadIndicatorView.swift | 2 +- submodules/RSDatabase | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Evergreen/MainWindow/Timeline/Cell/UnreadIndicatorView.swift b/Evergreen/MainWindow/Timeline/Cell/UnreadIndicatorView.swift index c139c8d10..990324b7d 100644 --- a/Evergreen/MainWindow/Timeline/Cell/UnreadIndicatorView.swift +++ b/Evergreen/MainWindow/Timeline/Cell/UnreadIndicatorView.swift @@ -38,7 +38,7 @@ class UnreadIndicatorView: NSView { override func draw(_ dirtyRect: NSRect) { if #available(OSX 10.14, *) { - let color = isEmphasized && isSelected ? NSColor.white : NSColor.controlAccent + let color = isEmphasized && isSelected ? NSColor.white : NSColor.controlAccentColor color.setFill() } else { let color = isEmphasized && isSelected ? NSColor.white : NSColor.systemBlue diff --git a/submodules/RSDatabase b/submodules/RSDatabase index 61a63064a..29c89417a 160000 --- a/submodules/RSDatabase +++ b/submodules/RSDatabase @@ -1 +1 @@ -Subproject commit 61a63064a54578c8c72b84f3756b72a651a3bf16 +Subproject commit 29c89417a7138e125ed0a076ba8d6f83b09aa522