From 9a026afe409c3d9b44ac01a199beb2762a7ec800 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Wed, 22 Sep 2021 20:04:58 +0900 Subject: [PATCH] goodbye ObjectiveC --- CoreStore.xcodeproj/project.pbxproj | 36 - .../contents.xcworkspacedata | 3 - CoreStoreTests/BridgingTests.h | 30 - CoreStoreTests/BridgingTests.m | 261 ---- .../CoreStoreTests-Bridging-Header.h | 5 - CoreStoreTests/ErrorTests.swift | 39 +- CoreStoreTests/IntoTests.swift | 11 - {LegacyDemo => Demo}/appIcons.sketch | Bin .../LegacyDemo.xcodeproj/project.pbxproj | 597 --------- .../contents.xcworkspacedata | 7 - LegacyDemo/LegacyDemo/AppDelegate.swift | 26 - .../LegacyDemo/Base.lproj/LaunchScreen.xib | 52 - .../LegacyDemo/Base.lproj/Main.storyboard | 1182 ----------------- ...etchingAndQueryingDemoViewController.swift | 319 ----- .../FetchingResultsViewController.swift | 68 - .../QueryingResultsViewController.swift | 88 -- .../Fetching and Querying Demo/TimeZone.swift | 20 - .../AppIcon.appiconset/Contents.json | 114 -- .../AppIcon.appiconset/Icon-60@2x.png | Bin 7321 -> 0 bytes .../AppIcon.appiconset/Icon-60@3x-1.png | Bin 11648 -> 0 bytes .../AppIcon.appiconset/Icon-60@3x.png | Bin 11648 -> 0 bytes .../AppIcon.appiconset/Icon-76.png | Bin 4223 -> 0 bytes .../AppIcon.appiconset/Icon-76@2x.png | Bin 9568 -> 0 bytes .../Mask + Oval 1 + Oval 1 + Oval 1.png | Bin 120873 -> 0 bytes .../LegacyDemo/Images.xcassets/Contents.json | 6 - .../CoreStoreIcon.imageset/Contents.json | 21 - .../CoreStoreIcon@2x.png | Bin 28665 -> 0 bytes .../first.imageset/Contents.json | 12 - .../Images.xcassets/first.imageset/first.pdf | Bin 2465 -> 0 bytes .../second.imageset/Contents.json | 12 - .../second.imageset/second.pdf | Bin 2423 -> 0 bytes LegacyDemo/LegacyDemo/Info.plist | 56 - .../LegacyDemo.xcdatamodel/contents | 26 - .../CollectionViewDemoViewController.swift | 168 --- .../ColorsDemo.swift | 88 -- .../ListObserverDemoViewController.swift | 181 --- .../ObjectObserverDemoViewController.swift | 192 --- .../ObserversViewController.swift | 59 - .../Palette.swift | 86 -- .../PaletteCollectionSectionHeaderView.swift | 17 - .../PaletteCollectionViewCell.swift | 18 - .../PaletteTableViewCell.swift | 18 - .../CustomLoggerViewController.swift | 126 -- .../MigrationsDemoViewController.swift | 445 ------- .../MyAppModel.xcdatamodeld/.xccurrentversion | 5 - .../MyAppModel.xcdatamodel/contents | 4 - .../MIgrations Demo/OrganismProtocol.swift | 16 - .../OrganismTableViewCell.swift | 22 - .../MIgrations Demo/OrganismV1.swift | 25 - .../MIgrations Demo/OrganismV2.swift | 27 - .../xcmapping.xml | 99 -- .../OrganismV2ToV3MigrationPolicy.swift | 29 - .../MIgrations Demo/OrganismV3.swift | 29 - .../xcmapping.xml | 87 -- .../.xccurrentversion | 8 - .../MigrationDemo.xcdatamodel/contents | 11 - .../MigrationDemoV2.xcdatamodel/contents | 12 - .../MigrationDemoV3.xcdatamodel/contents | 13 - .../Stack Setup Demo/FemaleAccount.swift | 15 - .../Stack Setup Demo/MaleAccount.swift | 15 - .../StackSetupDemoViewController.swift | 196 --- .../Stack Setup Demo/UserAccount.swift | 20 - .../StackSetupDemo.xcdatamodel/contents | 23 - .../SwiftUIContainerViewController.swift | 53 - .../LegacyDemo/SwiftUI Demo/SwiftUIView.swift | 183 --- .../LegacyDemo/Transactions Demo/Place.swift | 50 - .../TransactionsDemoViewController.swift | 233 ---- Sources/CSAsynchronousDataTransaction.swift | 119 +- Sources/CSBaseDataTransaction+Querying.swift | 163 +-- Sources/CSBaseDataTransaction.swift | 267 ++-- Sources/CSClauseTypes.swift | 18 +- Sources/CSCoreStore.swift | 27 +- Sources/CSDataStack+Migrating.swift | 93 +- Sources/CSDataStack+Observing.swift | 138 +- Sources/CSDataStack+Querying.swift | 182 +-- Sources/CSDataStack+Transaction.swift | 104 +- Sources/CSDataStack.swift | 163 +-- Sources/CSDynamicSchema.swift | 14 +- Sources/CSError.swift | 250 +--- Sources/CSFrom.swift | 127 +- Sources/CSGroupBy.swift | 73 +- Sources/CSInMemoryStore.swift | 75 +- Sources/CSInto.swift | 94 +- Sources/CSListMonitor.swift | 508 ++----- Sources/CSListObserver.swift | 118 +- Sources/CSMigrationResult.swift | 129 +- Sources/CSMigrationType.swift | 79 +- Sources/CSObjectMonitor.swift | 106 +- Sources/CSObjectObserver.swift | 33 +- Sources/CSOrderBy.swift | 81 +- Sources/CSSQliteStore.swift | 150 +-- Sources/CSSectionBy.swift | 61 +- Sources/CSSelect.swift | 432 +----- Sources/CSSetupResult.swift | 137 +- Sources/CSStorageInterface.swift | 68 +- Sources/CSSynchronousDataTransaction.swift | 110 +- Sources/CSTweak.swift | 45 +- Sources/CSUnsafeDataModelSchema.swift | 55 +- Sources/CSUnsafeDataTransaction.swift | 171 +-- Sources/CSWhere.swift | 118 +- Sources/CSXcodeDataModelSchema.swift | 55 +- Sources/CoreStoreBridge.h | 421 +----- Sources/CoreStoreBridge.m | 154 ++- Sources/CoreStoreBridge.swift | 146 +- Sources/CoreStoreError.swift | 19 +- Sources/CustomSchemaMappingProvider.swift | 12 +- Sources/DataStack.AddStoragePublisher.swift | 2 +- Sources/NSManagedObject+ObjectiveC.swift | 41 +- .../NSManagedObjectContext+ObjectiveC.swift | 142 -- Sources/Progress+ObjectiveC.swift | 12 +- 110 files changed, 1060 insertions(+), 9816 deletions(-) delete mode 100644 CoreStoreTests/BridgingTests.h delete mode 100644 CoreStoreTests/BridgingTests.m delete mode 100644 CoreStoreTests/CoreStoreTests-Bridging-Header.h rename {LegacyDemo => Demo}/appIcons.sketch (100%) delete mode 100644 LegacyDemo/LegacyDemo.xcodeproj/project.pbxproj delete mode 100644 LegacyDemo/LegacyDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 LegacyDemo/LegacyDemo/AppDelegate.swift delete mode 100644 LegacyDemo/LegacyDemo/Base.lproj/LaunchScreen.xib delete mode 100644 LegacyDemo/LegacyDemo/Base.lproj/Main.storyboard delete mode 100644 LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingAndQueryingDemoViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingResultsViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/Fetching and Querying Demo/QueryingResultsViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/Fetching and Querying Demo/TimeZone.swift delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x-1.png delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-76.png delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Mask + Oval 1 + Oval 1 + Oval 1.png delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/Contents.json delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/CoreStoreIcon.imageset/Contents.json delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/CoreStoreIcon.imageset/CoreStoreIcon@2x.png delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/first.imageset/Contents.json delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/first.imageset/first.pdf delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/second.imageset/Contents.json delete mode 100644 LegacyDemo/LegacyDemo/Images.xcassets/second.imageset/second.pdf delete mode 100644 LegacyDemo/LegacyDemo/Info.plist delete mode 100644 LegacyDemo/LegacyDemo/LegacyDemo.xcdatamodeld/LegacyDemo.xcdatamodel/contents delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/CollectionViewDemoViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/ColorsDemo.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/ListObserverDemoViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/ObjectObserverDemoViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/ObserversViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/Palette.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionSectionHeaderView.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionViewCell.swift delete mode 100644 LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteTableViewCell.swift delete mode 100644 LegacyDemo/LegacyDemo/Loggers Demo/CustomLoggerViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/MigrationsDemoViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/.xccurrentversion delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/MyAppModel.xcdatamodel/contents delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismProtocol.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismTableViewCell.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV1.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3.xcmappingmodel/xcmapping.xml delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3MigrationPolicy.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3.swift delete mode 100644 LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3ToV2.xcmappingmodel/xcmapping.xml delete mode 100644 LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/.xccurrentversion delete mode 100644 LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemo.xcdatamodel/contents delete mode 100644 LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV2.xcdatamodel/contents delete mode 100644 LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV3.xcdatamodel/contents delete mode 100644 LegacyDemo/LegacyDemo/Stack Setup Demo/FemaleAccount.swift delete mode 100644 LegacyDemo/LegacyDemo/Stack Setup Demo/MaleAccount.swift delete mode 100644 LegacyDemo/LegacyDemo/Stack Setup Demo/StackSetupDemoViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/Stack Setup Demo/UserAccount.swift delete mode 100644 LegacyDemo/LegacyDemo/StackSetupDemo.xcdatamodeld/StackSetupDemo.xcdatamodel/contents delete mode 100644 LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIContainerViewController.swift delete mode 100644 LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIView.swift delete mode 100644 LegacyDemo/LegacyDemo/Transactions Demo/Place.swift delete mode 100644 LegacyDemo/LegacyDemo/Transactions Demo/TransactionsDemoViewController.swift delete mode 100644 Sources/NSManagedObjectContext+ObjectiveC.swift diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 35e1255..5d32d01 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -819,9 +819,6 @@ B5DBE2D31C991B3E00B5CEFA /* CSDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */; }; B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */; }; B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */; }; - B5DBE2DF1C9939E100B5CEFA /* BridgingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */; }; - B5DBE2E01C9939E100B5CEFA /* BridgingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */; }; - B5DBE2E11C9939E100B5CEFA /* BridgingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */; }; B5DC47C61C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */; }; B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */; }; B5DC47C81C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */; }; @@ -908,10 +905,6 @@ B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */; }; B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */; }; B5ECDBF01CA6BF2000C7F112 /* CSFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */; }; - B5ECDBF91CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBF81CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift */; }; - B5ECDBFB1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBF81CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift */; }; - B5ECDBFC1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBF81CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift */; }; - B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBF81CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift */; }; B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBFE1CA80CBA00C7F112 /* CSWhere.swift */; }; B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBFE1CA80CBA00C7F112 /* CSWhere.swift */; }; B5ECDC021CA80CBA00C7F112 /* CSWhere.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBFE1CA80CBA00C7F112 /* CSWhere.swift */; }; @@ -1200,9 +1193,6 @@ B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPathGenericBindings.swift; sourceTree = ""; }; B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSCoreStore.swift; sourceTree = ""; }; B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDataStack.swift; sourceTree = ""; }; - B5DBE2DA1C9939E100B5CEFA /* CoreStoreTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreStoreTests-Bridging-Header.h"; sourceTree = ""; }; - B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BridgingTests.h; sourceTree = ""; }; - B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BridgingTests.m; sourceTree = ""; }; B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationChainTests.swift; sourceTree = ""; }; B5DC47C91C93D9C800FA3BF3 /* StorageInterfaceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageInterfaceTests.swift; sourceTree = ""; }; B5DE522A230BD7CC00A22534 /* Internals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Internals.swift; sourceTree = ""; }; @@ -1251,7 +1241,6 @@ B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSBaseDataTransaction+Querying.swift"; sourceTree = ""; }; B5ECDBE41CA6BEA300C7F112 /* CSClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSClauseTypes.swift; sourceTree = ""; }; B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSFrom.swift; sourceTree = ""; }; - B5ECDBF81CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+ObjectiveC.swift"; sourceTree = ""; }; B5ECDBFE1CA80CBA00C7F112 /* CSWhere.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSWhere.swift; sourceTree = ""; }; B5ECDC041CA8138100C7F112 /* CSOrderBy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSOrderBy.swift; sourceTree = ""; }; B5ECDC0A1CA8161B00C7F112 /* CSGroupBy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSGroupBy.swift; sourceTree = ""; }; @@ -1396,8 +1385,6 @@ isa = PBXGroup; children = ( B5AA37FE235DEBD700FFD4B9 /* BaseTests */, - B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */, - B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */, B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */, B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */, B52557871D02DE8100E51965 /* FetchTests.swift */, @@ -1432,7 +1419,6 @@ children = ( B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */, 2F03A53E19C5C6DA005002A5 /* Info.plist */, - B5DBE2DA1C9939E100B5CEFA /* CoreStoreTests-Bridging-Header.h */, ); name = "Supporting Files"; sourceTree = ""; @@ -1795,7 +1781,6 @@ B501FDDB1CA8D03600BE22EF /* Observing */, B5E1B5A61CAA49CE007FD580 /* Migrating */, B53FBA101CAB607000F0D40A /* Convenience */, - B5E222211CA4DE5700BA2E95 /* Internal */, ); name = ObjectiveC; sourceTree = ""; @@ -1811,14 +1796,6 @@ name = Migrating; sourceTree = ""; }; - B5E222211CA4DE5700BA2E95 /* Internal */ = { - isa = PBXGroup; - children = ( - B5ECDBF81CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift */, - ); - name = Internal; - sourceTree = ""; - }; B5E2222F1CA5339200BA2E95 /* Fetching and Querying */ = { isa = PBXGroup; children = ( @@ -2329,7 +2306,6 @@ B56E4ED423CDB54A00E1708C /* FieldProtocol.swift in Sources */, B509D7C423C848DA00F42824 /* Relationship.ToOne.swift in Sources */, B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */, - B5ECDBF91CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */, B5CA2B081F7E5ACA004B1936 /* WhereClauseType.swift in Sources */, B50E17612351FA66004F033C /* Internals.Closure.swift in Sources */, B50C3EEA23D1601400B29880 /* FieldCoders.swift in Sources */, @@ -2565,7 +2541,6 @@ B580857A1CDF808C004C2EEB /* SetupTests.swift in Sources */, B59A51832256C85E00CEF3C5 /* VersionLockTests.swift in Sources */, B5489F4C1CF5F743008B4978 /* BaseTestCase.swift in Sources */, - B5DBE2DF1C9939E100B5CEFA /* BridgingTests.m in Sources */, B57D27BE1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */, B5489F3F1CF5EEBC008B4978 /* TestEntity1.swift in Sources */, B57D27C21D0BC20100539C58 /* QueryTests.swift in Sources */, @@ -2578,7 +2553,6 @@ buildActionMask = 2147483647; files = ( 82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */, - B5ECDBFB1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */, B5635D152356C39500B80E6B /* DiffableDataSource.CollectionViewAdapter-UIKit.swift in Sources */, B5CA2B091F7E5ACA004B1936 /* WhereClauseType.swift in Sources */, B5C976E81C6E3A5D00B1AF90 /* Internals.CoreStoreFetchedResultsController.swift in Sources */, @@ -2802,7 +2776,6 @@ B5D8CA7D2346EC610055D7D1 /* ListPublisherTests.swift in Sources */, B52557751D02791400E51965 /* WhereTests.swift in Sources */, B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, - B5DBE2E01C9939E100B5CEFA /* BridgingTests.m in Sources */, B5220E0D1D0D0D19009BC71E /* ImportTests.swift in Sources */, B5D339B51E925C2B00C880DE /* DynamicModelTests.swift in Sources */, B525576D1CFAF18F00E51965 /* IntoTests.swift in Sources */, @@ -2896,7 +2869,6 @@ B5519A4D1CA1F4FB002BEF78 /* CSError.swift in Sources */, B5E1B5AC1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */, B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */, - B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */, B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */, B5831F4222126FED00D8604C /* KeyPathGenericBindings.swift in Sources */, B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */, @@ -3054,7 +3026,6 @@ B52557761D02791400E51965 /* WhereTests.swift in Sources */, B5D8CA7E2346EC610055D7D1 /* ListPublisherTests.swift in Sources */, B5DC47C81C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, - B5DBE2E11C9939E100B5CEFA /* BridgingTests.m in Sources */, B5220E0E1D0D0D19009BC71E /* ImportTests.swift in Sources */, B525576E1CFAF18F00E51965 /* IntoTests.swift in Sources */, B5D339B61E925C2B00C880DE /* DynamicModelTests.swift in Sources */, @@ -3084,7 +3055,6 @@ buildActionMask = 2147483647; files = ( B56321A91BD65219006C9394 /* Progress+Convenience.swift in Sources */, - B5ECDBFC1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */, B5635D162356C39500B80E6B /* DiffableDataSource.CollectionViewAdapter-UIKit.swift in Sources */, B5CA2B0A1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */, B5C976E91C6E3A5E00B1AF90 /* Internals.CoreStoreFetchedResultsController.swift in Sources */, @@ -3514,7 +3484,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = iphoneos; - SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; }; @@ -3530,7 +3499,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = iphoneos; - SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; }; name = Release; @@ -3600,7 +3568,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = appletvos; - SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; TARGETED_DEVICE_FAMILY = 3; @@ -3619,7 +3586,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = CoreStoreTests; SDKROOT = appletvos; - SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; TARGETED_DEVICE_FAMILY = 3; }; @@ -3696,7 +3662,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore; PRODUCT_NAME = CoreStoreTests; SDKROOT = macosx; - SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; }; @@ -3717,7 +3682,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore; PRODUCT_NAME = CoreStoreTests; SDKROOT = macosx; - SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h"; SWIFT_SWIFT3_OBJC_INFERENCE = Off; }; name = Release; diff --git a/CoreStore.xcworkspace/contents.xcworkspacedata b/CoreStore.xcworkspace/contents.xcworkspacedata index 23b89e6..baf3edb 100644 --- a/CoreStore.xcworkspace/contents.xcworkspacedata +++ b/CoreStore.xcworkspace/contents.xcworkspacedata @@ -7,7 +7,4 @@ - - diff --git a/CoreStoreTests/BridgingTests.h b/CoreStoreTests/BridgingTests.h deleted file mode 100644 index e2661da..0000000 --- a/CoreStoreTests/BridgingTests.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// BridgingTests.h -// CoreStore -// -// Copyright © 2018 John Rommel Estropia -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -#import - -@interface BridgingTests : XCTestCase - -@end diff --git a/CoreStoreTests/BridgingTests.m b/CoreStoreTests/BridgingTests.m deleted file mode 100644 index 31040ea..0000000 --- a/CoreStoreTests/BridgingTests.m +++ /dev/null @@ -1,261 +0,0 @@ -// -// BridgingTests.m -// CoreStore -// -// Copyright © 2018 John Rommel Estropia -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -#import "BridgingTests.h" -#import -#import -#import "CoreStoreTests-Swift.h" - -@import CoreData; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - - -// MARK: - BridgingTests - -@implementation BridgingTests - -- (void)test_ThatFlags_HaveCorrectValues { - - XCTAssertEqual(CSLocalStorageOptionsNone, 0); - XCTAssertEqual(CSLocalStorageOptionsRecreateStoreOnModelMismatch, 1); - XCTAssertEqual(CSLocalStorageOptionsPreventProgressiveMigration, 2); - XCTAssertEqual(CSLocalStorageOptionsAllowSynchronousLightweightMigration, 4); -} - -- (void)test_ThatKeyPaths_AreCorrect { - - XCTAssertEqualObjects(CSKeyPath(TestEntity1, testNumber), @"testNumber"); - XCTAssertEqualObjects(CSKeyPath(TestEntity1, testString), @"testString"); - XCTAssertEqualObjects(CSKeyPathOperator(count, TestEntity1, testString), @"@count.testString"); - XCTAssertEqualObjects(CSKeyPathOperator(max, TestEntity1, testNumber), @"@max.testNumber"); -} - -- (void)test_ThatFromClauses_BridgeCorrectly { - - { - CSFrom *from = CSFromClass([TestEntity1 class]); - XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]); - XCTAssertNil(from.configurations); - } - { - CSFrom *from = CSFromClass([TestEntity1 class], [NSNull null]); - XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]); - - NSArray *configurations = @[[NSNull null]]; - XCTAssertEqualObjects(from.configurations, configurations); - } - { - CSFrom *from = CSFromClass([TestEntity1 class], @"Config1"); - XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]); - - NSArray *configurations = @[@"Config1"]; - XCTAssertEqualObjects(from.configurations, configurations); - } - { - CSFrom *from = CSFromClass([TestEntity1 class], @[[NSNull null], @"Config2"]); - XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]); - - NSArray *configurations = @[[NSNull null], @"Config2"]; - XCTAssertEqualObjects(from.configurations, configurations); - } -} - -- (void)test_ThatWhereClauses_BridgeCorrectly { - - { - CSWhere *where = CSWhereFormat(@"%K == %@", @"key", @"value"); - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]; - XCTAssertEqualObjects(where.predicate, predicate); - } - { - CSWhere *where = CSWhereValue(YES); - NSPredicate *predicate = [NSPredicate predicateWithValue:YES]; - XCTAssertEqualObjects(where.predicate, predicate); - } - { - CSWhere *where = CSWherePredicate([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]); - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]; - XCTAssertEqualObjects(where.predicate, predicate); - } -} - -- (void)test_ThatOrderByClauses_BridgeCorrectly { - - { - CSOrderBy *orderBy = CSOrderByKey(CSSortAscending(@"key")); - XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:YES]]); - } - { - CSOrderBy *orderBy = CSOrderByKey(CSSortDescending(@"key")); - XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:NO]]); - } - { - CSOrderBy *orderBy = CSOrderByKeys(CSSortAscending(@"key1"), CSSortDescending(@"key2"), nil); - NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"key1" ascending:YES], - [NSSortDescriptor sortDescriptorWithKey:@"key2" ascending:NO]]; - XCTAssertEqualObjects(orderBy.sortDescriptors, sortDescriptors); - } -} - -- (void)test_ThatGroupByClauses_BridgeCorrectly { - - { - CSGroupBy *groupBy = CSGroupByKeyPath(@"key"); - XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]); - } - { - CSGroupBy *groupBy = CSGroupByKeyPaths(@[@"key1", @"key2"]); - - NSArray *keyPaths = @[@"key1", @"key2"]; - XCTAssertEqualObjects(groupBy.keyPaths, keyPaths); - } -} - -- (void)test_ThatTweakClauses_BridgeCorrectly { - - CSTweak *tweak = CSTweakRequest(^(NSFetchRequest * _Nonnull fetchRequest) { - - fetchRequest.fetchLimit = 100; - }); - NSFetchRequest *request = [NSFetchRequest new]; - tweak.block(request); - XCTAssertEqual(request.fetchLimit, 100); -} - -- (void)test_ThatIntoClauses_BridgeCorrectly { - - { - CSInto *into = CSIntoClass([TestEntity1 class]); - XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]); - } - { - CSInto *into = CSIntoClass([TestEntity1 class], [NSNull null]); - XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]); - XCTAssertNil(into.configuration); - } - { - CSInto *into = CSIntoClass([TestEntity1 class], @"Config1"); - XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]); - XCTAssertEqualObjects(into.configuration, @"Config1"); - } -} - -- (void)test_ThatDataStacks_BridgeCorrectly { - - CSDataStack *dataStack = [[CSDataStack alloc] - initWithXcodeModelName:@"Model" - bundle:[NSBundle bundleForClass:[self class]] - versionChain:nil]; - XCTAssertNotNil(dataStack); - - NSError *memoryError; - CSInMemoryStore *memoryStorage = [dataStack - addInMemoryStorageAndWait:[CSInMemoryStore new] - error:&memoryError]; - XCTAssertNotNil(memoryStorage); - XCTAssertEqualObjects([[memoryStorage class] storeType], [CSInMemoryStore storeType]); - XCTAssertEqualObjects([[memoryStorage class] storeType], NSInMemoryStoreType); - XCTAssertNil(memoryStorage.configuration); - XCTAssertNil(memoryStorage.storeOptions); - XCTAssertNil(memoryError); - - NSError *sqliteError; - CSSQLiteStore *sqliteStorage = [dataStack - addSQLiteStorageAndWait:[CSSQLiteStore new] - error:&sqliteError]; - XCTAssertNotNil(sqliteStorage); - XCTAssertEqualObjects([[sqliteStorage class] storeType], [CSSQLiteStore storeType]); - XCTAssertEqualObjects([[sqliteStorage class] storeType], NSSQLiteStoreType); - XCTAssertNil(sqliteStorage.configuration); - NSDictionary *storeOptions = @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" }, - NSBinaryStoreInsecureDecodingCompatibilityOption: @YES }; - XCTAssertEqualObjects(sqliteStorage.storeOptions, storeOptions); - XCTAssertNil(sqliteError); -} - -- (void)test_ThatTransactions_BridgeCorrectly { - - CSDataStack *dataStack = [[CSDataStack alloc] - initWithXcodeModelName:@"Model" - bundle:[NSBundle bundleForClass:[self class]] - versionChain:nil]; - XCTAssertNotNil(dataStack); - - [dataStack - addInMemoryStorageAndWait:[CSInMemoryStore new] - error:nil]; - - { - CSUnsafeDataTransaction *transaction = [dataStack beginUnsafe]; - XCTAssertNotNil(transaction); - XCTAssert([transaction isKindOfClass:[CSUnsafeDataTransaction class]]); - NSError *error; - BOOL result = [transaction commitAndWaitWithError:&error]; - XCTAssertTrue(result); - XCTAssertNil(error); - } - { - XCTestExpectation *expectation = [self expectationWithDescription:@"sync"]; - NSError *error; - BOOL result = - [dataStack - beginSynchronous:^(CSSynchronousDataTransaction * _Nonnull transaction) { - - XCTAssertNotNil(transaction); - XCTAssert([transaction isKindOfClass:[CSSynchronousDataTransaction class]]); - NSError *error; - XCTAssertTrue([transaction commitAndWaitWithError:&error]); - XCTAssertNil(error); - [expectation fulfill]; - } - error:&error]; - XCTAssertTrue(result); - XCTAssertNil(error); - } - { - XCTestExpectation *expectation = [self expectationWithDescription:@"async"]; - [dataStack beginAsynchronous:^(CSAsynchronousDataTransaction * _Nonnull transaction) { - - XCTAssertNotNil(transaction); - XCTAssert([transaction isKindOfClass:[CSAsynchronousDataTransaction class]]); - [transaction - commitWithSuccess:^{ - - [expectation fulfill]; - } - failure:^(CSError *error){ - - XCTFail(); - }]; - }]; - } - [self waitForExpectationsWithTimeout:10 handler:nil]; -} - -@end - -#pragma clang diagnostic pop diff --git a/CoreStoreTests/CoreStoreTests-Bridging-Header.h b/CoreStoreTests/CoreStoreTests-Bridging-Header.h deleted file mode 100644 index d5b75f7..0000000 --- a/CoreStoreTests/CoreStoreTests-Bridging-Header.h +++ /dev/null @@ -1,5 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - -#import "BridgingTests.h" \ No newline at end of file diff --git a/CoreStoreTests/ErrorTests.swift b/CoreStoreTests/ErrorTests.swift index 35f8527..efdb155 100644 --- a/CoreStoreTests/ErrorTests.swift +++ b/CoreStoreTests/ErrorTests.swift @@ -31,7 +31,6 @@ import CoreStore // MARK: - ErrorTests -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") final class ErrorTests: XCTestCase { @objc @@ -43,14 +42,12 @@ final class ErrorTests: XCTestCase { let userInfo: NSDictionary = [:] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) + let objcError = error as NSError XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.code, CoreStoreErrorCode.unknownError.rawValue) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) + let objcError2 = CoreStoreError(objcError) as NSError XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.unknownError.rawValue) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) @@ -68,14 +65,12 @@ final class ErrorTests: XCTestCase { let userInfo: NSDictionary = [ "existingPersistentStoreURL": dummyURL ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) + let objcError = error as NSError XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) + + let objcError2 = CoreStoreError(objcError) as NSError XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.differentStorageExistsAtURL.rawValue) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) @@ -103,14 +98,12 @@ final class ErrorTests: XCTestCase { "targetModel": schemaHistory.rawModel, "targetModelVersion": version ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) + let objcError = error as NSError XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.code, CoreStoreErrorCode.mappingModelNotFound.rawValue) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) + + let objcError2 = CoreStoreError(objcError) as NSError XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.mappingModelNotFound.rawValue) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) @@ -128,14 +121,12 @@ final class ErrorTests: XCTestCase { let userInfo: NSDictionary = [ "localStoreURL": dummyURL ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) + let objcError = error as NSError XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) + + let objcError2 = CoreStoreError(objcError) as NSError XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.progressiveMigrationRequired.rawValue) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) @@ -160,14 +151,12 @@ final class ErrorTests: XCTestCase { let userInfo: NSDictionary = [ "NSError": internalError ] - let objcError = error.bridgeToObjectiveC - XCTAssertEqual(error, objcError.bridgeToSwift) + let objcError = error as NSError XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError.code, CoreStoreErrorCode.internalError.rawValue) XCTAssertEqual(objcError.userInfo as NSDictionary, userInfo) - - let objcError2 = objcError.bridgeToSwift.bridgeToObjectiveC - XCTAssertEqual(error, objcError2.bridgeToSwift) + + let objcError2 = CoreStoreError(objcError) as NSError XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) XCTAssertEqual(objcError2.code, CoreStoreErrorCode.internalError.rawValue) XCTAssertEqual(objcError2.userInfo as NSDictionary, userInfo) diff --git a/CoreStoreTests/IntoTests.swift b/CoreStoreTests/IntoTests.swift index 73659fa..9ff8754 100644 --- a/CoreStoreTests/IntoTests.swift +++ b/CoreStoreTests/IntoTests.swift @@ -126,15 +126,4 @@ final class IntoTests: XCTestCase { XCTAssertNotEqual(into, Into("Config2")) } } - - @objc - dynamic func test_ThatIntoClauses_BridgeCorrectly() { - - do { - - let into = Into() - let objcInto = into.bridgeToObjectiveC - XCTAssertEqual(into, objcInto.bridgeToSwift) - } - } } diff --git a/LegacyDemo/appIcons.sketch b/Demo/appIcons.sketch similarity index 100% rename from LegacyDemo/appIcons.sketch rename to Demo/appIcons.sketch diff --git a/LegacyDemo/LegacyDemo.xcodeproj/project.pbxproj b/LegacyDemo/LegacyDemo.xcodeproj/project.pbxproj deleted file mode 100644 index 7f14ca8..0000000 --- a/LegacyDemo/LegacyDemo.xcodeproj/project.pbxproj +++ /dev/null @@ -1,597 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - B50132242344E24300FC238B /* SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50132232344E24300FC238B /* SwiftUIView.swift */; }; - B50132282344E5E900FC238B /* SwiftUIContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50132272344E5E900FC238B /* SwiftUIContainerViewController.swift */; }; - B501323523477D2300FC238B /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B501323423477D2300FC238B /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */; }; - B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */; }; - B503FAE11AFDC71700F90881 /* Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADD1AFDC71700F90881 /* Palette.swift */; }; - B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */; }; - B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */; }; - B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977D81B120B80003D50A5 /* ObserversViewController.swift */; }; - B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */; }; - B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977DE1B120F83003D50A5 /* MapKit.framework */; }; - B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977E01B120F8A003D50A5 /* CoreLocation.framework */; }; - B52977E41B121635003D50A5 /* Place.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977E31B121635003D50A5 /* Place.swift */; }; - B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */; }; - B54AAD521AF4D26E00848AE0 /* LegacyDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B54AAD501AF4D26E00848AE0 /* LegacyDemo.xcdatamodeld */; }; - B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD571AF4D26E00848AE0 /* Main.storyboard */; }; - B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */; }; - B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */; }; - B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */; }; - B5635D192357F9F700B80E6B /* CollectionViewDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5635D182357F9F700B80E6B /* CollectionViewDemoViewController.swift */; }; - B5635D1B2357FA4B00B80E6B /* PaletteCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5635D1A2357FA4B00B80E6B /* PaletteCollectionViewCell.swift */; }; - B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */; }; - B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566E3311B11DF3200F4F0C6 /* UserAccount.swift */; }; - B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */; }; - B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */; }; - B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D91B231BCA0075EE4A /* MaleAccount.swift */; }; - B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */; }; - B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */; }; - B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965171B2E20CC0075EE4A /* TimeZone.swift */; }; - B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */; }; - B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */; }; - B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */; }; - B5AA37EF2357D30300FFD4B9 /* ColorsDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AA37EE2357D30300FFD4B9 /* ColorsDemo.swift */; }; - B5C37EE52357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C37EE42357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift */; }; - B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */; }; - B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; }; - B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25841B36E23C0000406B /* OrganismV1.swift */; }; - B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25861B36E2520000406B /* OrganismV2.swift */; }; - B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */; }; - B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259A1B3EA4890000406B /* OrganismV3.swift */; }; - B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - B5E89ACF1C52929C003B04A9 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - B50132232344E24300FC238B /* SwiftUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIView.swift; sourceTree = ""; }; - B50132272344E5E900FC238B /* SwiftUIContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIContainerViewController.swift; sourceTree = ""; }; - B501323423477D2300FC238B /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; - B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListObserverDemoViewController.swift; sourceTree = ""; }; - B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverDemoViewController.swift; sourceTree = ""; }; - B503FADD1AFDC71700F90881 /* Palette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Palette.swift; sourceTree = ""; }; - B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaletteTableViewCell.swift; sourceTree = ""; }; - B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV2ToV3.xcmappingmodel; sourceTree = ""; }; - B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = OrganismV3ToV2.xcmappingmodel; sourceTree = ""; }; - B52977D81B120B80003D50A5 /* ObserversViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserversViewController.swift; sourceTree = ""; }; - B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsDemoViewController.swift; sourceTree = ""; }; - B52977DE1B120F83003D50A5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; - B52977E01B120F8A003D50A5 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; - B52977E31B121635003D50A5 /* Place.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Place.swift; sourceTree = ""; }; - B54AAD491AF4D26E00848AE0 /* LegacyDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LegacyDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; - B54AAD4D1AF4D26E00848AE0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - B54AAD511AF4D26E00848AE0 /* LegacyDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = LegacyDemo.xcdatamodel; sourceTree = ""; }; - B54AAD581AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - B54AAD5D1AF4D26E00848AE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; - B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2ToV3MigrationPolicy.swift; sourceTree = ""; }; - B5635D182357F9F700B80E6B /* CollectionViewDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewDemoViewController.swift; sourceTree = ""; }; - B5635D1A2357FA4B00B80E6B /* PaletteCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaletteCollectionViewCell.swift; sourceTree = ""; }; - B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StackSetupDemoViewController.swift; sourceTree = ""; }; - B566E3311B11DF3200F4F0C6 /* UserAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserAccount.swift; sourceTree = ""; }; - B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomLoggerViewController.swift; sourceTree = ""; }; - B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = StackSetupDemo.xcdatamodel; sourceTree = ""; }; - B56964D91B231BCA0075EE4A /* MaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaleAccount.swift; sourceTree = ""; }; - B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FemaleAccount.swift; sourceTree = ""; }; - B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingAndQueryingDemoViewController.swift; sourceTree = ""; }; - B56965171B2E20CC0075EE4A /* TimeZone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeZone.swift; sourceTree = ""; }; - B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingResultsViewController.swift; sourceTree = ""; }; - B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryingResultsViewController.swift; sourceTree = ""; }; - B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemo.xcdatamodel; sourceTree = ""; }; - B5AA37EE2357D30300FFD4B9 /* ColorsDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorsDemo.swift; sourceTree = ""; }; - B5BDC9211C202429008147CD /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B5C37EE42357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaletteCollectionSectionHeaderView.swift; sourceTree = ""; }; - B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OrganismTableViewCell.swift; path = "LegacyDemo/MIgrations Demo/OrganismTableViewCell.swift"; sourceTree = SOURCE_ROOT; }; - B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV2.xcdatamodel; sourceTree = ""; }; - B5EE25841B36E23C0000406B /* OrganismV1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV1.swift; sourceTree = ""; }; - B5EE25861B36E2520000406B /* OrganismV2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV2.swift; sourceTree = ""; }; - B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemoV3.xcdatamodel; sourceTree = ""; }; - B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationsDemoViewController.swift; sourceTree = ""; }; - B5EE259A1B3EA4890000406B /* OrganismV3.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismV3.swift; sourceTree = ""; }; - B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrganismProtocol.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - B54AAD461AF4D26E00848AE0 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B501323523477D2300FC238B /* SwiftUI.framework in Frameworks */, - B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */, - B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */, - B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - B50132222344E20B00FC238B /* SwiftUI Demo */ = { - isa = PBXGroup; - children = ( - B50132232344E24300FC238B /* SwiftUIView.swift */, - B50132272344E5E900FC238B /* SwiftUIContainerViewController.swift */, - ); - path = "SwiftUI Demo"; - sourceTree = ""; - }; - B503FADA1AFDC71700F90881 /* List and Object Observers Demo */ = { - isa = PBXGroup; - children = ( - B5AA37EE2357D30300FFD4B9 /* ColorsDemo.swift */, - B52977D81B120B80003D50A5 /* ObserversViewController.swift */, - B503FADB1AFDC71700F90881 /* ListObserverDemoViewController.swift */, - B5635D182357F9F700B80E6B /* CollectionViewDemoViewController.swift */, - B503FADC1AFDC71700F90881 /* ObjectObserverDemoViewController.swift */, - B503FADD1AFDC71700F90881 /* Palette.swift */, - B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */, - B5635D1A2357FA4B00B80E6B /* PaletteCollectionViewCell.swift */, - B5C37EE42357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift */, - ); - path = "List and Object Observers Demo"; - sourceTree = ""; - }; - B52977DB1B120F2C003D50A5 /* Transactions Demo */ = { - isa = PBXGroup; - children = ( - B52977E31B121635003D50A5 /* Place.swift */, - B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */, - ); - path = "Transactions Demo"; - sourceTree = ""; - }; - B52977E21B120F90003D50A5 /* Frameworks */ = { - isa = PBXGroup; - children = ( - B501323423477D2300FC238B /* SwiftUI.framework */, - B52977E01B120F8A003D50A5 /* CoreLocation.framework */, - B5BDC9211C202429008147CD /* CoreStore.framework */, - B52977DE1B120F83003D50A5 /* MapKit.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - B54AAD401AF4D26E00848AE0 = { - isa = PBXGroup; - children = ( - B52977E21B120F90003D50A5 /* Frameworks */, - B54AAD4B1AF4D26E00848AE0 /* LegacyDemo */, - B54AAD4A1AF4D26E00848AE0 /* Products */, - ); - sourceTree = ""; - }; - B54AAD4A1AF4D26E00848AE0 /* Products */ = { - isa = PBXGroup; - children = ( - B54AAD491AF4D26E00848AE0 /* LegacyDemo.app */, - ); - name = Products; - sourceTree = ""; - }; - B54AAD4B1AF4D26E00848AE0 /* LegacyDemo */ = { - isa = PBXGroup; - children = ( - B54AAD4E1AF4D26E00848AE0 /* AppDelegate.swift */, - B50132222344E20B00FC238B /* SwiftUI Demo */, - B566E3271B117AE700F4F0C6 /* Stack Setup Demo */, - B503FADA1AFDC71700F90881 /* List and Object Observers Demo */, - B52977DB1B120F2C003D50A5 /* Transactions Demo */, - B56965091B2B35370075EE4A /* Fetching and Querying Demo */, - B569652F1B3591460075EE4A /* Migrations Demo */, - B56964C61B20AC200075EE4A /* Loggers Demo */, - B54AAD571AF4D26E00848AE0 /* Main.storyboard */, - B54AAD5A1AF4D26E00848AE0 /* Images.xcassets */, - B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */, - B54AAD501AF4D26E00848AE0 /* LegacyDemo.xcdatamodeld */, - B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */, - B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */, - B54AAD4C1AF4D26E00848AE0 /* Supporting Files */, - ); - path = LegacyDemo; - sourceTree = ""; - }; - B54AAD4C1AF4D26E00848AE0 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - B54AAD4D1AF4D26E00848AE0 /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - B566E3271B117AE700F4F0C6 /* Stack Setup Demo */ = { - isa = PBXGroup; - children = ( - B56964DB1B231BCB0075EE4A /* FemaleAccount.swift */, - B56964D91B231BCA0075EE4A /* MaleAccount.swift */, - B566E3311B11DF3200F4F0C6 /* UserAccount.swift */, - B566E3291B117B1F00F4F0C6 /* StackSetupDemoViewController.swift */, - ); - path = "Stack Setup Demo"; - sourceTree = ""; - }; - B56964C61B20AC200075EE4A /* Loggers Demo */ = { - isa = PBXGroup; - children = ( - B56964C81B20AC780075EE4A /* CustomLoggerViewController.swift */, - ); - path = "Loggers Demo"; - sourceTree = ""; - }; - B56965091B2B35370075EE4A /* Fetching and Querying Demo */ = { - isa = PBXGroup; - children = ( - B56965171B2E20CC0075EE4A /* TimeZone.swift */, - B569650B1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift */, - B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */, - B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */, - ); - path = "Fetching and Querying Demo"; - sourceTree = ""; - }; - B569652F1B3591460075EE4A /* Migrations Demo */ = { - isa = PBXGroup; - children = ( - B5EE259D1B3EC1B20000406B /* OrganismProtocol.swift */, - B5EE259A1B3EA4890000406B /* OrganismV3.swift */, - B5EE25861B36E2520000406B /* OrganismV2.swift */, - B5EE25841B36E23C0000406B /* OrganismV1.swift */, - B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */, - B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */, - B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */, - B560070E1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift */, - B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */, - ); - path = "Migrations Demo"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - B54AAD481AF4D26E00848AE0 /* LegacyDemo */ = { - isa = PBXNativeTarget; - buildConfigurationList = B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "LegacyDemo" */; - buildPhases = ( - B54AAD451AF4D26E00848AE0 /* Sources */, - B54AAD461AF4D26E00848AE0 /* Frameworks */, - B54AAD471AF4D26E00848AE0 /* Resources */, - B5E89ACF1C52929C003B04A9 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = LegacyDemo; - productName = LegacyDemo; - productReference = B54AAD491AF4D26E00848AE0 /* LegacyDemo.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - B54AAD411AF4D26E00848AE0 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 1200; - ORGANIZATIONNAME = "John Rommel Estropia"; - TargetAttributes = { - B54AAD481AF4D26E00848AE0 = { - CreatedOnToolsVersion = 6.3; - DevelopmentTeam = 2JT32EJ5BH; - LastSwiftMigration = 0900; - }; - }; - }; - buildConfigurationList = B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "LegacyDemo" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = B54AAD401AF4D26E00848AE0; - productRefGroup = B54AAD4A1AF4D26E00848AE0 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - B54AAD481AF4D26E00848AE0 /* LegacyDemo */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - B54AAD471AF4D26E00848AE0 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B54AAD591AF4D26E00848AE0 /* Main.storyboard in Resources */, - B54AAD5E1AF4D26E00848AE0 /* LaunchScreen.xib in Resources */, - B54AAD5B1AF4D26E00848AE0 /* Images.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - B54AAD451AF4D26E00848AE0 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B56965181B2E20CC0075EE4A /* TimeZone.swift in Sources */, - B5C37EE52357FEBE0035A20D /* PaletteCollectionSectionHeaderView.swift in Sources */, - B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */, - B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */, - B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */, - B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */, - B52977E41B121635003D50A5 /* Place.swift in Sources */, - B569650C1B2B36E10075EE4A /* FetchingAndQueryingDemoViewController.swift in Sources */, - B569651A1B30888A0075EE4A /* FetchingResultsViewController.swift in Sources */, - B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */, - B503FAE01AFDC71700F90881 /* ObjectObserverDemoViewController.swift in Sources */, - B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */, - B56964C91B20AC780075EE4A /* CustomLoggerViewController.swift in Sources */, - B5635D192357F9F700B80E6B /* CollectionViewDemoViewController.swift in Sources */, - B566E32A1B117B1F00F4F0C6 /* StackSetupDemoViewController.swift in Sources */, - B56964DA1B231BCA0075EE4A /* MaleAccount.swift in Sources */, - B566E3321B11DF3200F4F0C6 /* UserAccount.swift in Sources */, - B54AAD521AF4D26E00848AE0 /* LegacyDemo.xcdatamodeld in Sources */, - B5EE259B1B3EA4890000406B /* OrganismV3.swift in Sources */, - B503FAE11AFDC71700F90881 /* Palette.swift in Sources */, - B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */, - B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */, - B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */, - B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */, - B50132282344E5E900FC238B /* SwiftUIContainerViewController.swift in Sources */, - B5635D1B2357FA4B00B80E6B /* PaletteCollectionViewCell.swift in Sources */, - B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */, - B56964DC1B231BCB0075EE4A /* FemaleAccount.swift in Sources */, - B5AA37EF2357D30300FFD4B9 /* ColorsDemo.swift in Sources */, - B5EE259E1B3EC1B20000406B /* OrganismProtocol.swift in Sources */, - B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */, - B50132242344E24300FC238B /* SwiftUIView.swift in Sources */, - B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */, - B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - B54AAD571AF4D26E00848AE0 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - B54AAD581AF4D26E00848AE0 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - B54AAD5C1AF4D26E00848AE0 /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - B54AAD5D1AF4D26E00848AE0 /* Base */, - ); - name = LaunchScreen.xib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - B54AAD6B1AF4D26E00848AE0 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - B54AAD6C1AF4D26E00848AE0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; - SWIFT_VERSION = 5.0; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - B54AAD6E1AF4D26E00848AE0 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = 2JT32EJ5BH; - INFOPLIST_FILE = LegacyDemo/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.legacydemo; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; - }; - name = Debug; - }; - B54AAD6F1AF4D26E00848AE0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = 2JT32EJ5BH; - INFOPLIST_FILE = LegacyDemo/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.legacydemo; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "LegacyDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B54AAD6B1AF4D26E00848AE0 /* Debug */, - B54AAD6C1AF4D26E00848AE0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B54AAD6D1AF4D26E00848AE0 /* Build configuration list for PBXNativeTarget "LegacyDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B54AAD6E1AF4D26E00848AE0 /* Debug */, - B54AAD6F1AF4D26E00848AE0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCVersionGroup section */ - B54AAD501AF4D26E00848AE0 /* LegacyDemo.xcdatamodeld */ = { - isa = XCVersionGroup; - children = ( - B54AAD511AF4D26E00848AE0 /* LegacyDemo.xcdatamodel */, - ); - currentVersion = B54AAD511AF4D26E00848AE0 /* LegacyDemo.xcdatamodel */; - path = LegacyDemo.xcdatamodeld; - sourceTree = ""; - versionGroupType = wrapper.xcdatamodel; - }; - B56964D51B231AE90075EE4A /* StackSetupDemo.xcdatamodeld */ = { - isa = XCVersionGroup; - children = ( - B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */, - ); - currentVersion = B56964D61B231AE90075EE4A /* StackSetupDemo.xcdatamodel */; - path = StackSetupDemo.xcdatamodeld; - sourceTree = ""; - versionGroupType = wrapper.xcdatamodel; - }; - B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */ = { - isa = XCVersionGroup; - children = ( - B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */, - B5EE25801B36E1B00000406B /* MigrationDemoV2.xcdatamodel */, - B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */, - ); - currentVersion = B5EE25881B36E2750000406B /* MigrationDemoV3.xcdatamodel */; - path = MigrationDemo.xcdatamodeld; - sourceTree = ""; - versionGroupType = wrapper.xcdatamodel; - }; -/* End XCVersionGroup section */ - }; - rootObject = B54AAD411AF4D26E00848AE0 /* Project object */; -} diff --git a/LegacyDemo/LegacyDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/LegacyDemo/LegacyDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index c81ed91..0000000 --- a/LegacyDemo/LegacyDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/LegacyDemo/LegacyDemo/AppDelegate.swift b/LegacyDemo/LegacyDemo/AppDelegate.swift deleted file mode 100644 index c52cf26..0000000 --- a/LegacyDemo/LegacyDemo/AppDelegate.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// AppDelegate.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/02. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit - - -// MARK: - AppDelegate - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - // MARK: UIApplicationDelegate - - var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { - - return true - } -} - diff --git a/LegacyDemo/LegacyDemo/Base.lproj/LaunchScreen.xib b/LegacyDemo/LegacyDemo/Base.lproj/LaunchScreen.xib deleted file mode 100644 index e53eb1b..0000000 --- a/LegacyDemo/LegacyDemo/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/LegacyDemo/LegacyDemo/Base.lproj/Main.storyboard b/LegacyDemo/LegacyDemo/Base.lproj/Main.storyboard deleted file mode 100644 index c99974c..0000000 --- a/LegacyDemo/LegacyDemo/Base.lproj/Main.storyboard +++ /dev/null @@ -1,1182 +0,0 @@ - - - - - - - - - - - - AppleSDGothicNeo-Regular - - - HelveticaNeue - HelveticaNeue-Bold - - - HelveticaNeue-Light - HelveticaNeue-Thin - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingAndQueryingDemoViewController.swift b/LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingAndQueryingDemoViewController.swift deleted file mode 100644 index 5d8de68..0000000 --- a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingAndQueryingDemoViewController.swift +++ /dev/null @@ -1,319 +0,0 @@ -// -// FetchingAndQueryingDemoViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/12. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - - -private struct Static { - - static let timeZonesStack: DataStack = { - - let dataStack = DataStack() - try! dataStack.addStorageAndWait( - SQLiteStore( - fileName: "TimeZoneDemo.sqlite", - configuration: "FetchingAndQueryingDemo", - localStorageOptions: .recreateStoreOnModelMismatch - ) - ) - _ = try? dataStack.perform( - synchronous: { (transaction) in - - try transaction.deleteAll(From()) - - for name in NSTimeZone.knownTimeZoneNames { - - let rawTimeZone = NSTimeZone(name: name)! - let cachedTimeZone = transaction.create(Into()) - - cachedTimeZone.name = rawTimeZone.name - cachedTimeZone.abbreviation = rawTimeZone.abbreviation ?? "" - cachedTimeZone.secondsFromGMT = Int32(rawTimeZone.secondsFromGMT) - cachedTimeZone.hasDaylightSavingTime = rawTimeZone.isDaylightSavingTime - cachedTimeZone.daylightSavingTimeOffset = rawTimeZone.daylightSavingTimeOffset - } - } - ) - return dataStack - }() -} - - -// MARK: - FetchingAndQueryingDemoViewController - -class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { - - // MARK: UIViewController - - override func viewDidAppear(_ animated: Bool) { - - super.viewDidAppear(animated) - - if self.didAppearOnce { - - return - } - - self.didAppearOnce = true - - let alert = UIAlertController( - title: "Fetch and Query Demo", - message: "This demo shows how to execute fetches and queries.\n\nEach menu item executes and displays a preconfigured fetch/query.", - preferredStyle: .alert - ) - alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - - super.prepare(for: segue, sender: sender) - - if let indexPath = sender as? IndexPath { - - switch segue.destination { - - case let controller as FetchingResultsViewController: - let item = self.fetchingItems[indexPath.row] - controller.set(timeZones: item.fetch(), title: item.title) - - case let controller as QueryingResultsViewController: - let item = self.queryingItems[indexPath.row] - controller.set(value: item.query(), title: item.title) - - default: - break - } - } - } - - - // MARK: UITableViewDataSource - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - - switch self.segmentedControl?.selectedSegmentIndex { - - case Section.fetching.rawValue?: - return self.fetchingItems.count - - case Section.querying.rawValue?: - return self.queryingItems.count - - default: - return 0 - } - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - - let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")! - - switch self.segmentedControl?.selectedSegmentIndex { - - case Section.fetching.rawValue?: - cell.textLabel?.text = self.fetchingItems[indexPath.row].title - - case Section.querying.rawValue?: - cell.textLabel?.text = self.queryingItems[indexPath.row].title - - default: - cell.textLabel?.text = nil - } - - return cell - } - - - // MARK: UITableViewDelegate - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - - tableView.deselectRow(at: indexPath, animated: true) - - switch self.segmentedControl?.selectedSegmentIndex { - - case Section.fetching.rawValue?: - self.performSegue(withIdentifier: "FetchingResultsViewController", sender: indexPath) - - case Section.querying.rawValue?: - self.performSegue(withIdentifier: "QueryingResultsViewController", sender: indexPath) - - default: - break - } - } - - - // MARK: Private - - private enum Section: Int { - - case fetching - case querying - } - - private let fetchingItems = [ - ( - title: "All Time Zones", - fetch: { () -> [TimeZone] in - - return try! Static.timeZonesStack.fetchAll( - From() - .orderBy(.ascending(\.name)) - ) - } - ), - ( - title: "Time Zones in Asia", - fetch: { () -> [TimeZone] in - - return try! Static.timeZonesStack.fetchAll( - From() - .where( - format: "%K BEGINSWITH[c] %@", - #keyPath(TimeZone.name), - "Asia" - ) - .orderBy(.ascending(\.secondsFromGMT)) - ) - } - ), - ( - title: "Time Zones in America and Europe", - fetch: { () -> [TimeZone] in - - return try! Static.timeZonesStack.fetchAll( - From() - .where( - format: "%K BEGINSWITH[c] %@ OR %K BEGINSWITH[c] %@", - #keyPath(TimeZone.name), - "America", - #keyPath(TimeZone.name), - "Europe" - ) - .orderBy(.ascending(\.secondsFromGMT)) - ) - } - ), - ( - title: "All Time Zones Except America", - fetch: { () -> [TimeZone] in - - return try! Static.timeZonesStack.fetchAll( - From() - .where( - format: "%K BEGINSWITH[c] %@", - #keyPath(TimeZone.name), - "America" - ) - .orderBy(.ascending(\.secondsFromGMT)) - ) - } - ), - ( - title: "Time Zones with Summer Time", - fetch: { () -> [TimeZone] in - - return try! Static.timeZonesStack.fetchAll( - From() - .where(\.hasDaylightSavingTime == true) - .orderBy(.ascending(\.name)) - ) - } - ) - ] - - private let queryingItems: [(title: String, query: () -> Any)] = [ - ( - title: "Number of Time Zones", - query: { () -> Any in - - return try! Static.timeZonesStack.queryValue( - From() - .select(NSNumber.self, .count(\.name)) - )! - } - ), - ( - title: "Abbreviation For Tokyo's Time Zone", - query: { () -> Any in - - return try! Static.timeZonesStack.queryValue( - From() - .select(String.self, .attribute(\.abbreviation)) - .where(format: "%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo") - )! - } - ), - ( - title: "All Abbreviations", - query: { () -> Any in - - return try! Static.timeZonesStack.queryAttributes( - From() - .select( - NSDictionary.self, - .attribute(\.name), - .attribute(\.abbreviation) - ) - .orderBy(.ascending(\.name)) - ) - } - ), - ( - title: "Number of Countries per Time Zone", - query: { () -> Any in - - return try! Static.timeZonesStack.queryAttributes( - From() - .select( - NSDictionary.self, - .count(\.abbreviation), - .attribute(\.abbreviation) - ) - .groupBy(\.abbreviation) - .orderBy( - .ascending(\.secondsFromGMT), - .ascending(\.name) - ) - ) - } - ), - ( - title: "Number of Countries with Summer Time", - query: { () -> Any in - - return try! Static.timeZonesStack.queryAttributes( - From() - .select( - NSDictionary.self, - .count(\.hasDaylightSavingTime, as: "numberOfCountries"), - .attribute(\.hasDaylightSavingTime) - ) - .groupBy(\.hasDaylightSavingTime) - .orderBy( - .descending(\.hasDaylightSavingTime), - .ascending(\.name) - ) - ) - } - ) - ] - - var didAppearOnce = false - - @IBOutlet dynamic weak var segmentedControl: UISegmentedControl? - @IBOutlet dynamic weak var tableView: UITableView? - - @IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) { - - self.tableView?.reloadData() - } -} diff --git a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingResultsViewController.swift b/LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingResultsViewController.swift deleted file mode 100644 index 1e93e7f..0000000 --- a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/FetchingResultsViewController.swift +++ /dev/null @@ -1,68 +0,0 @@ -// -// FetchingResultsViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/17. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit - -// MARK: - FetchingResultsViewController - -class FetchingResultsViewController: UITableViewController { - - // MARK: Public - - func set(timeZones: [TimeZone]?, title: String) { - - self.timeZones += timeZones ?? [] - self.sectionTitle = title - - self.tableView?.reloadData() - } - - - // MARK: UIViewController - - override func viewDidLoad() { - - super.viewDidLoad() - - self.tableView.estimatedRowHeight = 60 - self.tableView.rowHeight = UITableView.automaticDimension - } - - - // MARK: UITableViewDataSource - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - - return self.timeZones.count - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - - let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath) - - let timeZone = self.timeZones[indexPath.row] - cell.textLabel?.text = timeZone.name - cell.detailTextLabel?.text = timeZone.abbreviation - - return cell - } - - - // MARK: UITableViewDelegate - - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - - return self.sectionTitle - } - - - // MARK: Private - - var timeZones = [TimeZone]() - var sectionTitle: String? -} diff --git a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/QueryingResultsViewController.swift b/LegacyDemo/LegacyDemo/Fetching and Querying Demo/QueryingResultsViewController.swift deleted file mode 100644 index 17a663e..0000000 --- a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/QueryingResultsViewController.swift +++ /dev/null @@ -1,88 +0,0 @@ -// -// QueryingResultsViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/17. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit - -class QueryingResultsViewController: UITableViewController { - - // MARK: Public - - func set(value: Any?, title: String) { - - switch value { - - case (let array as [Any])?: - self.values = array.map { (item: Any) -> (title: String, detail: String) in - ( - title: String(describing: item), - detail: String(reflecting: type(of: item)) - ) - } - - case let item?: - self.values = [ - ( - title: String(describing: item), - detail: String(reflecting: type(of: item)) - ) - ] - - default: - self.values = [] - } - - self.sectionTitle = title - - self.tableView?.reloadData() - } - - - // MARK: UIViewController - - override func viewDidLoad() { - - super.viewDidLoad() - - self.tableView.estimatedRowHeight = 60 - self.tableView.rowHeight = UITableView.automaticDimension - } - - - // MARK: UITableViewDataSource - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - - return self.values.count - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - - let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath) - - let value = self.values[indexPath.row] - - cell.textLabel?.text = value.title - cell.detailTextLabel?.text = value.detail - - return cell - } - - - // MARK: UITableViewDelegate - - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - - return self.sectionTitle - } - - - // MARK: Private - - var values: [(title: String, detail: String)] = [] - var sectionTitle: String? -} diff --git a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/TimeZone.swift b/LegacyDemo/LegacyDemo/Fetching and Querying Demo/TimeZone.swift deleted file mode 100644 index c112b69..0000000 --- a/LegacyDemo/LegacyDemo/Fetching and Querying Demo/TimeZone.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// TimeZone.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/15. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData - -class TimeZone: NSManagedObject { - - @NSManaged var secondsFromGMT: Int32 - @NSManaged var abbreviation: String - @NSManaged var hasDaylightSavingTime: Bool - @NSManaged var daylightSavingTimeOffset: Double - @NSManaged var name: String - -} diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Contents.json b/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 3092627..0000000 --- a/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-60@3x-1.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-76.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-76@2x.png", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Mask + Oval 1 + Oval 1 + Oval 1.png", - "scale" : "1x" - }, - { - "idiom" : "car", - "size" : "60x60", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "car", - "filename" : "Icon-60@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png b/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png deleted file mode 100644 index 1d1cc0cc26577a88a68ae707f657388f91ecd47d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7321 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 KMNUMnLSTYg!YW+= diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png b/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png deleted file mode 100644 index 74457f33402d019413b1edcd11a700e5850b09a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11648 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 KMNUMnLSTYg!YW+= diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-76.png b/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-76.png deleted file mode 100644 index bd400e93aaa89e09bbf6df95cdf734b45a561685..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4223 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 Vv-Bf#M%DlT002ovPDHLkV1g!Z9a{hZ diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png b/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png deleted file mode 100644 index fd39f4a5edbcf9487ca85999ef22ccc4b44689ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9568 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 KMNUMnLSTZ1f8DhJ diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Mask + Oval 1 + Oval 1 + Oval 1.png b/LegacyDemo/LegacyDemo/Images.xcassets/AppIcon.appiconset/Mask + Oval 1 + Oval 1 + Oval 1.png deleted file mode 100644 index dfdb62a401968fae133a711615966b43053df66b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 120873 zcmeFZc|4TiA2vG1zRuWpW0xgD*}`MXAX`z0vWzIn5~0P6u`7(F1!0mxQKD2t$Yd#5 zB1Ma_Z>1Sa4UO^Mqu=j+&-uLPpL6~^=X{<%4G(kA^W4vUf4|pteXp+!S7$Uoj}#9K z2IIH4vpEcdv4JnyU|byF1t+VS#QZMU(#aAAt0VBz{n=qK3z)r)rF$I9j~4EMlV6UE zKmYX;>vFLOos2BXLCPz%b@vt(1hYx>`squh+gqtb%5+7_NPamIc~9f|gKKWr?^;D1 zp1G2LPB33FCiAS1L=v~)$zDGW{iNg+W#wdxjx#N>i-%0w`KX$xA8yw zf5pfCdXn~K{7>ulHtu1|ug1CMNAc8P87WS#1la%fuPw#aua&kG^YYEYg&||9Cq?d0m<(iR6em}-6Nf$rBIx$Y*#~J+nLSPHj2gkhIZALqUK58(tOjZ#(h{_5FP+Qc+k{ZU`I{YoH=hivxm}X$ z^%df$=Se<$68e$E%Fv4J(O*l#J}@|}Gs(Hx4&@=PD@`7dqj540HRfIxgeVBQ(uS*X zBJS>`n5^ER+}b-R`V{bBNv~_UC(%3dYa(!9*Lf_>weS~G{V>R1F z+4GdB$3h6&R755xm`4gB$NFM&pRMe6bc7IsuKyyBKvQF6;8LYNC`B7A(khekz7H8PBLy8BN!6!iC5$O)p@T!^~CDsuBvOtpXjA+kU4P`28R*W2IYEPc5xYA+0QFZ zS>v)h63)7}=@`Rt0|cJXYjed09Xrxp+`P1o|=d>#e9z1Kn}Imh0dM`oWe z&O{MRjDp!3QHz4GhHvjd-r!`|)8(;wP|Zr^3;1o$tmd(kKJ2bpd-v~)LH1}|2)i!x z`f`-_gb>1?#O*veqr*mPC*I}Ww9g=;z);NhUKFxqkPpv$=0GW0-6*9<2XoIhc^p@@ zJWdg3Vu-t<2_s2MUfKGUc5Qk+)N{RhbnCN*aq@;RFIcdTu8MGOdeN@>wL>;n79?qN zB=|N7qV`ibFRhhtvhIvuq?JyrX*Hnd(kFh<{bPR~H1BX%Hl(J18FZ&coE@pXJ#D)d zfmuDhWHg(EqFX|9ar_KHE;3QySr7sAib6*{
sZoTILW<>*T!tDGe2{}IA-r2 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 G7X3fKQ;LxQ diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/Contents.json b/LegacyDemo/LegacyDemo/Images.xcassets/Contents.json deleted file mode 100644 index da4a164..0000000 --- a/LegacyDemo/LegacyDemo/Images.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/CoreStoreIcon.imageset/Contents.json b/LegacyDemo/LegacyDemo/Images.xcassets/CoreStoreIcon.imageset/Contents.json deleted file mode 100644 index 5066e8a..0000000 --- a/LegacyDemo/LegacyDemo/Images.xcassets/CoreStoreIcon.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "CoreStoreIcon@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/CoreStoreIcon.imageset/CoreStoreIcon@2x.png b/LegacyDemo/LegacyDemo/Images.xcassets/CoreStoreIcon.imageset/CoreStoreIcon@2x.png deleted file mode 100644 index dd28b0f917a790475aa96823346541fb319f15a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28665 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 diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/second.imageset/Contents.json b/LegacyDemo/LegacyDemo/Images.xcassets/second.imageset/Contents.json deleted file mode 100644 index 03bd9c9..0000000 --- a/LegacyDemo/LegacyDemo/Images.xcassets/second.imageset/Contents.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "second.pdf" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/Images.xcassets/second.imageset/second.pdf b/LegacyDemo/LegacyDemo/Images.xcassets/second.imageset/second.pdf deleted file mode 100644 index 401614e288b4b160471c2776bed6f09762af3e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2423 zcmai02~-nz8dqq7rWU#)x2z)&iMWtV?gK$2a)?|BP!TbkV}J-Gl1wmy+3G9S0=uOY zwCjai6uBOPMMdNiN`VDYKwLQr2#W^`R93*Ua=0^)EGYY4=grIf|KIohziYnv{elnR zdN_hk6db<(+3RPcxs!iut8c(j0TLh=9mY931H^rhEE0|aXo!dh5Iv+ZFr+}9F+v#P zLSnfD0$f~hN>~92V{z)WJA&2)5rW!|I?;o?oI*%zejJiuY>hFLQwKlAa9O+PnPh#% zJp~JAfs-De6u@;{cREMs}D-sGib_4>50m8_|Uj-zC0m@Qx zJV+^5Da4Qxpf3sBtKZs<_aI$Cb1T+h<->yL^rfiGNelYkqgC3#SqVP_iy*_RPcbjH)xYf zvYdC-)D_t8c{=5%;$VJQxs_#61J*kuXMC?|&PbPo-7uSxoNr~&J94|gKk+03JGXXM zx4w~=^VUzWqQveu_ilRgPdgNNdnLZCH`=;w91}cP5ihdm*B_jI+rk=Pz2Lk!)XUu| zkls3P5&YHJ!t0kF+MUVBHOAx)a zy|JxHNd37z*~b5#%*0w_F|#4?erNP;pG`Fevoq2%?9Y>%Cmzv1(ks;aPIGaiy1mhU zr{7lB^Mem&`QK{b{uiDC zLD8muY(FNk{YdV|zO#o_VB%);8|~Bh(Z4p?GM}g-HN2;q7~YNl-lD~HZ$taYw$Fzbn6c?c5eo=@`i>()el#qwB)hI-gp0 ztsw@dh-I5NJkk)RCoBC`L8ffKfY)=oG=#4LA9TO6eA}9~@a6dupB+=S{%s&NY}^0GY`hAqod)uxXHitrN%bWOJohV>t?!&Z#d4y^7J@=Oh`HV zee**4j>xRUd)|D0^I-B#<`m1-5PO{)!v(q?ecFYqr_8Q{+z7#n0uFbq%_?hZ-Ck(6NRn=vDS7Nb1Xxx_)9`!i- zGR>av*PJ+P_AGO*a_$FbtCCISg5PK44p&W#t$)+HVcxpR9LAL%_Pv$p`0tO*sYZD0 zCG3-ipr4WoVbjpw%Nf^r^rnWcDcjumgBPEjO;NM6QtZ8wU#0rjHx5zs%CahF4$W*U zxu!q8kYP+>v!BNPVIRJUGIWU@7qVvx2VZDw4gV8%z%bjpF#aF(W|PmliwlakuRq>= zhaCRc^R!7T)#Twb0{!Tns=CxGcGX|leErg`f3|v0eBXxHU&6Sj-_>zOL!!d+j5Xt* zPS;rWd^zEF{5d5%)nNK=)zFJ8Uc=aQKD%UK)_TNes1Gh{SD*Mb_@O` z7*zs9Uq~Vq?v|^8FcM-yLGMKzR3YFB0z@CFM2X-dio%Gu6&MJj=I?uS7sA3AdE^p8 zE49$PjJzPIJwfn;jso7X2#jynr3dO@p5QAK1O9wqKLC=PkQjj~p#n|-5O`ihbTzzu zL{}2QEe28pJYfVZRW56FL`LvO&|C^1Th{0}hQMW$Ng$QPpnzlwnMnf=kVy8(y==L% zLMa>r0gELdT - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - CoreStore - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 6.3.2 - CFBundleSignature - ???? - CFBundleVersion - 4 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UIStatusBarStyle - UIStatusBarStyleLightContent - UIStatusBarTintParameters - - UINavigationBar - - Style - UIBarStyleDefault - Translucent - - - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - - UIUserInterfaceStyle - Light - UIViewControllerBasedStatusBarAppearance - - - diff --git a/LegacyDemo/LegacyDemo/LegacyDemo.xcdatamodeld/LegacyDemo.xcdatamodel/contents b/LegacyDemo/LegacyDemo/LegacyDemo.xcdatamodeld/LegacyDemo.xcdatamodel/contents deleted file mode 100644 index 3b181e8..0000000 --- a/LegacyDemo/LegacyDemo/LegacyDemo.xcdatamodeld/LegacyDemo.xcdatamodel/contents +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/CollectionViewDemoViewController.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/CollectionViewDemoViewController.swift deleted file mode 100644 index 73ac494..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/CollectionViewDemoViewController.swift +++ /dev/null @@ -1,168 +0,0 @@ -// -// CollectionViewDemoViewController.swift -// LegacyDemo -// -// Created by John Estropia on 2019/10/17. -// Copyright © 2019 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - - -// MARK: - CollectionViewDemoViewController - -final class CollectionViewDemoViewController: UICollectionViewController { - - // MARK: UIViewController - - override func viewDidLoad() { - - super.viewDidLoad() - - let navigationItem = self.navigationItem - navigationItem.leftBarButtonItems = [ - self.editButtonItem, - UIBarButtonItem( - barButtonSystemItem: .trash, - target: self, - action: #selector(self.resetBarButtonItemTouched(_:)) - ) - ] - - let filterBarButton = UIBarButtonItem( - title: ColorsDemo.filter.rawValue, - style: .plain, - target: self, - action: #selector(self.filterBarButtonItemTouched(_:)) - ) - navigationItem.rightBarButtonItems = [ - UIBarButtonItem( - barButtonSystemItem: .add, - target: self, - action: #selector(self.addBarButtonItemTouched(_:)) - ), - UIBarButtonItem( - barButtonSystemItem: .refresh, - target: self, - action: #selector(self.shuffleBarButtonItemTouched(_:)) - ), - filterBarButton - ] - self.filterBarButton = filterBarButton - - self.dataSource = DiffableDataSource.CollectionViewAdapter( - collectionView: self.collectionView, - dataStack: ColorsDemo.stack, - cellProvider: { (collectionView, indexPath, palette) in - - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PaletteCollectionViewCell", for: indexPath) as! PaletteCollectionViewCell - cell.colorView?.backgroundColor = palette.color - cell.label?.text = palette.colorText - return cell - }, - supplementaryViewProvider: { (collectionView, kind, indexPath) in - - switch kind { - - case UICollectionView.elementKindSectionHeader: - let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "PaletteCollectionSectionHeaderView", for: indexPath) as! PaletteCollectionSectionHeaderView - view.label?.text = ColorsDemo.palettes.snapshot.sectionIDs[indexPath.section] - return view - - default: - return nil - } - } - ) - ColorsDemo.palettes.addObserver(self) { [weak self] (listPublisher) in - - guard let self = self else { - - return - } - self.filterBarButton?.title = ColorsDemo.filter.rawValue - self.dataSource?.apply(listPublisher.snapshot, animatingDifferences: true) - } - self.dataSource?.apply(ColorsDemo.palettes.snapshot, animatingDifferences: false) - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - - super.prepare(for: segue, sender: sender) - - switch (segue.identifier, segue.destination, sender) { - - case ("ObjectObserverDemoViewController"?, let destinationViewController as ObjectObserverDemoViewController, let palette as ObjectPublisher): - destinationViewController.setPalette(palette) - - default: - break - } - } - - - // MARK: UICollectionViewDelegate - - override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - - collectionView.deselectItem(at: indexPath, animated: true) - - self.performSegue( - withIdentifier: "ObjectObserverDemoViewController", - sender: ColorsDemo.palettes.snapshot[indexPath] - ) - } - - - // MARK: Private - - private var filterBarButton: UIBarButtonItem? - private var dataSource: DiffableDataSource.CollectionViewAdapter? - - deinit { - - ColorsDemo.palettes.removeObserver(self) - } - - @IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) { - - ColorsDemo.stack.perform( - asynchronous: { (transaction) in - - try transaction.deleteAll(From()) - }, - completion: { _ in } - ) - } - - @IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) { - - ColorsDemo.filter = ColorsDemo.filter.next() - } - - @IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) { - - ColorsDemo.stack.perform( - asynchronous: { (transaction) in - - _ = transaction.create(Into()) - }, - completion: { _ in } - ) - } - - @IBAction private dynamic func shuffleBarButtonItemTouched(_ sender: AnyObject?) { - ColorsDemo.stack.perform( - asynchronous: { (transaction) in - - for palette in try transaction.fetchAll(From()) { - - palette.hue = Palette.randomHue() - palette.colorName = nil - } - }, - completion: { _ in } - ) - } -} diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ColorsDemo.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/ColorsDemo.swift deleted file mode 100644 index 4b488db..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ColorsDemo.swift +++ /dev/null @@ -1,88 +0,0 @@ -// -// ColorsDemo.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2019/10/17. -// Copyright © 2019 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreStore - - -// MARK: - ColorsDemo - -struct ColorsDemo { - - enum Filter: String { - - case all = "All Colors" - case light = "Light Colors" - case dark = "Dark Colors" - - func next() -> Filter { - - switch self { - - case .all: return .light - case .light: return .dark - case .dark: return .all - } - } - - func whereClause() -> Where { - - switch self { - - case .all: return .init() - case .light: return (\Palette.$brightness >= 0.9) - case .dark: return (\Palette.$brightness <= 0.4) - } - } - } - - static var filter = Filter.all { - - didSet { - - try! self.palettes.refetch( - From() - .sectionBy(\.$colorName) - .where(self.filter.whereClause()) - .orderBy(.ascending(\.$hue)) - ) - } - } - - static let stack: DataStack = { - - let dataStack = DataStack( - CoreStoreSchema( - modelVersion: "ColorsDemo", - entities: [ - Entity("Palette"), - ], - versionLock: [ - "Palette": [0x8c25aa53c7c90a28, 0xa243a34d25f1a3a7, 0x56565b6935b6055a, 0x4f988bb257bf274f] - ] - ) - ) - - try! dataStack.addStorageAndWait( - SQLiteStore( - fileName: "ColorsDemo.sqlite", - localStorageOptions: .recreateStoreOnModelMismatch - ) - ) - return dataStack - }() - - static let palettes: ListPublisher = { - - return ColorsDemo.stack.publishList( - From() - .sectionBy(\.$colorName) - .orderBy(.ascending(\.$hue)) - ) - }() -} diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ListObserverDemoViewController.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/ListObserverDemoViewController.swift deleted file mode 100644 index ec0ba86..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ListObserverDemoViewController.swift +++ /dev/null @@ -1,181 +0,0 @@ -// -// ListObserverDemoViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/02. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - - -// MARK: - ListObserverDemoViewController - -final class ListObserverDemoViewController: UITableViewController { - - // MARK: - EditableDataSource - - final class EditableDataSource: DiffableDataSource.TableViewAdapter { - - override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { - - switch editingStyle { - - case .delete: - let palette = ColorsDemo.palettes.snapshot[indexPath] - ColorsDemo.stack.perform( - asynchronous: { (transaction) in - - transaction.delete(palette) - }, - completion: { _ in } - ) - - default: - break - } - } - } - - - // MARK: UIViewController - - override func viewDidLoad() { - - super.viewDidLoad() - - let navigationItem = self.navigationItem - navigationItem.leftBarButtonItems = [ - self.editButtonItem, - UIBarButtonItem( - barButtonSystemItem: .trash, - target: self, - action: #selector(self.resetBarButtonItemTouched(_:)) - ) - ] - - let filterBarButton = UIBarButtonItem( - title: ColorsDemo.filter.rawValue, - style: .plain, - target: self, - action: #selector(self.filterBarButtonItemTouched(_:)) - ) - navigationItem.rightBarButtonItems = [ - UIBarButtonItem( - barButtonSystemItem: .add, - target: self, - action: #selector(self.addBarButtonItemTouched(_:)) - ), - UIBarButtonItem( - barButtonSystemItem: .refresh, - target: self, - action: #selector(self.shuffleBarButtonItemTouched(_:)) - ), - filterBarButton - ] - self.filterBarButton = filterBarButton - - self.dataSource = EditableDataSource( - tableView: self.tableView, - dataStack: ColorsDemo.stack, - cellProvider: { (tableView, indexPath, palette) in - - let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell - cell.colorView?.backgroundColor = palette.color - cell.label?.text = palette.colorText - return cell - } - ) - ColorsDemo.palettes.addObserver(self) { [weak self] (listPublisher) in - - guard let self = self else { - - return - } - self.filterBarButton?.title = ColorsDemo.filter.rawValue - self.dataSource?.apply(listPublisher.snapshot, animatingDifferences: true) - } - self.dataSource?.apply(ColorsDemo.palettes.snapshot, animatingDifferences: false) - } - - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - - super.prepare(for: segue, sender: sender) - - switch (segue.identifier, segue.destination, sender) { - - case ("ObjectObserverDemoViewController"?, let destinationViewController as ObjectObserverDemoViewController, let palette as ObjectPublisher): - destinationViewController.setPalette(palette) - - default: - break - } - } - - - // MARK: UITableViewDelegate - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - - tableView.deselectRow(at: indexPath, animated: true) - - self.performSegue( - withIdentifier: "ObjectObserverDemoViewController", - sender: ColorsDemo.palettes.snapshot[indexPath] - ) - } - - - // MARK: Private - - private var filterBarButton: UIBarButtonItem? - private var dataSource: DiffableDataSource.TableViewAdapter? - - deinit { - - ColorsDemo.palettes.removeObserver(self) - } - - @IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) { - - ColorsDemo.stack.perform( - asynchronous: { (transaction) in - - try transaction.deleteAll(From()) - }, - completion: { _ in } - ) - } - - @IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) { - - ColorsDemo.filter = ColorsDemo.filter.next() - } - - @IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) { - - ColorsDemo.stack.perform( - asynchronous: { (transaction) in - - _ = transaction.create(Into()) - }, - completion: { _ in } - ) - } - - @IBAction private dynamic func shuffleBarButtonItemTouched(_ sender: AnyObject?) { - ColorsDemo.stack.perform( - asynchronous: { (transaction) in - - for palette in try transaction.fetchAll(From()) { - - palette.hue = Palette.randomHue() - palette.colorName = nil - } - }, - completion: { _ in } - ) - } -} - diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ObjectObserverDemoViewController.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/ObjectObserverDemoViewController.swift deleted file mode 100644 index 0c8fd1a..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ObjectObserverDemoViewController.swift +++ /dev/null @@ -1,192 +0,0 @@ -// -// ObjectObserverDemoViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/06. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - - -// MARK: - ObjectObserverDemoViewController - -class ObjectObserverDemoViewController: UIViewController, ObjectObserver { - - func setPalette(_ newValue: O?) where O.ObjectType == Palette { - - guard self.monitor?.object?.objectID() != newValue?.objectID() else { - - return - } - if let newValue = newValue { - - self.monitor = newValue.asReadOnly(in: ColorsDemo.stack).map(ColorsDemo.stack.monitorObject(_:)) - } - else { - - self.monitor = nil - } - } - - - // MARK: NSObject - - deinit { - - self.monitor?.removeObserver(self) - } - - - // MARK: UIViewController - - required init?(coder aDecoder: NSCoder) { - - if let palette = try! ColorsDemo.stack.fetchOne(From().orderBy(.ascending(\.$hue))) { - - self.monitor = ColorsDemo.stack.monitorObject(palette) - } - else { - - _ = try? ColorsDemo.stack.perform( - synchronous: { (transaction) in - - _ = transaction.create(Into()) - } - ) - - let palette = try! ColorsDemo.stack.fetchOne(From().orderBy(.ascending(\.$hue)))! - self.monitor = ColorsDemo.stack.monitorObject(palette) - } - - super.init(coder: aDecoder) - } - - override func viewDidLoad() { - - super.viewDidLoad() - self.monitor?.addObserver(self) - - if let palette = self.monitor?.object { - - self.reloadPaletteInfo(palette, changedKeys: nil) - } - } - - - // MARK: ObjectObserver - - func objectMonitor(_ monitor: ObjectMonitor, didUpdateObject object: Palette, changedPersistentKeys: Set) { - - self.reloadPaletteInfo(object, changedKeys: changedPersistentKeys) - } - - func objectMonitor(_ monitor: ObjectMonitor, didDeleteObject object: Palette) { - - self.navigationItem.rightBarButtonItem?.isEnabled = false - - self.colorNameLabel?.alpha = 0.3 - self.colorView?.alpha = 0.3 - - self.hsbLabel?.text = "Deleted" - self.hsbLabel?.textColor = UIColor.red - - self.hueSlider?.isEnabled = false - self.saturationSlider?.isEnabled = false - self.brightnessSlider?.isEnabled = false - } - - - // MARK: Private - - var monitor: ObjectMonitor? - - @IBOutlet weak var colorNameLabel: UILabel? - @IBOutlet weak var colorView: UIView? - @IBOutlet weak var hsbLabel: UILabel? - @IBOutlet weak var dateLabel: UILabel? - @IBOutlet weak var hueSlider: UISlider? - @IBOutlet weak var saturationSlider: UISlider? - @IBOutlet weak var brightnessSlider: UISlider? - - @IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) { - - let hue = self.hueSlider?.value ?? 0 - ColorsDemo.stack.perform( - asynchronous: { [weak self] (transaction) in - - if let palette = transaction.edit(self?.monitor?.object) { - - palette.hue = Int(hue) - } - }, - completion: { _ in } - ) - } - - @IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) { - - let saturation = self.saturationSlider?.value ?? 0 - ColorsDemo.stack.perform( - asynchronous: { [weak self] (transaction) in - - if let palette = transaction.edit(self?.monitor?.object) { - - palette.saturation = saturation - } - }, - completion: { _ in } - ) - } - - @IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) { - - let brightness = self.brightnessSlider?.value ?? 0 - ColorsDemo.stack.perform( - asynchronous: { [weak self] (transaction) in - - if let palette = transaction.edit(self?.monitor?.object) { - - palette.brightness = brightness - } - }, - completion: { _ in } - ) - } - - @IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) { - - ColorsDemo.stack.perform( - asynchronous: { [weak self] (transaction) in - - transaction.delete(self?.monitor?.object) - }, - completion: { _ in } - ) - } - - func reloadPaletteInfo(_ palette: Palette, changedKeys: Set?) { - - self.colorNameLabel?.text = palette.colorName - - let color = palette.color - self.colorNameLabel?.textColor = color - self.colorView?.backgroundColor = color - - self.hsbLabel?.text = palette.colorText - - if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.$hue)) == true { - - self.hueSlider?.value = Float(palette.hue) - } - if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.$saturation)) == true { - - self.saturationSlider?.value = palette.saturation - } - if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.$brightness)) == true { - - self.brightnessSlider?.value = palette.brightness - } - } -} diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ObserversViewController.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/ObserversViewController.swift deleted file mode 100644 index e85627c..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/ObserversViewController.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// ObserversViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/24. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit - - -// MARK: - ObserversViewController - -class ObserversViewController: UIViewController { - - // MARK: UIViewController - - override func viewDidAppear(_ animated: Bool) { - - super.viewDidAppear(animated) - - let alert = UIAlertController( - title: "Observers Demo", - message: "This demo shows how to observe changes to a list of objects. The top and bottom view controllers both observe a single shared \"ListMonitor\" instance.\n\nTap on a row to see how to observe changes made to a single object using a \"ObjectMonitor\".", - preferredStyle: .alert - ) - alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - } - - - // MARK: Private - - @IBOutlet private dynamic weak var toggleTopBarButtonItem: UIBarButtonItem? - @IBOutlet private dynamic weak var toggleBottomBarButtonItem: UIBarButtonItem? - @IBOutlet private dynamic weak var stackView: UIStackView? - @IBOutlet private dynamic weak var topContainerView: UIView? - @IBOutlet private dynamic weak var bottomContainerView: UIView? - - @IBAction private dynamic func toggleTopContainerView() { - - UIView.animate(withDuration: 0.2) { - - self.topContainerView!.isHidden.toggle() - } - self.toggleTopBarButtonItem!.isEnabled = !self.bottomContainerView!.isHidden - self.toggleBottomBarButtonItem!.isEnabled = !self.topContainerView!.isHidden - } - - @IBAction private dynamic func toggleBottomContainerView() { - - UIView.animate(withDuration: 0.2) { - - self.bottomContainerView!.isHidden.toggle() - } - self.toggleTopBarButtonItem!.isEnabled = !self.bottomContainerView!.isHidden - self.toggleBottomBarButtonItem!.isEnabled = !self.topContainerView!.isHidden - } -} diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/Palette.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/Palette.swift deleted file mode 100644 index bc3124e..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/Palette.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// Palette.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/05. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import UIKit -import CoreData -import CoreStore - - -// MARK: - Palette - -final class Palette: CoreStoreObject { - - @Field.Stored( - "hue", - dynamicInitialValue: { Palette.randomHue() } - ) - var hue: Int - - @Field.Stored("saturation") - var saturation: Float = 1 - - @Field.Stored( - "brightness", - dynamicInitialValue: { Palette.randomBrightness() } - ) - var brightness: Float - - @Field.Virtual( - "colorName", - customGetter: { object, field in - if let colorName = field.primitiveValue { - return colorName - } - let colorName: String - switch object.$hue.value { - case 0 ..< 20: colorName = "Lower Reds" - case 20 ..< 57: colorName = "Oranges and Browns" - case 57 ..< 90: colorName = "Yellow-Greens" - case 90 ..< 159: colorName = "Greens" - case 159 ..< 197: colorName = "Blue-Greens" - case 197 ..< 241: colorName = "Blues" - case 241 ..< 297: colorName = "Violets" - case 297 ..< 331: colorName = "Magentas" - case 331 ..< 360: colorName = "Upper Reds" - default: colorName = "" - } - field.primitiveValue = colorName - return colorName - } - ) - var colorName: String! - - static func randomHue() -> Int { - - return Int.random(in: 0 ..< 360) - } - - static func randomBrightness() -> Float { - - return (Float.random(in: 0 ..< 70) + 30) / 100.0 - } -} - -extension Palette { - - var color: UIColor { - - return UIColor( - hue: CGFloat(self.hue) / 360.0, - saturation: CGFloat(self.saturation), - brightness: CGFloat(self.brightness), - alpha: 1.0 - ) - } - - var colorText: String { - - return "H: \(self.hue)˚, S: \(round(self.saturation * 100.0))%, B: \(round(self.brightness * 100.0))%" - } -} diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionSectionHeaderView.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionSectionHeaderView.swift deleted file mode 100644 index ecf7166..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionSectionHeaderView.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// PaletteCollectionSectionHeaderView.swift -// LegacyDemo -// -// Created by John Estropia on 2019/10/17. -// Copyright © 2019 John Rommel Estropia. All rights reserved. -// - -import UIKit - - -// MARK: - PaletteCollectionSectionHeaderView - -final class PaletteCollectionSectionHeaderView: UICollectionReusableView { - - @IBOutlet weak var label: UILabel? -} diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionViewCell.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionViewCell.swift deleted file mode 100644 index 2bf508f..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteCollectionViewCell.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// PaletteCollectionViewCell.swift -// LegacyDemo -// -// Created by John Estropia on 2019/10/17. -// Copyright © 2019 John Rommel Estropia. All rights reserved. -// - -import UIKit - - -// MARK: - PaletteCollectionViewCell - -final class PaletteCollectionViewCell: UICollectionViewCell { - - @IBOutlet weak var colorView: UIView? - @IBOutlet weak var label: UILabel? -} diff --git a/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteTableViewCell.swift b/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteTableViewCell.swift deleted file mode 100644 index 86b144d..0000000 --- a/LegacyDemo/LegacyDemo/List and Object Observers Demo/PaletteTableViewCell.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// PaletteTableViewCell.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/05. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit - - -// MARK: - PaletteTableViewCell - -final class PaletteTableViewCell: UITableViewCell { - - @IBOutlet weak var colorView: UIView? - @IBOutlet weak var label: UILabel? -} diff --git a/LegacyDemo/LegacyDemo/Loggers Demo/CustomLoggerViewController.swift b/LegacyDemo/LegacyDemo/Loggers Demo/CustomLoggerViewController.swift deleted file mode 100644 index 2de764e..0000000 --- a/LegacyDemo/LegacyDemo/Loggers Demo/CustomLoggerViewController.swift +++ /dev/null @@ -1,126 +0,0 @@ -// -// CustomLoggerViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/05. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - - -// MARK: - CustomLoggerViewController - -class CustomLoggerViewController: UIViewController, CoreStoreLogger { - - // MARK: NSObject - - let dataStack = DataStack() - - // MARK: UIViewController - - override func viewDidLoad() { - - super.viewDidLoad() - - try! self.dataStack.addStorageAndWait(SQLiteStore(fileName: "emptyStore.sqlite")) - } - - override func viewDidAppear(_ animated: Bool) { - - super.viewDidAppear(animated) - - CoreStoreDefaults.logger = self - - let alert = UIAlertController( - title: "Logger Demo", - message: "This demo shows how to plug-in any logging framework to CoreStore.\n\nThe view controller implements CoreStoreLogger and appends all logs to the text view.", - preferredStyle: .alert - ) - alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - } - - override func viewDidDisappear(_ animated: Bool) { - - super.viewDidDisappear(animated) - - CoreStoreDefaults.logger = DefaultLogger() - } - - - // MARK: CoreStoreLogger - - func log(level: LogLevel, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { - - DispatchQueue.main.async { [weak self] in - - let levelString: String - switch level { - - case .trace: levelString = "Trace" - case .notice: levelString = "Notice" - case .warning: levelString = "Warning" - case .fatal: levelString = "Fatal" - } - self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Log:\(levelString)] \(message)\n\n") - } - } - - func log(error: CoreStoreError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { - - DispatchQueue.main.async { [weak self] in - - self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Error] \(message): \(error)\n\n") - } - } - - func assert(_ condition: @autoclosure () -> Bool, message: @autoclosure () -> String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { - - if condition() { - - return - } - - let messageString = message() - DispatchQueue.main.async { [weak self] in - - self?.textView?.insertText("\((String(describing: fileName) as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Assert] \(messageString)\n\n") - } - } - - - // MARK: Private - - @IBOutlet dynamic weak var textView: UITextView? - @IBOutlet dynamic weak var segmentedControl: UISegmentedControl? - - @IBAction dynamic func segmentedControlValueChanged(_ sender: AnyObject?) { - - switch self.segmentedControl?.selectedSegmentIndex { - - case 0?: - let request = NSFetchRequest() - Where(true).applyToFetchRequest(request) - Where(false).applyToFetchRequest(request) - - case 1?: - _ = try? dataStack.addStorageAndWait( - SQLiteStore( - fileName: "emptyStore.sqlite", - configuration: "invalidStore" - ) - ) - - case 2?: - DispatchQueue.global(qos: .background).async { - - _ = try! self.dataStack.fetchOne(From()) - } - - default: - return - } - } -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/MigrationsDemoViewController.swift b/LegacyDemo/LegacyDemo/MIgrations Demo/MigrationsDemoViewController.swift deleted file mode 100644 index fc6a662..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/MigrationsDemoViewController.swift +++ /dev/null @@ -1,445 +0,0 @@ -// -// MigrationsDemoViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/21. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - - -// MARK: - MigrationsDemoViewController - -class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewDataSource, UITableViewDelegate { - - // MARK: UIViewController - - override func viewDidLoad() { - - super.viewDidLoad() - - if let segmentedControl = self.segmentedControl { - - for (index, model) in self.models.enumerated() { - - segmentedControl.setTitle( - model.label, - forSegmentAt: index - ) - } - } - self.set(dataStack: nil, model: nil, scrollToSelection: false) - } - - override func viewDidAppear(_ animated: Bool) { - - super.viewDidAppear(animated) - - let alert = UIAlertController( - title: "Migrations Demo", - message: "This demo shows how to run progressive migrations and how to support multiple model versions in a single project.\n\nThe persistent store contains 10000 organisms, which gain/lose properties when the migration evolves/devolves them.\n\nYou can use the \"mutate\" button to change an organism's properties then migrate to a different model to see how its value gets affected.", - preferredStyle: .alert - ) - alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - - - let modelMetadata = withExtendedLifetime(DataStack(xcodeModelName: "MigrationDemo")) { - (dataStack: DataStack) -> ModelMetadata in - - let models = self.models - let migrations = try! dataStack.requiredMigrationsForStorage( - SQLiteStore(fileName: "MigrationDemo.sqlite") - ) - - guard let storeVersion = migrations.first?.sourceVersion else { - - return models.first! - } - for model in models { - - if model.schemaHistory.currentModelVersion == storeVersion { - - return model - } - } - - return models.first! - } - - self.selectModelVersion(modelMetadata) - } - - // MARK: ListObserver - - func listMonitorWillChange(_ monitor: ListMonitor) { } - - func listMonitorDidChange(_ monitor: ListMonitor) { - - if self.lastSelectedIndexPath == nil, - let numberOfObjectsInSection = self.listMonitor?.numberOfObjects(in: 0), - numberOfObjectsInSection > 0 { - - self.tableView?.reloadData() - self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: false) - } - else { - - self.updateDisplay(reloadData: true, scrollToSelection: true, animated: true) - } - } - - func listMonitorDidRefetch(_ monitor: ListMonitor) { - - self.listMonitorDidChange(monitor) - } - - // MARK: UITableViewDataSource - - @objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - - return self.listMonitor?.numberOfObjects(in: 0) ?? 0 - } - - @objc dynamic func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - - let cell = tableView.dequeueReusableCell(withIdentifier: "OrganismTableViewCell", for: indexPath) as! OrganismTableViewCell - - let dna = (self.listMonitor?[indexPath] as? OrganismProtocol)?.dna.description ?? "" - cell.dnaLabel?.text = "DNA: \(dna)" - cell.mutateButtonHandler = { [weak self] () -> Void in - - guard let `self` = self, - let dataStack = self.dataStack, - let organism = self.listMonitor?[indexPath] else { - - return - } - - self.setSelectedIndexPath(indexPath, scrollToSelection: false) - self.setEnabled(false) - dataStack.perform( - asynchronous: { (transaction) in - - let organism = transaction.edit(organism) as! OrganismProtocol - organism.mutate() - }, - completion: { [weak self] _ in - - self?.setEnabled(true) - } - ) - } - return cell - } - - - // MARK: UITableViewDelegate - - @objc dynamic func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - - self.setSelectedIndexPath(indexPath, scrollToSelection: false) - } - - - // MARK: Private - - private typealias ModelMetadata = (label: String, entityType: NSManagedObject.Type, schemaHistory: SchemaHistory) - - private let models: [ModelMetadata] = [ - ( - label: "Model V1", - entityType: OrganismV1.self, - schemaHistory: SchemaHistory( - XcodeDataModelSchema.from( - modelName: "MigrationDemo", - migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"] - ), - migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"] - ) - ), - ( - label: "Model V2", - entityType: OrganismV2.self, - schemaHistory: SchemaHistory( - XcodeDataModelSchema.from( - modelName: "MigrationDemo", - migrationChain: [ - "MigrationDemo": "MigrationDemoV2", - "MigrationDemoV3": "MigrationDemoV2" - ] - ), - migrationChain: [ - "MigrationDemo": "MigrationDemoV2", - "MigrationDemoV3": "MigrationDemoV2" - ] - ) - ), - ( - label: "Model V3", - entityType: OrganismV3.self, - schemaHistory: SchemaHistory( - XcodeDataModelSchema.from( - modelName: "MigrationDemo", - migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"] - ), - migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"] - ) - ) - ] - - private var _listMonitor: ListMonitor? - private var listMonitor: ListMonitor? { - - return self._listMonitor - } - - private var _dataStack: DataStack? - private var dataStack: DataStack? { - - return self._dataStack - } - - private var _lastSelectedIndexPath: IndexPath? - private var lastSelectedIndexPath: IndexPath? { - - return self._lastSelectedIndexPath - } - - private func setSelectedIndexPath(_ indexPath: IndexPath, scrollToSelection: Bool) { - - self._lastSelectedIndexPath = indexPath - self.updateDisplay(reloadData: false, scrollToSelection: scrollToSelection, animated: true) - } - - @IBOutlet private dynamic weak var headerContainer: UIView? - @IBOutlet private dynamic weak var titleLabel: UILabel? - @IBOutlet private dynamic weak var organismLabel: UILabel? - @IBOutlet private dynamic weak var segmentedControl: UISegmentedControl? - @IBOutlet private dynamic weak var progressView: UIProgressView? - @IBOutlet private dynamic weak var tableView: UITableView? - - @IBAction private dynamic func segmentedControlValueChanged(_ sender: AnyObject?) { - - guard let index = self.segmentedControl?.selectedSegmentIndex else { - - return - } - - self.selectModelVersion(self.models[index]) - } - - private func selectModelVersion(_ model: ModelMetadata) { - - if self.dataStack?.modelVersion == model.schemaHistory.currentModelVersion { - - return - } - - self.set(dataStack: nil, model: nil, scrollToSelection: false) // explicitly trigger NSPersistentStore cleanup by deallocating the stack - - let dataStack = DataStack(schemaHistory: model.schemaHistory) - - self.setEnabled(false) - let progress = dataStack.addStorage( - SQLiteStore( - fileName: "MigrationDemo.sqlite", - migrationMappingProviders: [ - CustomSchemaMappingProvider( - from: "MigrationDemoV3", - to: "MigrationDemoV2", - entityMappings: [ - .transformEntity( - sourceEntity: "Organism", - destinationEntity: "Organism", - transformer: { (source, createDestination) in - - let destination = createDestination() - destination.enumerateAttributes { (attribute, sourceAttribute) in - - if let sourceAttribute = sourceAttribute { - - destination[attribute] = source[sourceAttribute] - } - } - destination["numberOfFlippers"] = source["numberOfLimbs"] - } - ) - ] - ) - ] - ), - completion: { [weak self] (result) -> Void in - - guard let `self` = self else { - - return - } - - guard case .success = result else { - - self.setEnabled(true) - return - } - - self.set(dataStack: dataStack, model: model, scrollToSelection: true) - - let count = try! dataStack.queryValue( - From(model.entityType) - .select(Int.self, .count(#keyPath(OrganismV1.dna))))! - if count > 0 { - - self.setEnabled(true) - } - else { - - for i: Int64 in 0 ..< 20 { - - dataStack.perform( - asynchronous: { (transaction) in - - for j: Int64 in 0 ..< 500 { - - let organism = transaction.create(Into(model.entityType)) as! OrganismProtocol - organism.dna = (i * 500) + j + 1 - organism.mutate() - } - }, - completion: { _ in } - ) - } - dataStack.perform( - asynchronous: { _ in }, - completion: { [weak self] _ in - - self?.setEnabled(true) - } - ) - } - } - ) - - if let progress = progress { - - progress.setProgressHandler { [weak self] (progress) -> Void in - - self?.reloadTableHeaderWithProgress(progress) - } - } - } - - private func setEnabled(_ enabled: Bool) { - - UIView.animate( - withDuration: 0.2, - delay: 0, - options: .beginFromCurrentState, - animations: { () -> Void in - - let navigationItem = self.navigationItem - navigationItem.leftBarButtonItem?.isEnabled = enabled - navigationItem.rightBarButtonItem?.isEnabled = enabled - navigationItem.hidesBackButton = !enabled - - self.segmentedControl?.isEnabled = enabled - - if let tableView = self.tableView { - - tableView.alpha = enabled ? 1.0 : 0.5 - tableView.isUserInteractionEnabled = enabled - } - }, - completion: nil - ) - } - - private func set(dataStack: DataStack?, model: ModelMetadata?, scrollToSelection: Bool) { - - if let dataStack = dataStack, let model = model { - - self.segmentedControl?.selectedSegmentIndex = self.models - .firstIndex( - where: { (arg) -> Bool in - - let (_, _, schemaHistory) = arg - return schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion - } - )! - - self._dataStack = dataStack - let listMonitor = dataStack.monitorList( - From(model.entityType), - OrderBy(.descending(#keyPath(OrganismV1.dna))) - ) - listMonitor.addObserver(self) - self._listMonitor = listMonitor - - if self.lastSelectedIndexPath == nil { - - if listMonitor.numberOfObjects(in: 0) > 0 { - - self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: true) - } - } - } - else { - - self.segmentedControl?.selectedSegmentIndex = UISegmentedControl.noSegment - self._listMonitor = nil - self._dataStack = nil - } - - self.updateDisplay(reloadData: true, scrollToSelection: scrollToSelection, animated: false) - } - - private func reloadTableHeaderWithProgress(_ progress: Progress) { - - self.progressView?.setProgress(Float(progress.fractionCompleted), animated: true) - self.titleLabel?.text = "Migrating: \(progress.localizedDescription ?? "")" - self.organismLabel?.text = "Progressive step \(progress.localizedAdditionalDescription ?? "")" - } - - private func updateDisplay(reloadData: Bool, scrollToSelection: Bool, animated: Bool) { - - var lines = [String]() - var organismType = "" - if let indexPath = self.lastSelectedIndexPath, let organism = self.listMonitor?[indexPath] { - - for property in organism.entity.properties { - - let value = organism.value(forKey: property.name) ?? NSNull() - lines.append("\(property.name): \(value)") - } - organismType = organism.entity.managedObjectClassName - } - - self.titleLabel?.text = organismType - self.organismLabel?.text = lines.joined(separator: "\n") - self.progressView?.progress = 0 - - self.headerContainer?.setNeedsLayout() - - guard let tableView = self.tableView else { - - return - } - - if reloadData { - - tableView.reloadData() - } - - tableView.layoutIfNeeded() - - if let indexPath = self.lastSelectedIndexPath, - indexPath.row < tableView.numberOfRows(inSection: 0) { - - tableView.selectRow(at: indexPath, - animated: scrollToSelection && animated, - scrollPosition: scrollToSelection ? .middle : .none - ) - } - } -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/.xccurrentversion b/LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/.xccurrentversion deleted file mode 100644 index 0c67376..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/.xccurrentversion +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/MyAppModel.xcdatamodel/contents b/LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/MyAppModel.xcdatamodel/contents deleted file mode 100644 index 34afc82..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/MyAppModel.xcdatamodeld/MyAppModel.xcdatamodel/contents +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismProtocol.swift b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismProtocol.swift deleted file mode 100644 index d672fed..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismProtocol.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// OrganismProtocol.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/27. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation - -protocol OrganismProtocol: AnyObject { - - var dna: Int64 { get set } - - func mutate() -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismTableViewCell.swift b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismTableViewCell.swift deleted file mode 100644 index 356e8af..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismTableViewCell.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// OrganismTableViewCell.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/07/12. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit - -class OrganismTableViewCell: UITableViewCell { - - @IBOutlet weak dynamic var dnaLabel: UILabel? - @IBOutlet weak dynamic var mutateButton: UIButton? - - var mutateButtonHandler: (() -> Void)? - - @IBAction dynamic func mutateButtonTouchUpInside(_ sender: UIButton?) { - - self.mutateButtonHandler?() - } -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV1.swift b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV1.swift deleted file mode 100644 index ea96d24..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV1.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// OrganismV1.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/21. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData - -class OrganismV1: NSManagedObject, OrganismProtocol { - - @NSManaged var dna: Int64 - @NSManaged var hasHead: Bool - @NSManaged var hasTail: Bool - - // MARK: OrganismProtocol - - func mutate() { - - self.hasHead = arc4random_uniform(2) == 1 - self.hasTail = arc4random_uniform(2) == 1 - } -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2.swift b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2.swift deleted file mode 100644 index 931fcab..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// OrganismV2.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/21. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData - -class OrganismV2: NSManagedObject, OrganismProtocol { - - @NSManaged var dna: Int64 - @NSManaged var hasHead: Bool - @NSManaged var hasTail: Bool - @NSManaged var numberOfFlippers: Int32 - - // MARK: OrganismProtocol - - func mutate() { - - self.hasHead = arc4random_uniform(2) == 1 - self.hasTail = arc4random_uniform(2) == 1 - self.numberOfFlippers = Int32(arc4random_uniform(9) / 2 * 2) - } -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3.xcmappingmodel/xcmapping.xml b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3.xcmappingmodel/xcmapping.xml deleted file mode 100644 index 80e10b6..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3.xcmappingmodel/xcmapping.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - 134481920 - C1A5998D-0F2D-40D2-8299-2B2804420D2B - 109 - - - - NSPersistenceFrameworkVersion - 526 - NSStoreModelVersionHashes - - XDDevAttributeMapping - - 0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc= - - XDDevEntityMapping - - qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI= - - XDDevMappingModel - - EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ= - - XDDevPropertyMapping - - XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA= - - XDDevRelationshipMapping - - akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs= - - - NSStoreModelVersionHashesVersion - 3 - NSStoreModelVersionIdentifiers - - - - - - - - - dna - - - - CoreStoreDemo.OrganismV2ToV3MigrationPolicy - Organism - Undefined - 1 - Organism - 1 - - - - - - numberOfLimbs - - - - hasVertebrae - - - - hasHead - - - - hasTail - - - - CoreStoreDemo/MigrationDemo.xcdatamodeld/MigrationDemoV2.xcdatamodel - YnBsaXN0MDDUAAEAAgADAAQABQAGBqAGoVgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv -cBIAAYagrxCtAAcACAAXADMANAA1AD0APgBZAFoAWwBhAGIAbgCCAIMAhACFAIYAhwCIAIkAigCjAKYArQCzAMIA0QDgAOMAWADzAQIBBgEKARkBHwEgASgBNwE4AUEBTQFOAU8BUAFRAWYBZwFvAXABcQF9AZEBkgGTAZQBlQGWAZcBmAGZAagBtwHGAcoB2QHoAekB+AIHAhYCIgI0AjUCNgI3AjgCOQI6AjsCSgJZAmgCdwJ4AocClgKlAq0CwgLDAssC1wLrAvoDCQMYAxwDKwM6A0kDWANnA3MDhQOUA6MDsgPBA8ID0QPgA+8EBAQFBA0EGQQtBDwESwRaBF4EbQR8BIsEmgSpBLUExwTWBNcE5gT1BQQFBQUUBSMFMgVHBUgFUAVcBXAFfwWOBZ0FoQWwBb8FzgXdBewF+AYKBhkGKAY3BkYGVQZkBnMGdAZ3BoAGhAaIBowGlAaXBpsGnFUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAEwAWXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoACgKyAqYAAgKqAAICr3gAYABkAGgAbABwAHQAeAAoAHwAgACEAIgAjACQAJQAmACcAKAAlABMAKwAsAC0ALgAvACUAJQATXxAcWERCdWNrZXRGb3JDbGFzc2Vzd2FzRW5jb2RlZF8QGlhEQnVja2V0Rm9yUGFja2FnZXNzdG9yYWdlXxAcWERCdWNrZXRGb3JJbnRlcmZhY2Vzc3RvcmFnZV8QD194ZF9vd25pbmdNb2RlbF8QHVhEQnVja2V0Rm9yUGFja2FnZXN3YXNFbmNvZGVkVl9vd25lcl8QG1hEQnVja2V0Rm9yRGF0YVR5cGVzc3RvcmFnZVtfdmlzaWJpbGl0eV8QGVhEQnVja2V0Rm9yQ2xhc3Nlc3N0b3JhZ2VVX25hbWVfEB9YREJ1Y2tldEZvckludGVyZmFjZXN3YXNFbmNvZGVkXxAeWERCdWNrZXRGb3JEYXRhVHlwZXN3YXNFbmNvZGVkXxAQX3VuaXF1ZUVsZW1lbnRJRIAEgKeApYABgASAAICmgKgQAIAFgAOABIAEgABQU1lFU9MANgA3AAoAOAA6ADxXTlMua2V5c1pOUy5vYmplY3RzoQA5gAahADuAB4AiWE9yZ2FuaXNt3xAQAD8AQABBAEIAHQBDAEQAHwBFAEYACgAhAEcASAAkAEkASgBLACUAJQAQAE8AUAAtACUASgBTADkASgBWAFcAWF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzc3RvcmFnZV8QIFhEQnVja2V0Rm9yU3RlcmVvdHlwZXN3YXNFbmNvZGVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc3N0b3JhZ2VfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc2R1cGxpY2F0ZXNfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zc3RvcmFnZVtfaXNBYnN0cmFjdIAJgCqABIAEgAKACoCigASACYCkgAaACYCjgAgIEiJt3CdXb3JkZXJlZNMANgA3AAoAXABeADyhAF2AC6EAX4AMgCJeWERfUFN0ZXJlb3R5cGXZAB0AIQBjAAoAJABkAB8ASQBlADsAXQBKAGkAEwAlAC0AWABtXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlgAeAC4AJgCmAAIAECIAN0wA2ADcACgBvAHgAPKgAcABxAHIAcwB0AHUAdgB3gA6AD4AQgBGAEoATgBSAFagAeQB6AHsAfAB9AH4AfwCAgBaAGoAbgByAHoAggCOAJ4AiXxATWERQTUNvbXBvdW5kSW5kZXhlc18QEFhEX1BTS19lbGVtZW50SURfEBpYRF9QU0tfdmVyc2lv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ExUTFxMYEz0TYROIE6wTrhOwE7ITtBO2E7gTuRO7E8gT1xPZE9sT3RPfE+ET4xPlE/QT9hP4E/oT/BP+FAAUAhQEFCQUTxRpFIIUnBS8FN8VHhUgFSIVJBUmFScVKBUpFSoVLBUuFS8VMBUyFTMVchV0FXYVeBV6FXsVfBV9FX4VgBWCFYMVhBWGFYcVxhXIFcoVzBXOFc8V0BXRFdIV1BXWFdcV2BXaFdsWGhYcFh4WIBYiFiMWJBYlFiYWKBYqFisWLBYuFi8WMhZxFnMWdRZ3FnkWehZ7FnwWfRZ/FoEWghaDFoUWhhbFFscWyRbLFs0WzhbPFtAW0RbTFtUW1hbXFtkW2hcZFxsXHRcfFyEXIhcjFyQXJRcnFykXKhcrFy0XLhc3F0UXUhdgF20XgBeXF6kX9BgXGDcYVxhZGFsYXRhfGGEYYhhjGGUYZhhoGGkYaxhtGG4YbxhxGHIYdxiEGIkYixiNGJIYlBiWGJgYvRjhGQgZLBkuGTAZMhk0GTYZOBk5GTsZSBlZGVsZXRlfGWEZYxllGWcZaRl6GXwZfhmAGYIZhBmGGYgZihmMGcsZzRnPGdEZ0xnUGdUZ1hnXGdkZ2xncGd0Z3xngGh8aIRojGiUaJxooGikaKhorGi0aLxowGjEaMxo0GnMadRp3Gnkaexp8Gn0afhp/GoEagxqEGoUahxqIGpUalhqXGpka2BraGtwa3hrgGuEa4hrjGuQa5hroGuka6hrsGu0bLBsuGzAbMhs0GzUbNhs3GzgbOhs8Gz0bPhtAG0EbgBuCG4QbhhuIG4kbihuLG4wbjhuQG5EbkhuUG5Ub1BvWG9gb2hvcG90b3hvfG+Ab4hvkG+Ub5hvoG+kcKBwqHCwcLhwwHDEcMhwzHDQcNhw4HDkcOhw8HD0cYhyGHK0c0RzTHNUc1xzZHNsc3RzeHOAc7Rz8HP4dAB0CHQQdBh0IHQodGR0bHR0dHx0hHSMdJR0nHSkdaB1qHWwdbh1wHXEdch1zHXQddh14HXkdeh18HX0dvB2+HcAdwh3EHcUdxh3HHcgdyh3MHc0dzh3QHdEeEB4SHhQeFh4YHhkeGh4bHhweHh4gHiEeIh4kHiUeZB5mHmgeah5sHm0ebh5vHnAech50HnUedh54HnkefB67Hr0evx7BHsMexB7FHsYexx7JHssezB7NHs8e0B8PHxEfEx8VHxcfGB8ZHxofGx8dHx8fIB8hHyMfJB9jH2UfZx9pH2sfbB9tH24fbx9xH3MfdB91H3cfeB/DH+YgBiAmICggKiAsIC4gMCAxIDIgNCA1IDcgOCA6IDwgPSA+IEAgQSBGIFMgWCBaIFwgYSBjIGUgZyCMILAg1yD7IP0g/yEBIQMhBSEHIQghCiEXISghKiEsIS4hMCEyITQhNiE4IUkhSyFNIU8hUSFTIVUhVyFZIVshmiGcIZ4hoCGiIaMhpCGlIaYhqCGqIashrCGuIa8h7iHwIfIh9CH2Ifch+CH5Ifoh/CH+If8iACICIgMiQiJEIkYiSCJKIksiTCJNIk4iUCJSIlMiVCJWIlciZCJlImYiaCKnIqkiqyKtIq8isCKxIrIisyK1IrciuCK5IrsivCL7Iv0i/yMBIwMjBCMFIwYjByMJIwsjDCMNIw8jECNPI1EjUyNVI1cjWCNZI1ojWyNdI18jYCNhI2MjZCOjI6UjpyOpI6sjrCOtI64jryOxI7MjtCO1I7cjuCP3I/kj+yP9I/8kACQBJAIkAyQFJAckCCQJJAskDCQxJFUkfCSgJKIkpCSmJKgkqiSsJK0kryS8JMskzSTPJNEk0yTVJNck2SToJOok7CTuJPAk8iT0JPYk+CU3JTklOyU9JT8lQCVBJUIlQyVFJUclSCVJJUslTCVOJY0ljyWRJZMllSWWJZclmCWZJZslnSWeJZ8loSWiJeEl4yXlJecl6SXqJesl7CXtJe8l8SXyJfMl9SX2JjUmNyY5JjsmPSY+Jj8mQCZBJkMmRSZGJkcmSSZKJkwmiyaNJo8mkSaTJpQmlSaWJpcmmSabJpwmnSafJqAm3ybhJuMm5SbnJugm6SbqJusm7SbvJvAm8SbzJvQnMyc1JzcnOSc7JzwnPSc+Jz8nQSdDJ0QnRSdHJ0gnkye2J9Yn9if4J/on/Cf+KAAoASgCKAQoBSgHKAgoCigMKA0oDigQKBEoFigjKCgoKigsKDEoMyg1KDcoXCiAKKcoyyjNKM8o0SjTKNUo1yjYKNoo5yj4KPoo/Cj+KQApAikEKQYpCCkZKRspHSkfKSEpIyklKScpKSkrKWopbCluKXApcilzKXQpdSl2KXgpeil7KXwpfil/Kb4pwCnCKcQpxinHKcgpySnKKcwpzinPKdAp0inTKhIqFCoWKhgqGiobKhwqHSoeKiAqIiojKiQqJionKjQqNSo2Kjgqdyp5KnsqfSp/KoAqgSqCKoMqhSqHKogqiSqLKowqyyrNKs8q0SrTKtQq1SrWKtcq2SrbKtwq3SrfKuArHyshKyMrJSsnKygrKSsqKysrLSsvKzArMSszKzQrcyt1K3creSt7K3wrfSt+K38rgSuDK4QrhSuHK4grxyvJK8srzSvPK9Ar0SvSK9Mr1SvXK9gr2SvbK9wsASwlLEwscCxyLHQsdix4LHosfCx9LH8sjCybLJ0snyyhLKMspSynLKksuCy6LLwsvizALMIsxCzGLMgtBy0JLQstDS0PLRAtES0SLRMtFS0XLRgtGS0bLRwtWy1dLV8tYS1jLWQtZS1mLWctaS1rLWwtbS1vLXAtry2xLbMttS23LbgtuS26LbstvS2/LcAtwS3DLcQuAy4FLgcuCS4LLgwuDS4OLg8uES4TLhQuFS4XLhguVy5ZLlsuXS5fLmAuYS5iLmMuZS5nLmguaS5rLmwuqy6tLq8usS6zLrQutS62LrcuuS67LrwuvS6/LsAu/y8BLwMvBS8HLwgvCS8KLwsvDS8PLxAvES8TLxQvHy8oLykvKy80Lz8vTi9ZL2cvfC+QL6cvuS/GL8cvyC/KL9cv2C/ZL9sv6C/pL+ov7C/1MAQwETAgMDIwRjBdMG8weDB5MHswiDCJMIowjDCNMJYwoDCnMK8wwTDGMMsAAAAAAAACAgAAAAAAAAakAAAAAAAAAAAAAAAAAAAwzQ== - - CoreStoreDemo/MigrationDemo.xcdatamodeld/MigrationDemoV3.xcdatamodel - YnBsaXN0MDDUAAEAAgADAAQABQAGB+QH5VgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv -cBIAAYagrxDFAAcACAAXADMANAA1AD0APgBZAFoAWwBhAGIAbgCCAIMAhACFAIYAhwCIAIkAigCjAKYArQCzAMIA0QDgAOMAWADzAQIBBgEKARkBHwEgASgBNwE4AUEBTwFQAVEBUgFTAVQBaQFqAXIBcwF0AYABlAGVAZYBlwGYAZkBmgGbAZwBqwG6AckBzQHcAesB+gIJAhgCJAI2AjcCOAI5AjoCOwI8Aj0CTAJNAlwCawJ6AnsCigKZAqgCsALFAsYCzgLaAu4C/QMMAxsDHwMuAz0DTANbA2oDdgOIA5cDpgO1A8QDxQPUA+MD8gQHBAgEEAQcBDAEPwROBF0EYQRwBH8EgASPBJ4ErQS5BMsE2gTpBPgFBwUIBRcFJgU1BUoFSwVTBV8FcwWCBZEFoAWkBbMFwgXRBeAF7wX7Bg0GHAYrBjoGSQZYBmcGdgaLBowGlAagBrQGwwbSBuEG5Qb0BwMHEgchBzAHPAdOB10HbAd7B4oHmQeoB7cHuAe7B8QHyAfMB9AH2AfbB98H4FUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAEwAWXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoACgMSAwYAAgMKAAIDD3gAYABkAGgAbABwAHQAeAAoAHwAgACEAIgAjACQAJQAmACcAKAAlABMAKwAsAC0ALgAvACUAJQATXxAcWERCdWNrZXRGb3JDbGFzc2Vzd2FzRW5jb2RlZF8QGlhEQnVja2V0Rm9yUGFja2FnZXNzdG9yYWdlXxAcWERCdWNrZXRGb3JJbnRlcmZhY2Vzc3RvcmFnZV8QD194ZF9vd25pbmdNb2RlbF8QHVhEQnVja2V0Rm9yUGFja2FnZXN3YXNFbmNvZGVkVl9vd25lcl8QG1hEQnVja2V0Rm9yRGF0YVR5cGVzc3RvcmFnZVtfdmlzaWJpbGl0eV8QGVhEQnVja2V0Rm9yQ2xhc3Nlc3N0b3JhZ2VVX25hbWVfEB9YREJ1Y2tldEZvckludGVyZmFjZXN3YXNFbmNvZGVkXxAeWERCdWNrZXRGb3JEYXRhVHlwZXN3YXNFbmNvZGVkXxAQX3VuaXF1ZUVsZW1lbnRJRIAEgL+AvYABgASAAIC+gMAQAIAFgAOABIAEgABQU1lFU9MANgA3AAoAOAA6ADxXTlMua2V5c1pOUy5vYmplY3RzoQA5gAahADuAB4AiWE9yZ2FuaXNt3xAQAD8AQABBAEIAHQBDAEQAHwBFAEYACgAhAEcASAAkAEkASgBLACUAJQAQAE8AUAAtACUASgBTADkASgBWAFcAWF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzc3RvcmFnZV8QIFhEQnVja2V0Rm9yU3RlcmVvdHlwZXN3YXNFbmNvZGVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc3N0b3JhZ2VfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc2R1cGxpY2F0ZXNfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zc3RvcmFnZVtfaXNBYnN0cmFjdIAJgCqABIAEgAKACoC6gASACYC8gAaACYC7gAgIEu7HTMhXb3JkZXJlZNMANgA3AAoAXABeADyhAF2AC6EAX4AMgCJeWERfUFN0ZXJlb3R5cGXZAB0AIQBjAAoAJABkAB8ASQBlADsAXQBKAGkAEwAlAC0AWABtXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlgAeAC4AJgCmAAIAECIAN0wA2ADcACgBvAHgAPKgAcABxAHIAcwB0AHUAdgB3gA6AD4AQgBGAEoATgBSAFagAeQB6AHsAfAB9AH4AfwCAgBaAGoAbgByAHoAggCOAJ4AiXxATWERQTUNv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ACQAlAATABMAEwaSAFgAWABYAC0AWACdAiYAWABYABMAWIAAgACAAICxCAgICIAZgEoICIAACN8QDwCLAIwAjQAdAI4AjwCQAB8AkQAKACEAkgCTACQAlAATAOUAEwaSAFgAWABYAC0AWACdAicAWABYABMAWIAAgB+AAICxCAgICIAZgEsICIAACN8QDwCLAIwAjQAdAI4AjwCQAB8AkQAKACEAkgCTACQAlAATABMAEwaSAFgAWABYAC0AWACdAigAWABYABMAWIAAgACAAICxCAgICIAZgEwICIAACN8QDwCLAIwAjQAdAI4AjwCQAB8AkQAKACEAkgCTACQAlAATA7cAEwaSAFgAWABYAC0AWACdAikAWABYABMAWIAAgG+AAICxCAgICIAZgE0ICIAACN8QDwCLAIwAjQAdAI4AjwCQAB8AkQAKACEAkgCTACQAlAATABMAEwaSAFgAWABYAC0AWACdAioAWABYABMAWIAAgACAAICxCAgICIAZgE4ICIAACN8QDwCLAIwAjQAdAI4AjwCQAB8AkQAKACEAkgCTACQAlAATABMAEwaSAFgAWABYAC0AWACdAisAWABYABMAWIAAgACAAICxCAgICIAZgE8ICIAACN8QDwCLAIwAjQAdAI4AjwCQAB8AkQAKACEAkgCTACQAlAATABMAEwaSAFgAWABYAC0AWACdAiwAWABYABMAWIAAgACAAICxCAgICIAZgFAICIAACFpkdXBsaWNhdGVz0gA3AAoHuQCloIAY0gCnAKgHvAe9WlhEUE1FbnRpdHmnB74HvwfAB8EHwgfDAKxaWERQTUVudGl0eV1YRFVNTENsYXNzSW1wXxASWERVTUxDbGFzc2lmaWVySW1wXxARWERVTUxOYW1lc3BhY2VJbXBfEBRYRFVNTE5hbWVkRWxlbWVudEltcF8QD1hEVU1MRWxlbWVudEltcNMANgA3AAoHxQfGADygoIAi0wA2ADcACgfJB8oAPKCggCLTADYANwAKB80HzgA8oKCAItIApwCoB9EH0l5YRE1vZGVsUGFja2FnZaYH0wfUB9UH1gfXAKxeWERNb2RlbFBhY2thZ2VfEA9YRFVNTFBhY2thZ2VJbXBfEBFYRFVNTE5hbWVzcGFjZUltcF8QFFhEVU1MTmFtZWRFbGVtZW50SW1wXxAPWERVTUxFbGVtZW50SW1w0gA3AAoH2QCloIAY0wA2ADcACgfcB90APKCggCJQ0gCnAKgH4QfiWVhEUE1Nb2RlbKMH4QfjAKxXWERNb2RlbF8QD05TS2V5ZWRBcmNoaXZlctEH5gAoVHJvb3SAAQAIABkAIgArADUAOgA/AcwB0gHvAgECCAIVAigCQAJOAmgCagJsAm4CcAJyAnQCdgKvAs4C6wMKAxwDPANDA2EDbQOJA48DsQPSA+UD5wPpA+sD7QPvA/ED8wP1A/cD+QP7A/0D/wQBBAIEBgQTBBsEJgQpBCsELgQwBDIEOwR+BKIExgTpBRAFMAVXBX4FngXCBeYF8gX0BfYF+AX6BfwF/gYABgIGBAYGBggGCgYMBg4GDwYUBhwGKQYsBi4GMQYzBjUGRAZpBo0GtAbYBtoG3AbeBuAG4gbkBuUG5wb0BwUHBwcJBwsHDQcPBxEHEwcVByYHKAcqBywHLgcwBzIHNAc2BzgHTgdhB34HmgeuB8AH1gfvCC4INAg9CEoIVghgCGoIdQiACI0IlQiXCJkImwidCJ4InwigCKEIowilCKYIpwipCKoIswi0CLYIvwjKCNMI4gjpCPEI+gkDCRYJHwkyCUkJWwmaCZwJngmgCaIJowmkCaUJpgmoCaoJqwmsCa4JrwnuCfAJ8gn0CfYJ9wn4CfkJ+gn8Cf4J/woACgIKAwpCCkQKRgpICkoKSwpMCk0KTgpQClIKUwpUClYKVwpgCmEKYwqiCqQKpgqoCqoKqwqsCq0KrgqwCrIKswq0CrYKtwq4CvcK+Qr7Cv0K/wsACwELAgsDCwULBwsICwkLCwsMCxkLGgsbCx0LJgs8C0MLUAuPC5ELkwuVC5cLmAuZC5oLmwudC58LoAuhC6MLpAu9C78LwQvDC8QLxgvdC+YL9AwBDA8MJAw4DE8MYQygDKIMpAymDKgMqQyqDKsMrAyuDLAMsQyyDLQMtQzQDNkM7gz9DRINIA01DUkNYA1yDX8Nig2MDY4NkA2SDZQNnw2hDaMNpQ2nDakNqw25DcYNyg3SDdoOJQ5IDmgOiA6KDowOjg6QDpIOkw6UDpYOlw6ZDpoOnA6eDp8OoA6iDqMOqA61DroOvA6+DsMOxQ7HDskO3g7zDxgPPA9jD4cPiQ+LD40Pjw+RD5MPlA+WD6MPtA+2D7gPug+8D74PwA/CD8QP1Q/XD9kP2w/dD98P4Q/jD+UP5xAFECMQNhBKEF8QfBCQEKYQ5RDnEOkQ6xDtEO4Q7xDwEPEQ8xD1EPYQ9xD5EPoRORE7ET0RPxFBEUIRQxFEEUURRxFJEUoRSxFNEU4RjRGPEZERkxGVEZYRlxGYEZkRmxGdEZ4RnxGhEaIRrxGwEbERsxHyEfQR9hH4EfoR+xH8Ef0R/hIAEgISAxIEEgYSBxJGEkgSShJMEk4STxJQElESUhJUElYSVxJYEloSWxKaEpwSnhKgEqISoxKkEqUSphKoEqoSqxKsEq4SrxLuEvAS8hL0EvYS9xL4EvkS+hL8Ev4S/xMAEwITAxNCE0QTRhNIE0oTSxNME00TThNQE1ITUxNUE1YTVxN8E6ATxxPrE+0T7xPxE/MT9RP3E/gT+hQHFBYUGBQaFBwUHhQgFCIUJBQzFDUUNxQ5FDsUPRQ/FEEUQxRjFI4UqBTBFNsU+xUeFV0VXxVhFWMVZRVmFWcVaBVpFWsVbRVuFW8VcRVyFXQVsxW1FbcVuRW7FbwVvRW+Fb8VwRXDFcQVxRXHFcgWBxYJFgsWDRYPFhAWERYSFhMWFRYXFhgWGRYbFhwWWxZdFl8WYRZjFmQWZRZmFmcWaRZrFmwWbRZvFnAWchaxFrMWtRa3FrkWuha7FrwWvRa/FsEWwhbDFsUWxhcFFwcXCRcLFw0XDhcPFxAXERcTFxUXFhcXFxkXGhdZF1sXXRdfF2EXYhdjF2QXZRdnF2kXahdrF20Xbhd3F4UXkhegF60XwBfXF+kYNBhXGHcYlxiZGJsYnRifGKEYohijGKUYphioGKkYqxitGK4YrxixGLIYtxjEGMkYyxjNGNIY1BjWGNgY/RkhGUgZbBluGXAZchl0GXYZeBl5GXsZiBmZGZsZnRmfGaEZoxmlGacZqRm6GbwZvhnAGcIZxBnGGcgZyhnMGgsaDRoPGhEaExoUGhUaFhoXGhkaGxocGh0aHxogGl8aYRpjGmUaZxpoGmkaahprGm0abxpwGnEacxp0GrMatRq3Grkauxq8Gr0avhq/GsEawxrEGsUaxxrIGtUa1hrXGtkbGBsaGxwbHhsgGyEbIhsjGyQbJhsoGykbKhssGy0bbBtuG3Abcht0G3Ubdht3G3gbeht8G30bfhuAG4EbwBvCG8QbxhvIG8kbyhvLG8wbzhvQG9Eb0hvUG9UcFBwWHBgcGhwcHB0cHhwfHCAcIhwkHCUcJhwoHCkcaBxqHGwcbhxwHHEcchxzHHQcdhx4HHkcehx8HH0cohzGHO0dER0THRUdFx0ZHRsdHR0eHSAdLR08HT4dQB1CHUQdRh1IHUodWR1bHV0dXx1hHWMdZR1nHWkdqB2qHawdrh2wHbEdsh2zHbQdth24Hbkduh28Hb0d/B3+HgAeAh4EHgUeBh4HHggeCh4MHg0eDh4QHhEeUB5SHlQeVh5YHlkeWh5bHlweXh5gHmEeYh5kHmUepB6mHqgeqh6sHq0erh6vHrAesh60HrUeth64HrkevB77Hv0e/x8BHwMfBB8FHwYfBx8JHwsfDB8NHw8fEB9PH1EfUx9VH1cfWB9ZH1ofWx9dH18fYB9hH2MfZB+jH6Ufpx+pH6sfrB+tH64frx+xH7MftB+1H7cfuCADICYgRiBmIGggaiBsIG4gcCBxIHIgdCB1IHcgeCB6IHwgfSB+IIAggSCGIJMgmCCaIJwgoSCjIKUgpyDMIPAhFyE7IT0hPyFBIUMhRSFHIUghSiFXIWghaiFsIW4hcCFyIXQhdiF4IYkhiyGNIY8hkSGTIZUhlyGZIZsh2iHcId4h4CHiIeMh5CHlIeYh6CHqIesh7CHuIe8iLiIwIjIiNCI2IjciOCI5IjoiPCI+Ij8iQCJCIkMigiKEIoYiiCKKIosijCKNIo4ikCKSIpMilCKWIpcipCKlIqYiqCLnIuki6yLtIu8i8CLxIvIi8yL1Ivci+CL5Ivsi/CM7Iz0jPyNBI0MjRCNFI0YjRyNJI0sjTCNNI08jUCNRI5AjkiOUI5YjmCOZI5ojmyOcI54joCOhI6IjpCOlI+Qj5iPoI+oj7CPtI+4j7yPwI/Ij9CP1I/Yj+CP5JDgkOiQ8JD4kQCRBJEIkQyREJEYkSCRJJEokTCRNJHIkliS9JOEk4yTlJOck6STrJO0k7iTwJP0lDCUOJRAlEiUUJRYlGCUaJSklKyUtJS8lMSUzJTUlNyU5JXgleiV8JX4lgCWBJYIlgyWEJYYliCWJJYoljCWNJcwlziXQJdIl1CXVJdYl1yXYJdol3CXdJd4l4CXhJiAmIiYkJiYmKCYpJiomKyYsJi4mMCYxJjImNCY1JnQmdiZ4JnomfCZ9Jn4mfyaAJoImhCaFJoYmiCaJJowmyybNJs8m0SbTJtQm1SbWJtcm2SbbJtwm3SbfJuAnHychJyMnJScnJygnKScqJysnLScvJzAnMSczJzQncyd1J3cneSd7J3wnfSd+J38ngSeDJ4QnhSeHJ4gn0yf2KBYoNig4KDooPCg+KEAoQShCKEQoRShHKEgoSihMKE0oTihQKFEoVihjKGgoaihsKHEocyh1KHconCjAKOcpCykNKQ8pESkTKRUpFykYKRopJyk4KTopPCk+KUApQilEKUYpSClZKVspXSlfKWEpYyllKWcpaSlrKaoprCmuKbApsimzKbQptSm2Kbgpuim7Kbwpvim/Kf4qACoCKgQqBioHKggqCSoKKgwqDioPKhAqEioTKlIqVCpWKlgqWipbKlwqXSpeKmAqYipjKmQqZipnKnQqdSp2Kngqtyq5KrsqvSq/KsAqwSrCKsMqxSrHKsgqySrLKswrCysNKw8rESsTKxQrFSsWKxcrGSsbKxwrHSsfKyArXythK2MrZStnK2graStqK2srbStvK3ArcStzK3Qrsyu1K7cruSu7K7wrvSu+K78rwSvDK8QrxSvHK8gsBywJLAssDSwPLBAsESwSLBMsFSwXLBgsGSwbLBwsQSxlLIwssCyyLLQstiy4LLosvCy9LL8szCzbLN0s3yzhLOMs5SznLOks+Cz6LPws/i0ALQItBC0GLQgtRy1JLUstTS1PLVAtUS1SLVMtVS1XLVgtWS1bLVwtmy2dLZ8toS2jLaQtpS2mLactqS2rLawtrS2vLbAt7y3xLfMt9S33Lfgt+S36Lfst/S3/LgAuAS4DLgQuQy5FLkcuSS5LLkwuTS5OLk8uUS5TLlQuVS5XLlguly6ZLpsunS6fLqAuoS6iLqMupS6nLqguqS6rLqwu6y7tLu8u8S7zLvQu9S72Lvcu+S77Lvwu/S7/LwAvPy9BL0MvRS9HL0gvSS9KL0svTS9PL1AvUS9TL1Qvny/CL+IwAjAEMAYwCDAKMAwwDTAOMBAwETATMBQwFjAYMBkwGjAcMB0wJjAzMDgwOjA8MEEwQzBFMEcwbDCQMLcw2zDdMN8w4TDjMOUw5zDoMOow9zEIMQoxDDEOMRAxEjEUMRYxGDEpMSsxLTEvMTExMzE1MTcxOTE7MXoxfDF+MYAxgjGDMYQxhTGGMYgxijGLMYwxjjGPMc4x0DHSMdQx1jHXMdgx2THaMdwx3jHfMeAx4jHjMiIyJDImMigyKjIrMiwyLTIuMjAyMjIzMjQyNjI3MkQyRTJGMkgyhzKJMosyjTKPMpAykTKSMpMylTKXMpgymTKbMpwy2zLdMt8y4TLjMuQy5TLmMucy6TLrMuwy7TLvMvAzLzMxMzMzNTM3MzgzOTM6MzszPTM/M0AzQTNDM0QzgzOFM4cziTOLM4wzjTOOM48zkTOTM5QzlTOXM5gz1zPZM9sz3TPfM+Az4TPiM+Mz5TPnM+gz6TPrM+w0ETQ1NFw0gDSCNIQ0hjSINIo0jDSNNI80nDSrNK00rzSxNLM0tTS3NLk0yDTKNMw0zjTQNNI01DTWNNg1FzUZNRs1HTUfNSA1ITUiNSM1JTUnNSg1KTUrNSw1azVtNW81cTVzNXQ1dTV2NXc1eTV7NXw1fTV/NYA1vzXBNcM1xTXHNcg1yTXKNcs1zTXPNdA10TXTNdQ2EzYVNhc2GTYbNhw2HTYeNh82ITYjNiQ2JTYnNig2ZzZpNms2bTZvNnA2cTZyNnM2dTZ3Nng2eTZ7Nnw2uza9Nr82wTbDNsQ2xTbGNsc2yTbLNsw2zTbPNtA3DzcRNxM3FTcXNxg3GTcaNxs3HTcfNyA3ITcjNyQ3Lzc4Nzk3OzdEN083XjdpN3c3jDegN7c3yTfWN9c32DfaN+c36DfpN+s3+Df5N/o3/DgFOBQ4ITgwOEI4VjhtOH84iDiJOIs4mDiZOJo4nDidOKY4sDi3OL840TjWONsAAAAAAAACAgAAAAAAAAfoAAAAAAAAAAAAAAAAAAA43Q== - - - - - Organism - Undefined - 0 - Organism - 1 - - - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3MigrationPolicy.swift b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3MigrationPolicy.swift deleted file mode 100644 index 033593e..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV2ToV3MigrationPolicy.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// OrganismV2ToV3MigrationPolicy.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/27. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import CoreData - -class OrganismV2ToV3MigrationPolicy: NSEntityMigrationPolicy { - - override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws { - - try super.createDestinationInstances(forSource: sInstance, in: mapping, manager: manager) - - for dInstance in manager.destinationInstances(forEntityMappingName: mapping.name, sourceInstances: [sInstance]) { - - dInstance.setValue( - false, - forKey: #keyPath(OrganismV3.hasVertebrae) - ) - dInstance.setValue( - sInstance.value(forKey: #keyPath(OrganismV2.numberOfFlippers)), - forKey: #keyPath(OrganismV3.numberOfLimbs) - ) - } - } -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3.swift b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3.swift deleted file mode 100644 index e2a910e..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// OrganismV3.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/27. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData - -class OrganismV3: NSManagedObject, OrganismProtocol { - - @NSManaged var dna: Int64 - @NSManaged var hasHead: Bool - @NSManaged var hasTail: Bool - @NSManaged var numberOfLimbs: Int32 - @NSManaged var hasVertebrae: Bool - - // MARK: OrganismProtocol - - func mutate() { - - self.hasHead = arc4random_uniform(2) == 1 - self.hasTail = arc4random_uniform(2) == 1 - self.numberOfLimbs = Int32(arc4random_uniform(9) / 2 * 2) - self.hasVertebrae = arc4random_uniform(2) == 1 - } -} diff --git a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3ToV2.xcmappingmodel/xcmapping.xml b/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3ToV2.xcmappingmodel/xcmapping.xml deleted file mode 100644 index 2798a07..0000000 --- a/LegacyDemo/LegacyDemo/MIgrations Demo/OrganismV3ToV2.xcmappingmodel/xcmapping.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - 134481920 - 8160C973-F2E8-4296-AC28-7329092D6700 - 107 - - - - NSPersistenceFrameworkVersion - 754 - NSStoreModelVersionHashes - - XDDevAttributeMapping - - 0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc= - - XDDevEntityMapping - - qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI= - - XDDevMappingModel - - EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ= - - XDDevPropertyMapping - - XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA= - - XDDevRelationshipMapping - - akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs= - - - NSStoreModelVersionHashesVersion - 3 - NSStoreModelVersionIdentifiers - - - - - - - - - CoreStoreDemo/MigrationDemo.xcdatamodeld/MigrationDemoV3.xcdatamodel - YnBsaXN0MDDUAAEAAgADAAQABQAGB+QH5VgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv -cBIAAYagrxDFAAcACAAXADMANAA1AD0APgBZAFoAWwBhAGIAbgCCAIMAhACFAIYAhwCIAIkAigCjAKYArQCzAMIA0QDgAOMAWADzAQIBBgEKARkBHwEgASgBNwE4AUEBTwFQAVEBUgFTAVQBaQFqAXIBcwF0AYABlAGVAZYBlwGYAZkBmgGbAZwBqwG6AckBzQHcAesB+gIJAhgCJAI2AjcCOAI5AjoCOwI8Aj0CTAJNAlwCawJ6AnsCigKZAqgCsALFAsYCzgLaAu4C/QMMAxsDHwMuAz0DTANbA2oDdgOIA5cDpgO1A8QDxQPUA+MD8gQHBAgEEAQcBDAEPwROBF0EYQRwBH8EgASPBJ4ErQS5BMsE2gTpBPgFBwUIBRcFJgU1BUoFSwVTBV8FcwWCBZEFoAWkBbMFwgXRBeAF7wX7Bg0GHAYrBjoGSQZYBmcGdgaLBowGlAagBrQGwwbSBuEG5Qb0BwMHEgchBzAHPAdOB10HbAd7B4oHmQeoB7cHuAe7B8QHyAfMB9AH2AfbB98H4FUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAEwAWXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoACgMSAwYAAgMKAAIDD3gAYABkAGgAbABwAHQAeAAoAHwAgACEAIgAjACQAJQAmACcAKAAlABMAKwAsAC0ALgAvACUAJQATXxAcWERCdWNrZXRGb3JDbGFzc2Vzd2FzRW5jb2RlZF8QGlhEQnVja2V0Rm9yUGFja2FnZXNzdG9yYWdlXxAcWERCdWNrZXRGb3JJbnRlcmZhY2Vzc3RvcmFnZV8QD194ZF9vd25pbmdNb2RlbF8QHVhEQnVja2V0Rm9yUGFja2FnZXN3YXNFbmNvZGVkVl9vd25lcl8QG1hEQnVja2V0Rm9yRGF0YVR5cGVzc3RvcmFnZVtfdmlzaWJpbGl0eV8QGVhEQnVja2V0Rm9yQ2xhc3Nlc3N0b3JhZ2VVX25hbWVfEB9YREJ1Y2tldEZvckludGVyZmFjZXN3YXNFbmNvZGVkXxAeWERCdWNrZXRGb3JEYXRhVHlwZXN3YXNFbmNvZGVkXxAQX3VuaXF1ZUVsZW1lbnRJRIAEgL+AvYABgASAAIC+gMAQAIAFgAOABIAEgABQU1lFU9MANgA3AAoAOAA6ADxXTlMua2V5c1pOUy5vYmplY3RzoQA5gAahADuAB4AiWE9yZ2FuaXNt3xAQAD8AQABBAEIAHQBDAEQAHwBFAEYACgAhAEcASAAkAEkASgBLACUAJQAQAE8AUAAtACUASgBTADkASgBWAFcAWF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzc3RvcmFnZV8QIFhEQnVja2V0Rm9yU3RlcmVvdHlwZXN3YXNFbmNvZGVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc3N0b3JhZ2VfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc2R1cGxpY2F0ZXNfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zc3RvcmFnZVtfaXNBYnN0cmFjdIAJgCqABIAEgAKACoC6gASACYC8gAaACYC7gAgIEpznnxdXb3JkZXJlZNMANgA3AAoAXABeADyhAF2AC6EAX4AMgCJeWERfUFN0ZXJlb3R5cGXZAB0AIQBjAAoAJABkAB8ASQBlADsAXQBKAGkAEwAlAC0AWABtXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlgAeAC4AJgCmAAIAECIAN0wA2ADcACgBvAHgAPKgAcABxAHIAcwB0AHUAdgB3gA6AD4AQgBGAEoATgBSAFagAeQB6AHsAfAB9AH4AfwCAgBaAGoAbgByAHoAggCOAJ4AiXxATWERQTUNv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bXDSADcACgfZAKWggBjTADYANwAKB9wH3QA8oKCAIlDSAKcAqAfhB+JZWERQTU1vZGVsowfhB+MArFdYRE1vZGVsXxAPTlNLZXllZEFyY2hpdmVy0QfmAChUcm9vdIABAAgAGQAiACsANQA6AD8BzAHSAe8CAQIIAhUCKAJAAk4CaAJqAmwCbgJwAnICdAJ2Aq8CzgLrAwoDHAM8A0MDYQNtA4kDjwOxA9ID5QPnA+kD6wPtA+8D8QPzA/UD9wP5A/sD/QP/BAEEAgQGBBMEGwQmBCkEKwQuBDAEMgQ7BH4EogTGBOkFEAUwBVcFfgWeBcIF5gXyBfQF9gX4BfoF/AX+BgAGAgYEBgYGCAYKBgwGDgYPBhQGHAYpBiwGLgYxBjMGNQZEBmkGjQa0BtgG2gbcBt4G4AbiBuQG5QbnBvQHBQcHBwkHCwcNBw8HEQcTBxUHJgcoByoHLAcuBzAHMgc0BzYHOAdOB2EHfgeaB64HwAfWB+8ILgg0CD0ISghWCGAIagh1CIAIjQiVCJcImQibCJ0IngifCKAIoQijCKUIpginCKkIqgizCLQItgi/CMoI0wjiCOkI8Qj6CQMJFgkfCTIJSQlbCZoJnAmeCaAJogmjCaQJpQmmCagJqgmrCawJrgmvCe4J8AnyCfQJ9gn3CfgJ+Qn6CfwJ/gn/CgAKAgoDCkIKRApGCkgKSgpLCkwKTQpOClAKUgpTClQKVgpXCmAKYQpjCqIKpAqmCqgKqgqrCqwKrQquCrAKsgqzCrQKtgq3CrgK9wr5CvsK/Qr/CwALAQsCCwMLBQsHCwgLCQsLCwwLGQsaCxsLHQsmCzwLQwtQC48LkQuTC5ULlwuYC5kLmgubC50LnwugC6ELowukC70LvwvBC8MLxAvGC90L5gv0DAEMDwwkDDgMTwxhDKAMogykDKYMqAypDKoMqwysDK4MsAyxDLIMtAy1DNAM2QzuDP0NEg0gDTUNSQ1gDXINfw2KDYwNjg2QDZINlA2fDaENow2lDacNqQ2rDbkNxg3KDdIN2g4lDkgOaA6IDooOjA6ODpAOkg6TDpQOlg6XDpkOmg6cDp4Onw6gDqIOow6oDrUOug68Dr4Oww7FDscOyQ7eDvMPGA88D2MPhw+JD4sPjQ+PD5EPkw+UD5YPow+0D7YPuA+6D7wPvg/AD8IPxA/VD9cP2Q/bD90P3w/hD+MP5Q/nEAUQIxA2EEoQXxB8EJAQphDlEOcQ6RDrEO0Q7hDvEPAQ8RDzEPUQ9hD3EPkQ+hE5ETsRPRE/EUERQhFDEUQRRRFHEUkRShFLEU0RThGNEY8RkRGTEZURlhGXEZgRmRGbEZ0RnhGfEaERohGvEbARsRGzEfIR9BH2EfgR+hH7EfwR/RH+EgASAhIDEgQSBhIHEkYSSBJKEkwSThJPElASURJSElQSVhJXElgSWhJbEpoSnBKeEqASohKjEqQSpRKmEqgSqhKrEqwSrhKvEu4S8BLyEvQS9hL3EvgS+RL6EvwS/hL/EwATAhMDE0ITRBNGE0gTShNLE0wTTRNOE1ATUhNTE1QTVhNXE3wToBPHE+sT7RPvE/ET8xP1E/cT+BP6FAcUFhQYFBoUHBQeFCAUIhQkFDMUNRQ3FDkUOxQ9FD8UQRRDFGMUjhSoFMEU2xT7FR4VXRVfFWEVYxVlFWYVZxVoFWkVaxVtFW4VbxVxFXIVdBWzFbUVtxW5FbsVvBW9Fb4VvxXBFcMVxBXFFccVyBYHFgkWCxYNFg8WEBYRFhIWExYVFhcWGBYZFhsWHBZbFl0WXxZhFmMWZBZlFmYWZxZpFmsWbBZtFm8WcBZyFrEWsxa1FrcWuRa6FrsWvBa9Fr8WwRbCFsMWxRbGFwUXBxcJFwsXDRcOFw8XEBcRFxMXFRcWFxcXGRcaF1kXWxddF18XYRdiF2MXZBdlF2cXaRdqF2sXbRduF3cXhReSF6AXrRfAF9cX6Rg0GFcYdxiXGJkYmxidGJ8YoRiiGKMYpRimGKgYqRirGK0YrhivGLEYshi3GMQYyRjLGM0Y0hjUGNYY2Bj9GSEZSBlsGW4ZcBlyGXQZdhl4GXkZexmIGZkZmxmdGZ8ZoRmjGaUZpxmpGboZvBm+GcAZwhnEGcYZyBnKGcwaCxoNGg8aERoTGhQaFRoWGhcaGRobGhwaHRofGiAaXxphGmMaZRpnGmgaaRpqGmsabRpvGnAacRpzGnQasxq1GrcauRq7GrwavRq+Gr8awRrDGsQaxRrHGsga1RrWGtca2RsYGxobHBseGyAbIRsiGyMbJBsmGygbKRsqGywbLRtsG24bcBtyG3QbdRt2G3cbeBt6G3wbfRt+G4AbgRvAG8IbxBvGG8gbyRvKG8sbzBvOG9Ab0RvSG9Qb1RwUHBYcGBwaHBwcHRweHB8cIBwiHCQcJRwmHCgcKRxoHGocbBxuHHAccRxyHHMcdBx2HHgceRx6HHwcfRyiHMYc7R0RHRMdFR0XHRkdGx0dHR4dIB0tHTwdPh1AHUIdRB1GHUgdSh1ZHVsdXR1fHWEdYx1lHWcdaR2oHaodrB2uHbAdsR2yHbMdtB22HbgduR26HbwdvR38Hf4eAB4CHgQeBR4GHgceCB4KHgweDR4OHhAeER5QHlIeVB5WHlgeWR5aHlseXB5eHmAeYR5iHmQeZR6kHqYeqB6qHqwerR6uHq8esB6yHrQetR62HrgeuR68Hvse/R7/HwEfAx8EHwUfBh8HHwkfCx8MHw0fDx8QH08fUR9TH1UfVx9YH1kfWh9bH10fXx9gH2EfYx9kH6MfpR+nH6kfqx+sH60frh+vH7Efsx+0H7Uftx+4IAMgJiBGIGYgaCBqIGwgbiBwIHEgciB0IHUgdyB4IHogfCB9IH4ggCCBIIYgkyCYIJognCChIKMgpSCnIMwg8CEXITshPSE/IUEhQyFFIUchSCFKIVchaCFqIWwhbiFwIXIhdCF2IXghiSGLIY0hjyGRIZMhlSGXIZkhmyHaIdwh3iHgIeIh4yHkIeUh5iHoIeoh6yHsIe4h7yIuIjAiMiI0IjYiNyI4IjkiOiI8Ij4iPyJAIkIiQyKCIoQihiKIIooiiyKMIo0ijiKQIpIikyKUIpYilyKkIqUipiKoIuci6SLrIu0i7yLwIvEi8iLzIvUi9yL4Ivki+yL8IzsjPSM/I0EjQyNEI0UjRiNHI0kjSyNMI00jTyNQI1EjkCOSI5QjliOYI5kjmiObI5wjniOgI6EjoiOkI6Uj5CPmI+gj6iPsI+0j7iPvI/Aj8iP0I/Uj9iP4I/kkOCQ6JDwkPiRAJEEkQiRDJEQkRiRIJEkkSiRMJE0kciSWJL0k4STjJOUk5yTpJOsk7STuJPAk/SUMJQ4lECUSJRQlFiUYJRolKSUrJS0lLyUxJTMlNSU3JTkleCV6JXwlfiWAJYElgiWDJYQlhiWIJYkliiWMJY0lzCXOJdAl0iXUJdUl1iXXJdgl2iXcJd0l3iXgJeEmICYiJiQmJiYoJikmKiYrJiwmLiYwJjEmMiY0JjUmdCZ2JngmeiZ8Jn0mfiZ/JoAmgiaEJoUmhiaIJokmjCbLJs0mzybRJtMm1CbVJtYm1ybZJtsm3CbdJt8m4CcfJyEnIyclJycnKCcpJyonKyctJy8nMCcxJzMnNCdzJ3Undyd5J3snfCd9J34nfyeBJ4MnhCeFJ4cniCfTJ/YoFig2KDgoOig8KD4oQChBKEIoRChFKEcoSChKKEwoTShOKFAoUShWKGMoaChqKGwocShzKHUodyicKMAo5ykLKQ0pDykRKRMpFSkXKRgpGiknKTgpOik8KT4pQClCKUQpRilIKVkpWyldKV8pYSljKWUpZylpKWspqimsKa4psCmyKbMptCm1KbYpuCm6KbspvCm+Kb8p/ioAKgIqBCoGKgcqCCoJKgoqDCoOKg8qECoSKhMqUipUKlYqWCpaKlsqXCpdKl4qYCpiKmMqZCpmKmcqdCp1KnYqeCq3Krkquyq9Kr8qwCrBKsIqwyrFKscqyCrJKssqzCsLKw0rDysRKxMrFCsVKxYrFysZKxsrHCsdKx8rICtfK2ErYytlK2craCtpK2orayttK28rcCtxK3MrdCuzK7Urtyu5K7srvCu9K74rvyvBK8MrxCvFK8cryCwHLAksCywNLA8sECwRLBIsEywVLBcsGCwZLBssHCxBLGUsjCywLLIstCy2LLgsuiy8LL0svyzMLNss3SzfLOEs4yzlLOcs6Sz4LPos/Cz+LQAtAi0ELQYtCC1HLUktSy1NLU8tUC1RLVItUy1VLVctWC1ZLVstXC2bLZ0tny2hLaMtpC2lLaYtpy2pLastrC2tLa8tsC3vLfEt8y31Lfct+C35Lfot+y39Lf8uAC4BLgMuBC5DLkUuRy5JLksuTC5NLk4uTy5RLlMuVC5VLlcuWC6XLpkumy6dLp8uoC6hLqIuoy6lLqcuqC6pLqsurC7rLu0u7y7xLvMu9C71LvYu9y75Lvsu/C79Lv8vAC8/L0EvQy9FL0cvSC9JL0ovSy9NL08vUC9RL1MvVC+fL8Iv4jACMAQwBjAIMAowDDANMA4wEDARMBMwFDAWMBgwGTAaMBwwHTAiMC8wNDA2MDgwPTA/MEEwQzBoMIwwszDXMNkw2zDdMN8w4TDjMOQw5jDzMQQxBjEIMQoxDDEOMRAxEjEUMSUxJzEpMSsxLTEvMTExMzE1MTcxdjF4MXoxfDF+MX8xgDGBMYIxhDGGMYcxiDGKMYsxyjHMMc4x0DHSMdMx1DHVMdYx2DHaMdsx3DHeMd8yHjIgMiIyJDImMicyKDIpMioyLDIuMi8yMDIyMjMyQDJBMkIyRDKDMoUyhzKJMosyjDKNMo4yjzKRMpMylDKVMpcymDLXMtky2zLdMt8y4DLhMuIy4zLlMucy6DLpMusy7DMrMy0zLzMxMzMzNDM1MzYzNzM5MzszPDM9Mz8zQDN/M4EzgzOFM4cziDOJM4ozizONM48zkDORM5MzlDPTM9Uz1zPZM9sz3DPdM94z3zPhM+Mz5DPlM+cz6DQNNDE0WDR8NH40gDSCNIQ0hjSINIk0izSYNKc0qTSrNK00rzSxNLM0tTTENMY0yDTKNMw0zjTQNNI01DUTNRU1FzUZNRs1HDUdNR41HzUhNSM1JDUlNSc1KDVnNWk1azVtNW81cDVxNXI1czV1NXc1eDV5NXs1fDW7Nb01vzXBNcM1xDXFNcY1xzXJNcs1zDXNNc810DYPNhE2EzYVNhc2GDYZNho2GzYdNh82IDYhNiM2JDZjNmU2ZzZpNms2bDZtNm42bzZxNnM2dDZ1Nnc2eDa3Nrk2uza9Nr82wDbBNsI2wzbFNsc2yDbJNss2zDcLNw03DzcRNxM3FDcVNxY3FzcZNxs3HDcdNx83IDcrNzQ3NTc3N0A3SzdaN2U3czeIN5w3szfFN9I30zfUN9Y34zfkN+U35zf0N/U39jf4OAE4EDgdOCw4PjhSOGk4eziEOIU4hziUOJU4ljiYOJk4ojisOLM4uzjNONI41wAAAAAAAAICAAAAAAAAB+gAAAAAAAAAAAAAAAAAADjZ - - CoreStoreDemo/MigrationDemo.xcdatamodeld/MigrationDemoV2.xcdatamodel - YnBsaXN0MDDUAAEAAgADAAQABQAGBqAGoVgkdmVyc2lvblgkb2JqZWN0c1kkYXJjaGl2ZXJUJHRv -cBIAAYagrxCtAAcACAAXADMANAA1AD0APgBZAFoAWwBhAGIAbgCCAIMAhACFAIYAhwCIAIkAigCjAKYArQCzAMIA0QDgAOMAWADzAQIBBgEKARkBHwEgASgBNwE4AUEBTQFOAU8BUAFRAWYBZwFvAXABcQF9AZEBkgGTAZQBlQGWAZcBmAGZAagBtwHGAcoB2QHoAekB+AIHAhYCIgI0AjUCNgI3AjgCOQI6AjsCSgJLAloCaQJ4AnkCiAKXAqYCrgLDAsQCzALYAuwC+wMKAxkDHQMsAzsDSgNZA2gDdAOGA5UDpAOzA8IDwwPSA+ED8AQFBAYEDgQaBC4EPQRMBFsEXwRuBH0EjASbBKoEtgTIBNcE5gT1BQQFBQUUBSMFMgVHBUgFUAVcBXAFfwWOBZ0FoQWwBb8FzgXdBewF+AYKBhkGKAY3BkYGVQZkBnMGdAZ3BoAGhAaIBowGlAaXBpsGnFUkbnVsbNcACQAKAAsADAANAA4ADwAQABEAEgATABQAEwAWXxAPX3hkX3Jvb3RQYWNrYWdlViRjbGFzc1xfeGRfY29tbWVudHNfEBBfeGRfbW9kZWxNYW5hZ2VyXxAVX2NvbmZpZ3VyYXRpb25zQnlOYW1lXV94ZF9tb2RlbE5hbWVfEBdfbW9kZWxWZXJzaW9uSWRlbnRpZmllcoACgKyAqYAAgKqAAICr3gAYABkAGgAbABwAHQAeAAoAHwAgACEAIgAjACQAJQAmACcAKAAlABMAKwAsAC0ALgAvACUAJQATXxAcWERCdWNrZXRGb3JDbGFzc2Vzd2FzRW5jb2RlZF8QGlhEQnVja2V0Rm9yUGFja2FnZXNzdG9yYWdlXxAcWERCdWNrZXRGb3JJbnRlcmZhY2Vzc3RvcmFnZV8QD194ZF9vd25pbmdNb2RlbF8QHVhEQnVja2V0Rm9yUGFja2FnZXN3YXNFbmNvZGVkVl9vd25lcl8QG1hEQnVja2V0Rm9yRGF0YVR5cGVzc3RvcmFnZVtfdmlzaWJpbGl0eV8QGVhEQnVja2V0Rm9yQ2xhc3Nlc3N0b3JhZ2VVX25hbWVfEB9YREJ1Y2tldEZvckludGVyZmFjZXN3YXNFbmNvZGVkXxAeWERCdWNrZXRGb3JEYXRhVHlwZXN3YXNFbmNvZGVkXxAQX3VuaXF1ZUVsZW1lbnRJRIAEgKeApYABgASAAICmgKgQAIAFgAOABIAEgABQU1lFU9MANgA3AAoAOAA6ADxXTlMua2V5c1pOUy5vYmplY3RzoQA5gAahADuAB4AiWE9yZ2FuaXNt3xAQAD8AQABBAEIAHQBDAEQAHwBFAEYACgAhAEcASAAkAEkASgBLACUAJQAQAE8AUAAtACUASgBTADkASgBWAFcAWF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzc3RvcmFnZV8QIFhEQnVja2V0Rm9yU3RlcmVvdHlwZXN3YXNFbmNvZGVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc3N0b3JhZ2VfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc2R1cGxpY2F0ZXNfECRYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zb3JkZXJlZF8QIVhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zc3RvcmFnZVtfaXNBYnN0cmFjdIAJgCqABIAEgAKACoCigASACYCkgAaACYCjgAgIEox4F8pXb3JkZXJlZNMANgA3AAoAXABeADyhAF2AC6EAX4AMgCJeWERfUFN0ZXJlb3R5cGXZAB0AIQBjAAoAJABkAB8ASQBlADsAXQBKAGkAEwAlAC0AWABtXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAkWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXN3YXNFbmNvZGVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlgAeAC4AJgCmAAIAECIAN0wA2ADcACgBvAHgAPKgAcABxAHIAcwB0AHUAdgB3gA6AD4AQgBGAEoATgBSAFagAeQB6AHsAfAB9AH4AfwCAgBaAGoAbgByAHoAggCOAJ4AiXxATWERQTUNvbXBvdW5kSW5kZXhlc18QEFhEX1BTS19lbGVtZW50SURfEBpYRF9QU0tfdmVyc2lv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ExMTFBMVExcTGBM9E2ETiBOsE64TsBOyE7QTthO4E7kTuxPIE9cT2RPbE90T3xPhE+MT5RP0E/YT+BP6E/wT/hQAFAIUBBQkFE8UaRSCFJwUvBTfFR4VIBUiFSQVJhUnFSgVKRUqFSwVLhUvFTAVMhUzFTUVdBV2FXgVehV8FX0VfhV/FYAVghWEFYUVhhWIFYkVyBXKFcwVzhXQFdEV0hXTFdQV1hXYFdkV2hXcFd0WHBYeFiAWIhYkFiUWJhYnFigWKhYsFi0WLhYwFjEWNBZzFnUWdxZ5FnsWfBZ9Fn4WfxaBFoMWhBaFFocWiBbHFskWyxbNFs8W0BbRFtIW0xbVFtcW2BbZFtsW3BcbFx0XHxchFyMXJBclFyYXJxcpFysXLBctFy8XMBc5F0cXVBdiF28XgheZF6sX9hgZGDkYWRhbGF0YXxhhGGMYZBhlGGcYaBhqGGsYbRhvGHAYcRhzGHQYeRiGGIsYjRiPGJQYlhiYGJoYvxjjGQoZLhkwGTIZNBk2GTgZOhk7GT0ZShlbGV0ZXxlhGWMZZRlnGWkZaxl8GX4ZgBmCGYQZhhmIGYoZjBmOGc0ZzxnRGdMZ1RnWGdcZ2BnZGdsZ3RneGd8Z4RniGiEaIxolGicaKRoqGisaLBotGi8aMRoyGjMaNRo2GnUadxp5GnsafRp+Gn8agBqBGoMahRqGGocaiRqKGpcamBqZGpsa2hrcGt4a4BriGuMa5BrlGuYa6BrqGusa7BruGu8bLhswGzIbNBs2GzcbOBs5GzobPBs+Gz8bQBtCG0MbghuEG4YbiBuKG4sbjBuNG44bkBuSG5MblBuWG5cb1hvYG9ob3BveG98b4BvhG+Ib5BvmG+cb6BvqG+scKhwsHC4cMBwyHDMcNBw1HDYcOBw6HDscPBw+HD8cZByIHK8c0xzVHNcc2RzbHN0c3xzgHOIc7xz+HQAdAh0EHQYdCB0KHQwdGx0dHR8dIR0jHSUdJx0pHSsdah1sHW4dcB1yHXMddB11HXYdeB16HXsdfB1+HX8dvh3AHcIdxB3GHccdyB3JHcodzB3OHc8d0B3SHdMeEh4UHhYeGB4aHhseHB4dHh4eIB4iHiMeJB4mHiceZh5oHmoebB5uHm8ecB5xHnIedB52HnceeB56Hnsefh69Hr8ewR7DHsUexh7HHsgeyR7LHs0ezh7PHtEe0h8RHxMfFR8XHxkfGh8bHxwfHR8fHyEfIh8jHyUfJh9lH2cfaR9rH20fbh9vH3AfcR9zH3Ufdh93H3kfeh/FH+ggCCAoICogLCAuIDAgMiAzIDQgNiA3IDkgOiA8ID4gPyBAIEIgQyBMIFkgXiBgIGIgZyBpIGsgbSCSILYg3SEBIQMhBSEHIQkhCyENIQ4hECEdIS4hMCEyITQhNiE4ITohPCE+IU8hUSFTIVUhVyFZIVshXSFfIWEhoCGiIaQhpiGoIakhqiGrIawhriGwIbEhsiG0IbUh9CH2Ifgh+iH8If0h/iH/IgAiAiIEIgUiBiIIIgkiSCJKIkwiTiJQIlEiUiJTIlQiViJYIlkiWiJcIl0iaiJrImwibiKtIq8isSKzIrUitiK3IrgiuSK7Ir0iviK/IsEiwiMBIwMjBSMHIwkjCiMLIwwjDSMPIxEjEiMTIxUjFiNVI1cjWSNbI10jXiNfI2AjYSNjI2UjZiNnI2kjaiOpI6sjrSOvI7EjsiOzI7QjtSO3I7kjuiO7I70jviP9I/8kASQDJAUkBiQHJAgkCSQLJA0kDiQPJBEkEiQ3JFskgiSmJKgkqiSsJK4ksCSyJLMktSTCJNEk0yTVJNck2STbJN0k3yTuJPAk8iT0JPYk+CT6JPwk/iU9JT8lQSVDJUUlRiVHJUglSSVLJU0lTiVPJVElUiWRJZMllSWXJZklmiWbJZwlnSWfJaEloiWjJaUlpiXlJecl6SXrJe0l7iXvJfAl8SXzJfUl9iX3Jfkl+iY5JjsmPSY/JkEmQiZDJkQmRSZHJkkmSiZLJk0mTiZQJo8mkSaTJpUmlyaYJpkmmiabJp0mnyagJqEmoyakJuMm5SbnJukm6ybsJu0m7ibvJvEm8yb0JvUm9yb4JzcnOSc7Jz0nPydAJ0EnQidDJ0UnRydIJ0knSydMJ5cnuifaJ/on/Cf+KAAoAigEKAUoBigIKAkoCygMKA4oECgRKBIoFCgVKBooJygsKC4oMCg1KDcoOSg7KGAohCirKM8o0SjTKNUo1yjZKNso3CjeKOso/Cj+KQApAikEKQYpCCkKKQwpHSkfKSEpIyklKScpKSkrKS0pLyluKXApcil0KXYpdyl4KXkpeil8KX4pfymAKYIpgynCKcQpxinIKcopyynMKc0pzinQKdIp0ynUKdYp1yoWKhgqGiocKh4qHyogKiEqIiokKiYqJyooKioqKyo4KjkqOio8KnsqfSp/KoEqgyqEKoUqhiqHKokqiyqMKo0qjyqQKs8q0SrTKtUq1yrYKtkq2irbKt0q3yrgKuEq4yrkKyMrJSsnKykrKyssKy0rLisvKzErMys0KzUrNys4K3creSt7K30rfyuAK4ErgiuDK4UrhyuIK4kriyuMK8srzSvPK9Er0yvUK9Ur1ivXK9kr2yvcK90r3yvgLAUsKSxQLHQsdix4LHosfCx+LIAsgSyDLJAsnyyhLKMspSynLKksqyytLLwsvizALMIsxCzGLMgsyizMLQstDS0PLREtEy0ULRUtFi0XLRktGy0cLR0tHy0gLV8tYS1jLWUtZy1oLWktai1rLW0tby1wLXEtcy10LbMttS23Lbktuy28Lb0tvi2/LcEtwy3ELcUtxy3ILgcuCS4LLg0uDy4QLhEuEi4TLhUuFy4YLhkuGy4cLlsuXS5fLmEuYy5kLmUuZi5nLmkuay5sLm0uby5wLq8usS6zLrUuty64Lrkuui67Lr0uvy7ALsEuwy7ELwMvBS8HLwkvCy8MLw0vDi8PLxEvEy8ULxUvFy8YLyMvLC8tLy8vOC9DL1IvXS9rL4AvlC+rL70vyi/LL8wvzi/bL9wv3S/fL+wv7S/uL/Av+TAIMBUwJDA2MEowYTBzMHwwfTB/MIwwjTCOMJAwkTCaMKQwqzCzMMUwyjDPAAAAAAAAAgIAAAAAAAAGpAAAAAAAAAAAAAAAAAAAMNE= - - - - - Organism - Undefined - 1 - Organism - 1 - - - - - - YnBsaXN0MDDUAQIDBAUGPD1YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoKwH -CBMUGRoiJywtMjZVJG51bGzVCQoLDA0ODxAREllOU09wZXJhbmReTlNTZWxlY3Rvck5hbWVfEBBOU0V4cHJlc3Npb25UeXBlW05TQXJndW1lbnRzViRjbGFzc4ADgAIQBIAGgAtfEBB2YWx1ZUZvcktleVBhdGg60xULDRYXGFpOU1ZhcmlhYmxlgAQQAoAFVnNvdXJjZdIbHB0eWiRjbGFzc25hbWVYJGNsYXNzZXNfEBROU1ZhcmlhYmxlRXhwcmVzc2lvbqMfICFfEBROU1ZhcmlhYmxlRXhwcmVzc2lvblxOU0V4cHJlc3Npb25YTlNPYmplY3TSIw0kJlpOUy5vYmplY3RzoSWAB4AK0w0LKCkqK1lOU0tleVBhdGiACRAKgAhdbnVtYmVyT2ZMaW1ic9IbHC4vXxAcTlNLZXlQYXRoU3BlY2lmaWVyRXhwcmVzc2lvbqMwMSFfEBxOU0tleVBhdGhTcGVjaWZpZXJFeHByZXNzaW9uXE5TRXhwcmVzc2lvbtIbHDM0Xk5TTXV0YWJsZUFycmF5ozM1IVdOU0FycmF50hscNzhfEBNOU0tleVBhdGhFeHByZXNzaW9upDk6OyFfEBNOU0tleVBhdGhFeHByZXNzaW9uXxAUTlNGdW5jdGlvbkV4cHJlc3Npb25cTlNFeHByZXNzaW9uXxAPTlNLZXllZEFyY2hpdmVy0T4/VHJvb3SAAQAIABEAGgAjAC0AMgA3AEQASgBVAF8AbgCBAI0AlACWAJgAmgCcAJ4AsQC4AMMAxQDHAMkA0ADVAOAA6QEAAQQBGwEoATEBNgFBAUMBRQFHAU4BWAFaAVwBXgFsAXEBkAGUAbMBwAHFAdQB2AHgAeUB+wIAAhYCLQI6AkwCTwJUAAAAAAAAAgEAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAlY= - - numberOfFlippers - - - - hasTail - - - - hasHead - - - - dna - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/.xccurrentversion b/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/.xccurrentversion deleted file mode 100644 index d85ac4a..0000000 --- a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/.xccurrentversion +++ /dev/null @@ -1,8 +0,0 @@ - - - - - _XCCurrentVersionName - MigrationDemoV3.xcdatamodel - - diff --git a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemo.xcdatamodel/contents b/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemo.xcdatamodel/contents deleted file mode 100644 index 9063bad..0000000 --- a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemo.xcdatamodel/contents +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV2.xcdatamodel/contents b/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV2.xcdatamodel/contents deleted file mode 100644 index 3a252de..0000000 --- a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV2.xcdatamodel/contents +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV3.xcdatamodel/contents b/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV3.xcdatamodel/contents deleted file mode 100644 index 1d684b5..0000000 --- a/LegacyDemo/LegacyDemo/MigrationDemo.xcdatamodeld/MigrationDemoV3.xcdatamodel/contents +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/Stack Setup Demo/FemaleAccount.swift b/LegacyDemo/LegacyDemo/Stack Setup Demo/FemaleAccount.swift deleted file mode 100644 index e370d49..0000000 --- a/LegacyDemo/LegacyDemo/Stack Setup Demo/FemaleAccount.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// FemaleAccount.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/06. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData - -class FemaleAccount: UserAccount { - - -} diff --git a/LegacyDemo/LegacyDemo/Stack Setup Demo/MaleAccount.swift b/LegacyDemo/LegacyDemo/Stack Setup Demo/MaleAccount.swift deleted file mode 100644 index faba9ba..0000000 --- a/LegacyDemo/LegacyDemo/Stack Setup Demo/MaleAccount.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// MaleAccount.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/06/06. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData - -class MaleAccount: UserAccount { - - -} diff --git a/LegacyDemo/LegacyDemo/Stack Setup Demo/StackSetupDemoViewController.swift b/LegacyDemo/LegacyDemo/Stack Setup Demo/StackSetupDemoViewController.swift deleted file mode 100644 index d2422b5..0000000 --- a/LegacyDemo/LegacyDemo/Stack Setup Demo/StackSetupDemoViewController.swift +++ /dev/null @@ -1,196 +0,0 @@ -// -// StackSetupDemoViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/24. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - - -private struct Static { - - static let maleConfiguration = "MaleAccounts" - static let femaleConfiguration = "FemaleAccounts" - - static let facebookStack: DataStack = { - - let dataStack = DataStack(xcodeModelName: "StackSetupDemo") - try! dataStack.addStorageAndWait( - SQLiteStore( - fileName: "AccountsDemo_FB_Male.sqlite", - configuration: maleConfiguration, - localStorageOptions: .recreateStoreOnModelMismatch - ) - ) - try! dataStack.addStorageAndWait( - SQLiteStore( - fileName: "AccountsDemo_FB_Female.sqlite", - configuration: femaleConfiguration, - localStorageOptions: .recreateStoreOnModelMismatch - ) - ) - - _ = try? dataStack.perform( - synchronous: { (transaction) in - - try transaction.deleteAll(From()) - - let account1 = transaction.create(Into(maleConfiguration)) - account1.accountType = "Facebook" - account1.name = "John Smith HCD" - account1.friends = 42 - - let account2 = transaction.create(Into(femaleConfiguration)) - account2.accountType = "Facebook" - account2.name = "Jane Doe HCD" - account2.friends = 314 - } - ) - - return dataStack - }() - - static let twitterStack: DataStack = { - - let dataStack = DataStack(xcodeModelName: "StackSetupDemo") - try! dataStack.addStorageAndWait( - SQLiteStore( - fileName: "AccountsDemo_TW_Male.sqlite", - configuration: maleConfiguration, - localStorageOptions: .recreateStoreOnModelMismatch - ) - ) - try! dataStack.addStorageAndWait( - SQLiteStore( - fileName: "AccountsDemo_TW_Female.sqlite", - configuration: femaleConfiguration, - localStorageOptions: .recreateStoreOnModelMismatch - ) - ) - - _ = try? dataStack.perform( - synchronous: { (transaction) in - - try transaction.deleteAll(From()) - - let account1 = transaction.create(Into(maleConfiguration)) - account1.accountType = "Twitter" - account1.name = "#johnsmith_hcd" - account1.friends = 7 - - let account2 = transaction.create(Into(femaleConfiguration)) - account2.accountType = "Twitter" - account2.name = "#janedoe_hcd" - account2.friends = 100 - } - ) - return dataStack - }() -} - - - - -// MARK: - StackSetupDemoViewController - -class StackSetupDemoViewController: UITableViewController { - - let accounts = [ - try! Static.facebookStack.fetchAll(From()), - try! Static.twitterStack.fetchAll(From()) - ] - - - // MARK: UIViewController - - override func viewWillAppear(_ animated: Bool) { - - super.viewWillAppear(animated) - - self.tableView.reloadData() - - let indexPath = IndexPath(row: 0, section: 0) - self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none) - self.updateDetails(account: self.accounts[indexPath.section][indexPath.row]) - } - - override func viewDidAppear(_ animated: Bool) { - - super.viewDidAppear(animated) - - let alert = UIAlertController( - title: "Setup Demo", - message: "This demo shows how to initialize 2 DataStacks with 2 configurations each, for a total of 4 SQLite files, each with 1 instance of a \"UserAccount\" entity.", - preferredStyle: .alert - ) - alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - } - - - // MARK: UITableViewDataSource - - override func numberOfSections(in tableView: UITableView) -> Int { - - return self.accounts.count - } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - - return self.accounts[section].count - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - - let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")! - - let account = self.accounts[indexPath.section][indexPath.row] - cell.textLabel?.text = account.name - cell.detailTextLabel?.text = "\(account.friends) friends" - - return cell - } - - - // MARK: UITableViewDelegate - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - - let account = self.accounts[indexPath.section][indexPath.row] - self.updateDetails(account: account) - } - - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - - switch section { - - case 0: - let count = self.accounts[section].count - return "Facebook Accounts (\(count) users)" - - case 1: - let count = self.accounts[section].count - return "Twitter Accounts (\(count) users)" - - default: - return nil - } - } - - - // MARK: Private - - @IBOutlet private dynamic weak var accountTypeLabel: UILabel? - @IBOutlet private dynamic weak var nameLabel: UILabel? - @IBOutlet private dynamic weak var friendsLabel: UILabel? - - private func updateDetails(account: UserAccount) { - - self.accountTypeLabel?.text = account.accountType - self.nameLabel?.text = account.name - self.friendsLabel?.text = "\(account.friends) friends" - } -} diff --git a/LegacyDemo/LegacyDemo/Stack Setup Demo/UserAccount.swift b/LegacyDemo/LegacyDemo/Stack Setup Demo/UserAccount.swift deleted file mode 100644 index b3e1e57..0000000 --- a/LegacyDemo/LegacyDemo/Stack Setup Demo/UserAccount.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// UserAccount.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/24. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData - - -// MARK: - UserAccount - -class UserAccount: NSManagedObject { - - @NSManaged var accountType: String? - @NSManaged var name: String? - @NSManaged var friends: Int32 -} diff --git a/LegacyDemo/LegacyDemo/StackSetupDemo.xcdatamodeld/StackSetupDemo.xcdatamodel/contents b/LegacyDemo/LegacyDemo/StackSetupDemo.xcdatamodeld/StackSetupDemo.xcdatamodel/contents deleted file mode 100644 index 71bef7a..0000000 --- a/LegacyDemo/LegacyDemo/StackSetupDemo.xcdatamodeld/StackSetupDemo.xcdatamodel/contents +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIContainerViewController.swift b/LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIContainerViewController.swift deleted file mode 100644 index d1c6fe7..0000000 --- a/LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIContainerViewController.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// SwiftUIContainerViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2019/10/02. -// Copyright © 2019 John Rommel Estropia. All rights reserved. -// - -import UIKit -import CoreStore - -#if canImport(SwiftUI) -import SwiftUI - -#endif - -#if canImport(Combine) -import Combine - -#endif - -import Compression -final class SwiftUIContainerViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - - #if canImport(SwiftUI) && canImport(Combine) - - if #available(iOS 13, *) { - - let hostingController = UIHostingController( - rootView: SwiftUIView( - palettes: ColorsDemo.stack.publishList( - From() - .sectionBy(\.$colorName) - .orderBy(.ascending(\.$hue)) - ) - ) - .environment(\.dataStack, ColorsDemo.stack) - ) - self.addChild(hostingController) - - hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - hostingController.view.frame = self.view.bounds.inset(by: self.view.safeAreaInsets) - self.view.addSubview(hostingController.view) - - hostingController.didMove(toParent: self) - } - - #endif - } -} diff --git a/LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIView.swift b/LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIView.swift deleted file mode 100644 index d8e41ab..0000000 --- a/LegacyDemo/LegacyDemo/SwiftUI Demo/SwiftUIView.swift +++ /dev/null @@ -1,183 +0,0 @@ -// -// SwiftUIView.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2019/10/02. -// Copyright © 2019 John Rommel Estropia. All rights reserved. -// - -#if canImport(SwiftUI) && canImport(Combine) -import SwiftUI -import Combine - -import CoreStore - - -@available(iOS 13.0.0, *) -struct SwiftUIView: View { - - @Environment(\.dataStack) - var dataStack: DataStack - - @ObservedObject - var palettes: ListPublisher - - var body: some View { - NavigationView { - List { - ForEach(palettes.snapshot.sectionIDs, id: \.self) { (sectionID) in - Section(header: Text(sectionID)) { - ForEach(self.palettes.snapshot.items(inSectionWithID: sectionID), id: \.self) { palette in - NavigationLink( - destination: DetailView(palette: palette), - label: { ColorCell(palette: palette) } - ) - } - .onDelete { itemIndices in - let objectIDsToDelete = self.palettes.snapshot.itemIDs( - inSectionWithID: sectionID, - atIndices: itemIndices - ) - self.dataStack.perform( - asynchronous: { transaction in - - transaction.delete(objectIDs: objectIDsToDelete) - }, - completion: { _ in } - ) - } - } - } - } - .navigationBarTitle(Text("SwiftUI (\(palettes.snapshot.numberOfItems) objects)")) - .navigationBarItems( - leading: EditButton(), - trailing: HStack { - Button( - action: { - - self.dataStack.perform( - asynchronous: { transaction in - - for palette in try transaction.fetchAll(From()) { - - palette.hue = Palette.randomHue() - palette.colorName = nil - } - }, - completion: { _ in } - ) - }, - label: { - Image(systemName: "goforward") - } - ) - .frame(width: 30) - Button( - action: { - - self.dataStack.perform( - asynchronous: { transaction in - - _ = transaction.create(Into()) - }, - completion: { _ in } - ) - }, - label: { - Image(systemName: "plus") - } - ) - .frame(width: 30) - } - ) - .alert( - isPresented: $needsShowAlert, - content: { - Alert( - title: Text("SwiftUI Binding Demo"), - message: Text("This demo shows how to bind to ListPublisher and to CoreStoreObject when using SwiftUI"), - dismissButton: .cancel(Text("OK")) - ) - } - ) - .onAppear { - - self.needsShowAlert = true - } - } - } - - @State - private var needsShowAlert = false -} - -@available(iOS 13.0.0, *) -struct ColorCell: View { - - @ObservedObject - var palette: ObjectPublisher - - var body: some View { - HStack { - Color(palette.color ?? UIColor.clear) - .cornerRadius(5) - .frame(width: 30, height: 30, alignment: .leading) - Text(palette.colorText ?? "") - } - } -} - -@available(iOS 13.0.0, *) -struct DetailView: View { - - @Environment(\.dataStack) - var dataStack: DataStack - - @ObservedObject - var palette: ObjectPublisher - - @State var hue: Float = 0 - @State var saturation: Float = 0 - @State var brightness: Float = 0 - - init(palette: ObjectPublisher) { - - self.palette = palette - self.hue = Float(palette.hue ?? 0) - self.saturation = palette.saturation ?? 0 - self.brightness = palette.brightness ?? 0 - } - - var body: some View { - ZStack { - Color(palette.color ?? UIColor.clear) - .cornerRadius(20) - .padding(20) - VStack { - Text(palette.colorText ?? "") - .navigationBarTitle(Text("Color")) - Slider(value: $hue, in: 0.0 ... 359.0 as ClosedRange) - Slider(value: $saturation, in: 0.0 ... 1.0 as ClosedRange) - Slider(value: $brightness, in: 0.0 ... 0.1 as ClosedRange) - } - } - } -} - -@available(iOS 13.0.0, *) -struct SwiftUIView_Previews: PreviewProvider { - - static var previews: some View { - SwiftUIView( - palettes: ColorsDemo.stack.publishList( - From() - .sectionBy(\.$colorName) - .orderBy(.ascending(\.$hue)) - ) - ) - .environment(\.dataStack, ColorsDemo.stack) - } -} - -#endif diff --git a/LegacyDemo/LegacyDemo/Transactions Demo/Place.swift b/LegacyDemo/LegacyDemo/Transactions Demo/Place.swift deleted file mode 100644 index 37670f2..0000000 --- a/LegacyDemo/LegacyDemo/Transactions Demo/Place.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// Place.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/24. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import Foundation -import CoreData -import MapKit - - -// MARK: - Place - -class Place: NSManagedObject, MKAnnotation { - - @NSManaged var latitude: Double - @NSManaged var longitude: Double - @NSManaged var title: String? - @NSManaged var subtitle: String? - - func setInitialValues() { - - self.latitude = Double(arc4random_uniform(180)) - 90 - self.longitude = Double(arc4random_uniform(360)) - 180 - self.title = "\(self.latitude), \(self.longitude)" - self.subtitle = nil - } - - // MARK: MKAnnotation - - var coordinate: CLLocationCoordinate2D { - - get { - - return CLLocationCoordinate2DMake( - self.latitude, - self.longitude - ) - } - set { - - self.latitude = newValue.latitude - self.longitude = newValue.longitude - self.title = "\(self.latitude), \(self.longitude)" - self.subtitle = nil - } - } -} diff --git a/LegacyDemo/LegacyDemo/Transactions Demo/TransactionsDemoViewController.swift b/LegacyDemo/LegacyDemo/Transactions Demo/TransactionsDemoViewController.swift deleted file mode 100644 index abd270b..0000000 --- a/LegacyDemo/LegacyDemo/Transactions Demo/TransactionsDemoViewController.swift +++ /dev/null @@ -1,233 +0,0 @@ -// -// TransactionsDemoViewController.swift -// LegacyDemo -// -// Created by John Rommel Estropia on 2015/05/24. -// Copyright © 2018 John Rommel Estropia. All rights reserved. -// - -import UIKit -import Contacts -import CoreLocation -import MapKit -import AddressBookUI -import CoreStore - - -private struct Static { - - static let dataStack = DataStack() - - static let placeController: ObjectMonitor = { - - try! Static.dataStack.addStorageAndWait( - SQLiteStore( - fileName: "PlaceDemo.sqlite", - configuration: "TransactionsDemo", - localStorageOptions: .recreateStoreOnModelMismatch - ) - ) - - var place = try! Static.dataStack.fetchOne(From()) - if place == nil { - - _ = try? Static.dataStack.perform( - synchronous: { (transaction) in - - let place = transaction.create(Into()) - place.setInitialValues() - } - ) - place = try! Static.dataStack.fetchOne(From()) - } - - return Static.dataStack.monitorObject(place!) - }() -} - - -// MARK: - TransactionsDemoViewController - -class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, ObjectObserver { - - // MARK: NSObject - - deinit { - - Static.placeController.removeObserver(self) - } - - - // MARK: UIViewController - - override func viewDidLoad() { - - super.viewDidLoad() - - let longPressGesture = UILongPressGestureRecognizer( - target: self, - action: #selector(self.longPressGestureRecognized(_:)) - ) - self.mapView?.addGestureRecognizer(longPressGesture) - - Static.placeController.addObserver(self) - - self.navigationItem.rightBarButtonItem = UIBarButtonItem( - barButtonSystemItem: .refresh, - target: self, - action: #selector(self.refreshButtonTapped(_:)) - ) - } - - override func viewDidAppear(_ animated: Bool) { - - super.viewDidAppear(animated) - - let alert = UIAlertController( - title: "Transactions Demo", - message: "This demo shows how to use the 3 types of transactions to save updates: synchronous, asynchronous, and unsafe.\n\nTap and hold on the map to change the pin location.", - preferredStyle: .alert - ) - alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) - self.present(alert, animated: true, completion: nil) - } - - override func viewWillAppear(_ animated: Bool) { - - super.viewWillAppear(animated) - - if let mapView = self.mapView, let place = Static.placeController.object { - - mapView.addAnnotation(place) - mapView.setCenter(place.coordinate, animated: false) - mapView.selectAnnotation(place, animated: false) - } - } - - - // MARK: MKMapViewDelegate - - func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { - - let identifier = "MKAnnotationView" - var annotationView: MKPinAnnotationView! = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView - if annotationView == nil { - - annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) - annotationView.isEnabled = true - annotationView.canShowCallout = true - annotationView.animatesDrop = true - } - else { - - annotationView.annotation = annotation - } - - return annotationView - } - - - // MARK: ObjectObserver - - func objectMonitor(_ monitor: ObjectMonitor, willUpdateObject object: Place) { - - // none - } - - func objectMonitor(_ monitor: ObjectMonitor, didUpdateObject object: Place, changedPersistentKeys: Set) { - - if let mapView = self.mapView { - - mapView.removeAnnotations(mapView.annotations) - mapView.addAnnotation(object) - mapView.setCenter(object.coordinate, animated: true) - mapView.selectAnnotation(object, animated: true) - - if changedPersistentKeys.contains(#keyPath(Place.latitude)) || changedPersistentKeys.contains(#keyPath(Place.longitude)) { - - self.geocode(place: object) - } - } - } - - func objectMonitor(_ monitor: ObjectMonitor, didDeleteObject object: Place) { - - // none - } - - - // MARK: Private - - var geocoder: CLGeocoder? - - @IBOutlet weak var mapView: MKMapView? - - @IBAction dynamic func longPressGestureRecognized(_ sender: AnyObject?) { - - if let mapView = self.mapView, - let gesture = sender as? UILongPressGestureRecognizer, - gesture.state == .began { - - let coordinate = mapView.convert( - gesture.location(in: mapView), - toCoordinateFrom: mapView - ) - Static.dataStack.perform( - asynchronous: { (transaction) in - - let place = transaction.edit(Static.placeController.object) - place?.coordinate = coordinate - }, - completion: { _ in } - ) - } - } - - @IBAction dynamic func refreshButtonTapped(_ sender: AnyObject?) { - - _ = try? Static.dataStack.perform( - synchronous: { (transaction) in - - let place = transaction.edit(Static.placeController.object) - place?.setInitialValues() - } - ) - } - - func geocode(place: Place) { - - let transaction = Static.dataStack.beginUnsafe() - - self.geocoder?.cancelGeocode() - - let geocoder = CLGeocoder() - self.geocoder = geocoder - geocoder.reverseGeocodeLocation( - CLLocation(latitude: place.latitude, longitude: place.longitude), - completionHandler: { [weak self] (placemarks, error) -> Void in - - if let placemark = placemarks?.first, let dictionary = placemark.addressDictionary { - - let place = transaction.edit(Static.placeController.object) - place?.title = placemark.name - place?.subtitle = CNPostalAddressFormatter.string( - from: autoreleasepool { - - let address = CNMutablePostalAddress() - (dictionary["Street"] as? String).flatMap({ address.street = $0 }) - (dictionary["State"] as? String).flatMap({ address.state = $0 }) - (dictionary["City"] as? String).flatMap({ address.city = $0 }) - (dictionary["Country"] as? String).flatMap({ address.country = $0 }) - (dictionary["ZIP"] as? String).flatMap({ address.postalCode = $0 }) - return address - }, - style: .mailingAddress - ) - transaction.commit { (_) -> Void in } - } - - self?.geocoder = nil - } - ) - } -} diff --git a/Sources/CSAsynchronousDataTransaction.swift b/Sources/CSAsynchronousDataTransaction.swift index 9e39fb3..388a860 100644 --- a/Sources/CSAsynchronousDataTransaction.swift +++ b/Sources/CSAsynchronousDataTransaction.swift @@ -29,113 +29,55 @@ import CoreData // MARK: - CSAsynchronousDataTransaction -/** - The `CSAsynchronousDataTransaction` serves as the Objective-C bridging type for `AsynchronousDataTransaction`. - - - SeeAlso: `AsynchronousDataTransaction` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSAsynchronousDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType { - - /** - Saves the transaction changes. This method should not be used after the `-commitWithCompletion:` method was already called once. - - - parameter success: the block executed if the save succeeds. - - parameter failure: the block executed if the save fails. A `CSError` is reported as the argument of the block. - */ + @objc public func commitWithSuccess(_ success: (() -> Void)?, failure: ((CSError) -> Void)?) { - - Internals.assert( - self.bridgeToSwift.transactionQueue.cs_isCurrentExecutionContext(), - "Attempted to commit a \(Internals.typeName(self)) outside its designated queue." - ) - Internals.assert( - !self.bridgeToSwift.isCommitted, - "Attempted to commit a \(Internals.typeName(self)) more than once." - ) - self.bridgeToSwift.autoCommit { (_, error) in - - if let error = error { - - failure?(error.bridgeToObjectiveC) - } - else { - - success?() - } - } + + fatalError() } // MARK: NSObject public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } // MARK: BaseDataTransaction - - /** - Creates a new `NSManagedObject` with the specified entity type. - - - parameter into: the `CSInto` clause indicating the destination `NSManagedObject` entity type and the destination configuration - - returns: a new `NSManagedObject` instance of the specified entity type. - */ + @objc public override func createInto(_ into: CSInto) -> Any { - - return self.bridgeToSwift.create(into.bridgeToSwift) + + fatalError() } - - /** - Returns an editable proxy of a specified `NSManagedObject`. This method should not be used after the `-commitWithCompletion:` method was already called once. - - - parameter object: the `NSManagedObject` type to be edited - - returns: an editable proxy for the specified `NSManagedObject`. - */ + @objc public override func editObject(_ object: NSManagedObject?) -> Any? { - - return self.bridgeToSwift.edit(object) + + fatalError() } - - /** - Returns an editable proxy of the object with the specified `NSManagedObjectID`. This method should not be used after the `-commitWithCompletion:` method was already called once. - - - parameter into: a `CSInto` clause specifying the entity type - - parameter objectID: the `NSManagedObjectID` for the object to be edited - - returns: an editable proxy for the specified `NSManagedObject`. - */ + @objc public override func editInto(_ into: CSInto, objectID: NSManagedObjectID) -> Any? { - - return self.bridgeToSwift.edit(into.bridgeToSwift, objectID) + + fatalError() } - - /** - Deletes a specified `NSManagedObject`. This method should not be used after the `-commitWithCompletion:` method was already called once. - - - parameter object: the `NSManagedObject` type to be deleted - */ + @objc public override func deleteObject(_ object: NSManagedObject?) { - - self.bridgeToSwift.delete(object) + + fatalError() } - - /** - Deletes the specified `NSManagedObject`s. - - - parameter objects: the `NSManagedObject`s type to be deleted - */ + @objc public override func deleteObjects(_ objects: [NSManagedObject]) { - - self.bridgeToSwift.delete(objects) + + fatalError() } @@ -144,31 +86,26 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction, CoreSto public typealias SwiftType = AsynchronousDataTransaction public var bridgeToSwift: AsynchronousDataTransaction { - - return super.swiftTransaction as! AsynchronousDataTransaction + + fatalError() } public required init(_ swiftValue: AsynchronousDataTransaction) { - - super.init(swiftValue as BaseDataTransaction) - } - - public required override init(_ swiftValue: BaseDataTransaction) { - - super.init(swiftValue) + + fatalError() } } // MARK: - AsynchronousDataTransaction -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension AsynchronousDataTransaction: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSAsynchronousDataTransaction { - - return CSAsynchronousDataTransaction(self) + + fatalError() } } diff --git a/Sources/CSBaseDataTransaction+Querying.swift b/Sources/CSBaseDataTransaction+Querying.swift index d993df4..a664900 100644 --- a/Sources/CSBaseDataTransaction+Querying.swift +++ b/Sources/CSBaseDataTransaction+Querying.swift @@ -29,167 +29,66 @@ import CoreData // MARK: - CSBaseDataTransaction +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension CSBaseDataTransaction { - - /** - Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context. - - - parameter object: a reference to the object created/fetched outside the transaction - - returns: the `NSManagedObject` instance if the object exists in the transaction, or `nil` if not found. - */ + @objc public func fetchExistingObject(_ object: NSManagedObject) -> Any? { - - return self.swiftTransaction.context.fetchExisting(object) as NSManagedObject? + + fatalError() } - - /** - Fetches the `NSManagedObject` instance in the transaction's context from an `NSManagedObjectID`. - - - parameter objectID: the `NSManagedObjectID` for the object - - returns: the `NSManagedObject` instance if the object exists in the transaction, or `nil` if not found. - */ + @objc public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? { - - return self.swiftTransaction.context.fetchExisting(objectID) as NSManagedObject? + + fatalError() } - - /** - Fetches the `NSManagedObject` instances in the transaction's context from references created from a transaction or from a different managed object context. - - - parameter objects: an array of `NSManagedObject`s created/fetched outside the transaction - - returns: the `NSManagedObject` array for objects that exists in the transaction - */ + @objc public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] { - - return self.swiftTransaction.context.fetchExisting(objects) as [NSManagedObject] + + fatalError() } - - /** - Fetches the `NSManagedObject` instances in the transaction's context from a list of `NSManagedObjectID`. - - - parameter objectIDs: the `NSManagedObjectID` array for the objects - - returns: the `NSManagedObject` array for objects that exists in the transaction - */ + @objc public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] { - - return self.swiftTransaction.context.fetchExisting(objectIDs) as [NSManagedObject] + + fatalError() } - - /** - Fetches the first `NSManagedObject` instance that satisfies the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `From` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: the first `NSManagedObject` instance that satisfies the specified `CSFetchClause`s - */ + @objc public func fetchOneFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> Any? { - - Internals.assert( - self.swiftTransaction.isRunningInAllowedQueue(), - "Attempted to fetch from a \(Internals.typeName(self)) outside its designated queue." - ) - return (try? self.swiftTransaction.context.fetchOne(from, fetchClauses))? - .flatMap({ $0 }) + + fatalError() } - - /** - Fetches all `NSManagedObject` instances that satisfy the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: all `NSManagedObject` instances that satisfy the specified `CSFetchClause`s - */ + @objc public func fetchAllFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> [Any]? { - - Internals.assert( - self.swiftTransaction.isRunningInAllowedQueue(), - "Attempted to fetch from a \(Internals.typeName(self)) outside its designated queue." - ) - return (try? self.swiftTransaction.context.fetchAll(from, fetchClauses)) - .flatMap({ $0 }) + + fatalError() } - - /** - Fetches the number of `NSManagedObject`s that satisfy the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: the number `NSManagedObject`s that satisfy the specified `CSFetchClause`s - */ + @objc public func fetchCountFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSNumber? { - - Internals.assert( - self.swiftTransaction.isRunningInAllowedQueue(), - "Attempted to fetch from a \(Internals.typeName(self)) outside its designated queue." - ) - return (try? self.swiftTransaction.context.fetchCount(from, fetchClauses)) - .flatMap({ NSNumber(value: $0) }) + + fatalError() } - - /** - Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `CSFetchClause`s - */ + @objc public func fetchObjectIDFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSManagedObjectID? { - - Internals.assert( - self.swiftTransaction.isRunningInAllowedQueue(), - "Attempted to fetch from a \(Internals.typeName(self)) outside its designated queue." - ) - return (try? self.swiftTransaction.context.fetchObjectID(from, fetchClauses)) - .flatMap({ $0 }) + + fatalError() } - - /** - Queries aggregate values as specified by the `CSQueryClause`s. Requires at least a `CSSelect` clause, and optional `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter selectClause: a `CSSelect` clause indicating the properties to fetch, and with the generic type indicating the return type. - - parameter queryClauses: a series of `CSQueryClause` instances for the query request. Accepts `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - returns: the result of the the query. The type of the return value is specified by the generic type of the `CSSelect` parameter. - */ + @objc public func queryValueFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> Any? { - - Internals.assert( - self.swiftTransaction.isRunningInAllowedQueue(), - "Attempted to query from a \(Internals.typeName(self)) outside its designated queue." - ) - return (try? self.swiftTransaction.context.queryValue(from, selectClause, queryClauses)) - .flatMap({ $0 }) + + fatalError() } - - /** - Queries a dictionary of attribute values as specified by the `CSQueryClause`s. Requires at least a `CSSelect` clause, and optional `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter selectClause: a `CSSelect` clause indicating the properties to fetch, and with the generic type indicating the return type. - - parameter queryClauses: a series of `CSQueryClause` instances for the query request. Accepts `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - returns: the result of the the query. The type of the return value is specified by the generic type of the `CSSelect` parameter. - */ + @objc public func queryAttributesFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> [[String: Any]]? { - - Internals.assert( - self.swiftTransaction.isRunningInAllowedQueue(), - "Attempted to query from a \(Internals.typeName(self)) outside its designated queue." - ) - return (try? self.swiftTransaction.context.queryAttributes(from, selectClause, queryClauses)) - .flatMap({ $0 }) + + fatalError() } } diff --git a/Sources/CSBaseDataTransaction.swift b/Sources/CSBaseDataTransaction.swift index c909e4b..483ecfc 100644 --- a/Sources/CSBaseDataTransaction.swift +++ b/Sources/CSBaseDataTransaction.swift @@ -29,226 +29,121 @@ import CoreData // MARK: - CSBaseDataTransaction -/** - The `CSBaseDataTransaction` serves as the Objective-C bridging type for `BaseDataTransaction`. - - - SeeAlso: `BaseDataTransaction` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public class CSBaseDataTransaction: NSObject { // MARK: Object management - - /** - Indicates if the transaction has pending changes - */ + @objc public var hasChanges: Bool { - - return self.swiftTransaction.hasChanges - } - - /** - Creates a new `NSManagedObject` with the specified entity type. - - - parameter into: the `CSInto` clause indicating the destination `NSManagedObject` entity type and the destination configuration - - returns: a new `NSManagedObject` instance of the specified entity type. - */ - @objc - public func createInto(_ into: CSInto) -> Any { - - return self.swiftTransaction.create(into.bridgeToSwift) - } - - /** - Returns an editable proxy of a specified `NSManagedObject`. - - - parameter object: the `NSManagedObject` type to be edited - - returns: an editable proxy for the specified `NSManagedObject`. - */ - @objc - public func editObject(_ object: NSManagedObject?) -> Any? { - - return self.swiftTransaction.edit(object) - } - - /** - Returns an editable proxy of the object with the specified `NSManagedObjectID`. - - - parameter into: a `CSInto` clause specifying the entity type - - parameter objectID: the `NSManagedObjectID` for the object to be edited - - returns: an editable proxy for the specified `NSManagedObject`. - */ - @objc - public func editInto(_ into: CSInto, objectID: NSManagedObjectID) -> Any? { - - return self.swiftTransaction.edit(into.bridgeToSwift, objectID) + + fatalError() + } + + @objc + public func createInto(_ into: CSInto) -> Any { + + fatalError() + } + + @objc + public func editObject(_ object: NSManagedObject?) -> Any? { + + fatalError() + } + + @objc + public func editInto(_ into: CSInto, objectID: NSManagedObjectID) -> Any? { + + fatalError() } - /** - Deletes a specified `NSManagedObject`. - - - parameter object: the `NSManagedObject` to be deleted - */ @objc public func deleteObject(_ object: NSManagedObject?) { - - self.swiftTransaction.delete(object) + + fatalError() } - - /** - Deletes the specified `NSManagedObject`s. - - - parameter objects: the `NSManagedObject`s to be deleted - */ + @objc public func deleteObjects(_ objects: [NSManagedObject]) { - - self.swiftTransaction.delete(objects) + + fatalError() } - - /** - Refreshes all registered objects `NSManagedObject`s in the transaction. - */ + @objc public func refreshAndMergeAllObjects() { - - self.swiftTransaction.refreshAndMergeAllObjects() + + fatalError() } // MARK: Inspecting Pending Objects - - /** - Returns all pending `NSManagedObject`s of the specified type that were inserted to the transaction. This method should not be called after the `-commit*:` method was called. - - - parameter entity: the `NSManagedObject` subclass to filter - - returns: an `NSSet` of pending `NSManagedObject`s of the specified type that were inserted to the transaction. - */ + @objc public func insertedObjectsOfType(_ entity: NSManagedObject.Type) -> Set { - - return self.swiftTransaction.insertedObjects(entity) - } - - /** - Returns all pending `NSManagedObjectID`s that were inserted to the transaction. This method should not be called after the `-commit*:` method was called. - - - returns: an `NSSet` of pending `NSManagedObjectID`s that were inserted to the transaction. - */ - @objc - public func insertedObjectIDs() -> Set { - - return self.swiftTransaction.insertedObjectIDs() - } - - /** - Returns all pending `NSManagedObjectID`s of the specified type that were inserted to the transaction. This method should not be called after the `-commit*:` method was called. - - - parameter entity: the `NSManagedObject` subclass to filter - - returns: an `NSSet` of pending `NSManagedObjectID`s of the specified type that were inserted to the transaction. - */ - @objc - public func insertedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set { - - return self.swiftTransaction.insertedObjectIDs(entity) - } - - /** - Returns all pending `NSManagedObject`s of the specified type that were updated in the transaction. This method should not be called after the `-commit*:` method was called. - - - parameter entity: the `NSManagedObject` subclass to filter - - returns: an `NSSet` of pending `NSManagedObject`s of the specified type that were updated in the transaction. - */ - @objc - public func updatedObjectsOfType(_ entity: NSManagedObject.Type) -> Set { - - return self.swiftTransaction.updatedObjects(entity) - } - - /** - Returns all pending `NSManagedObjectID`s that were updated in the transaction. This method should not be called after the `-commit*:` method was called. - - - returns: an `NSSet` of pending `NSManagedObjectID`s that were updated in the transaction. - */ - @objc - public func updatedObjectIDs() -> Set { - - return self.swiftTransaction.updatedObjectIDs() - } - - /** - Returns all pending `NSManagedObjectID`s of the specified type that were updated in the transaction. This method should not be called after the `-commit*:` method was called. - - - parameter entity: the `NSManagedObject` subclass to filter - - returns: an `NSSet` of pending `NSManagedObjectID`s of the specified type that were updated in the transaction. - */ - @objc - public func updatedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set { - - return self.swiftTransaction.updatedObjectIDs(entity) - } - - /** - Returns all pending `NSManagedObject`s of the specified type that were deleted from the transaction. This method should not be called after the `-commit*:` method was called. - - - parameter entity: the `NSManagedObject` subclass to filter - - returns: an `NSSet` of pending `NSManagedObject`s of the specified type that were deleted from the transaction. - */ - @objc - public func deletedObjectsOfType(_ entity: NSManagedObject.Type) -> Set { - - return self.swiftTransaction.deletedObjects(entity) - } - - /** - Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `-commit*:` method was called. - - - returns: an `NSSet` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. - */ - @objc - public func deletedObjectIDs() -> Set { - - return self.swiftTransaction.deletedObjectIDs() + + fatalError() + } + + @objc + public func insertedObjectIDs() -> Set { + + fatalError() + } + + @objc + public func insertedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set { + + fatalError() + } + + @objc + public func updatedObjectsOfType(_ entity: NSManagedObject.Type) -> Set { + + fatalError() + } + + @objc + public func updatedObjectIDs() -> Set { + + fatalError() + } + + @objc + public func updatedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set { + + fatalError() + } + + @objc + public func deletedObjectsOfType(_ entity: NSManagedObject.Type) -> Set { + + fatalError() + } + + @objc + public func deletedObjectIDs() -> Set { + + fatalError() } - /** - Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `-commit*:` method was called. - - - parameter entity: the `NSManagedObject` subclass to filter - - returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. - */ @objc public func deletedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set { - - return self.swiftTransaction.deletedObjectIDs(entity) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return ObjectIdentifier(self.swiftTransaction).hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSBaseDataTransaction else { - - return false - } - return self.swiftTransaction === object.swiftTransaction - } - - - // MARK: Internal - - internal let swiftTransaction: BaseDataTransaction - - internal init(_ swiftValue: BaseDataTransaction) { - - self.swiftTransaction = swiftValue - super.init() + + fatalError() } } diff --git a/Sources/CSClauseTypes.swift b/Sources/CSClauseTypes.swift index c73a5c4..a5a5e71 100644 --- a/Sources/CSClauseTypes.swift +++ b/Sources/CSClauseTypes.swift @@ -29,11 +29,7 @@ import CoreData // MARK: - CSFetchClause -/** - The `CSFetchClause` implement clauses used to configure `NSFetchRequest`s. - - - SeeAlso: `FetchClause` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSFetchClause { @@ -44,11 +40,7 @@ public protocol CSFetchClause { // MARK: - CSQueryClause -/** - The `CSQueryClause` implement clauses used to configure `NSFetchRequest`s. - - - SeeAlso: `QueryClause` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSQueryClause { @@ -59,11 +51,7 @@ public protocol CSQueryClause { // MARK: - CSDeleteClause -/** - The `CSDeleteClause` implement clauses used to configure `NSFetchRequest`s. - - - SeeAlso: `DeleteClause` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSDeleteClause { diff --git a/Sources/CSCoreStore.swift b/Sources/CSCoreStore.swift index c07e675..fe3a41b 100644 --- a/Sources/CSCoreStore.swift +++ b/Sources/CSCoreStore.swift @@ -28,33 +28,14 @@ import Foundation // MARK: - CSCoreStore -/** - The `CSCoreStore` serves as the Objective-C bridging type for `CoreStore`. - - - SeeAlso: `CoreStore` - */ -@available(*, deprecated, message: "Call methods directly from the CSDataStack instead") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSCoreStore: NSObject { - - /** - The default `CSDataStack` instance to be used. If `defaultStack` is not set before the first time accessed, a default-configured `CSDataStack` will be created. - - - SeeAlso: `CSDataStack` - - Note: Changing the `defaultStack` is thread safe, but it is recommended to setup `CSDataStacks` on a common queue (e.g. the main queue). - */ + @objc public static var defaultStack: CSDataStack { - get { return CoreStoreDefaults.dataStack.bridgeToObjectiveC } - set { CoreStoreDefaults.dataStack = newValue.bridgeToSwift } - } - - - // MARK: Private - - private override init() { - - fatalError() + get { fatalError() } + set { fatalError() } } } diff --git a/Sources/CSDataStack+Migrating.swift b/Sources/CSDataStack+Migrating.swift index b3e95f2..047217e 100644 --- a/Sources/CSDataStack+Migrating.swift +++ b/Sources/CSDataStack+Migrating.swift @@ -29,99 +29,30 @@ import CoreData // MARK: - CSDataStack -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension CSDataStack { - /** - Asynchronously adds a `CSInMemoryStore` to the stack. Migrations are also initiated by default. - ``` - NSError *error; - NSProgress *migrationProgress = [dataStack - addInMemoryStorage:[CSInMemoryStore new] - completion:^(CSSetupResult *result) { - if (result.isSuccess) { - // ... - } - } - error: &error]; - ``` - - parameter storage: the `CSInMemoryStore` instance - - parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `CSSetupResult` argument indicates the result. This closure is NOT executed if an error is thrown, but will be executed with a failure `CSSetupResult` result if an error occurs asynchronously. - */ @objc public func addInMemoryStorage(_ storage: CSInMemoryStore, completion: @escaping (CSSetupResult) -> Void) { - - self.bridgeToSwift.addStorage( - storage.bridgeToSwift, - completion: { completion($0.bridgeToObjectiveC) } - ) + + fatalError() } - - /** - Asynchronously adds a `CSSQLiteStore` to the stack. Migrations are also initiated by default. - ``` - NSError *error; - NSProgress *migrationProgress = [dataStack - addInMemoryStorage:[[CSSQLiteStore alloc] - initWithFileName:@"core_data.sqlite" - configuration:@"Config1"] - completion:^(CSSetupResult *result) { - if (result.isSuccess) { - // ... - } - } - error: &error]; - ``` - - parameter storage: the `CSSQLiteStore` instance - - parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `CSSetupResult` argument indicates the result. This closure is NOT executed if an error is thrown, but will be executed with a failure `CSSetupResult` result if an error occurs asynchronously. Note that the `CSLocalStorage` associated to the `-[CSSetupResult storage]` may not always be the same instance as the parameter argument if a previous `CSLocalStorage` was already added at the same URL and with the same configuration. - - parameter error: the `NSError` pointer that indicates the reason in case of an failure - - returns: an `NSProgress` instance if a migration has started. `nil` if no migrations are required or if `error` was set. - */ + @objc public func addSQLiteStorage(_ storage: CSSQLiteStore, completion: @escaping (CSSetupResult) -> Void, error: NSErrorPointer) -> Progress? { - - return bridge(error) { - - self.bridgeToSwift.addStorage( - storage.bridgeToSwift, - completion: { completion($0.bridgeToObjectiveC) } - ) - } + + fatalError() } - - /** - Migrates a `CSSQLiteStore` to match the `CSDataStack`'s managed object model version. This method does NOT add the migrated store to the data stack. - - - parameter storage: the `CSSQLiteStore` instance - - parameter completion: the closure to be executed on the main queue when the migration completes, either due to success or failure. The closure's `CSMigrationResult` argument indicates the result. This closure is NOT executed if an error is thrown, but will be executed with a failure `CSSetupResult` result if an error occurs asynchronously. - - parameter error: the `NSError` pointer that indicates the reason in case of an failure - - returns: an `NSProgress` instance if a migration has started. `nil` if no migrations are required or if `error` was set. - */ + @objc public func upgradeStorageIfNeeded(_ storage: CSSQLiteStore, completion: @escaping (CSMigrationResult) -> Void, error: NSErrorPointer) -> Progress? { - - return bridge(error) { - - try self.bridgeToSwift.upgradeStorageIfNeeded( - storage.bridgeToSwift, - completion: { completion($0.bridgeToObjectiveC) } - ) - } + + fatalError() } - - /** - Checks the migration steps required for the `CSSQLiteStore` to match the `CSDataStack`'s managed object model version. - - - parameter storage: the `CSSQLiteStore` instance - - parameter error: the `NSError` pointer that indicates the reason in case of an failure - - returns: a `CSMigrationType` array indicating the migration steps required for the store, or an empty array if the file does not exist yet. Otherwise, `nil` is returned and the `error` argument is set if either inspection of the store failed, or if no mapping model was found/inferred. - */ + @objc public func requiredMigrationsForSQLiteStore(_ storage: CSSQLiteStore, error: NSErrorPointer) -> [CSMigrationType]? { - - return bridge(error) { - - try self.bridgeToSwift.requiredMigrationsForStorage(storage.bridgeToSwift) - } + + fatalError() } } diff --git a/Sources/CSDataStack+Observing.swift b/Sources/CSDataStack+Observing.swift index d0c2ff4..5b6d9cc 100644 --- a/Sources/CSDataStack+Observing.swift +++ b/Sources/CSDataStack+Observing.swift @@ -29,143 +29,35 @@ import CoreData // MARK: - CSDataStack -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension CSDataStack { - /** - Creates a `CSObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`. - - - parameter object: the `NSManagedObject` to observe changes from - - returns: an `ObjectMonitor` that monitors changes to `object` - */ @objc public func monitorObject(_ object: NSManagedObject) -> CSObjectMonitor { - - return self.bridgeToSwift.monitorObject(object).bridgeToObjectiveC + + fatalError() } - - /** - Creates a `CSListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `CSListObserver`s may then register themselves to be notified when changes are made to the list. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: a `CSListMonitor` instance that monitors changes to the list - */ + @objc public func monitorListFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> CSListMonitor { - - Internals.assert( - Thread.isMainThread, - "Attempted to observe objects from \(Internals.typeName(self)) outside the main thread." - ) - Internals.assert( - fetchClauses.contains { $0 is CSOrderBy }, - "A CSListMonitor requires a CSOrderBy clause." - ) - return ListMonitor( - dataStack: self.bridgeToSwift, - from: from.bridgeToSwift, - sectionBy: nil, - applyFetchClauses: { (fetchRequest) in - - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - } - ).bridgeToObjectiveC + + fatalError() } - - /** - Asynchronously creates a `CSListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `CSListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed. - - - parameter createAsynchronously: the closure that receives the created `CSListMonitor` instance - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for fetching the object list. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - */ + @objc public func monitorListByCreatingAsynchronously(_ createAsynchronously: @escaping (CSListMonitor) -> Void, from: CSFrom, fetchClauses: [CSFetchClause]) { - - Internals.assert( - Thread.isMainThread, - "Attempted to observe objects from \(Internals.typeName(self)) outside the main thread." - ) - Internals.assert( - fetchClauses.contains { $0 is CSOrderBy }, - "A CSListMonitor requires an CSOrderBy clause." - ) - _ = ListMonitor( - dataStack: self.bridgeToSwift, - from: from.bridgeToSwift, - sectionBy: nil, - applyFetchClauses: { (fetchRequest) in - - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - }, - createAsynchronously: { - - createAsynchronously($0.bridgeToObjectiveC) - } - ) + + fatalError() } - - /** - Creates a `CSListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter sectionBy: a `CSSectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections. - - parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: a `CSListMonitor` instance that monitors changes to the list - */ + @objc public func monitorSectionedListFrom(_ from: CSFrom, sectionBy: CSSectionBy, fetchClauses: [CSFetchClause]) -> CSListMonitor { - - Internals.assert( - Thread.isMainThread, - "Attempted to observe objects from \(Internals.typeName(self)) outside the main thread." - ) - Internals.assert( - fetchClauses.contains { $0 is CSOrderBy }, - "A CSListMonitor requires an CSOrderBy clause." - ) - return ListMonitor( - dataStack: self.bridgeToSwift, - from: from.bridgeToSwift, - sectionBy: sectionBy.bridgeToSwift, - applyFetchClauses: { (fetchRequest) in - - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - } - ).bridgeToObjectiveC + + fatalError() } - - /** - Asynchronously creates a `CSListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `CSListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed. - - - parameter createAsynchronously: the closure that receives the created `CSListMonitor` instance - - parameter from: a `CSFrom` clause indicating the entity type - - parameter sectionBy: a `CSSectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections. - - parameter fetchClauses: a series of `CSFetchClause` instances for fetching the object list. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - */ + public func monitorSectionedListByCreatingAsynchronously(_ createAsynchronously: @escaping (CSListMonitor) -> Void, from: CSFrom, sectionBy: CSSectionBy, fetchClauses: [CSFetchClause]) { - - Internals.assert( - Thread.isMainThread, - "Attempted to observe objects from \(Internals.typeName(self)) outside the main thread." - ) - Internals.assert( - fetchClauses.contains { $0 is CSOrderBy }, - "A CSListMonitor requires an CSOrderBy clause." - ) - _ = ListMonitor( - dataStack: self.bridgeToSwift, - from: from.bridgeToSwift, - sectionBy: sectionBy.bridgeToSwift, - applyFetchClauses: { (fetchRequest) in - - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - }, - createAsynchronously: { - - createAsynchronously($0.bridgeToObjectiveC) - } - ) + + fatalError() } } diff --git a/Sources/CSDataStack+Querying.swift b/Sources/CSDataStack+Querying.swift index 1c1a440..6877d92 100644 --- a/Sources/CSDataStack+Querying.swift +++ b/Sources/CSDataStack+Querying.swift @@ -29,186 +29,72 @@ import CoreData // MARK: - CSDataStack -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension CSDataStack { - - /** - Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context. - - - parameter object: a reference to the object created/fetched outside the transaction - - returns: the `NSManagedObject` instance if the object exists in the transaction, or `nil` if not found. - */ + @objc public func fetchExistingObject(_ object: NSManagedObject) -> Any? { - - return self.bridgeToSwift.mainContext.fetchExisting(object) as NSManagedObject? + + fatalError() } - - /** - Fetches the `NSManagedObject` instance in the transaction's context from an `NSManagedObjectID`. - - - parameter objectID: the `NSManagedObjectID` for the object - - returns: the `NSManagedObject` instance if the object exists in the transaction, or `nil` if not found. - */ + @objc public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? { - - return self.bridgeToSwift.mainContext.fetchExisting(objectID) as NSManagedObject? + + fatalError() } - - /** - Fetches the `NSManagedObject` instances in the transaction's context from references created from a transaction or from a different managed object context. - - - parameter objects: an array of `NSManagedObject`s created/fetched outside the transaction - - returns: the `NSManagedObject` array for objects that exists in the transaction - */ + @objc public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] { - - return self.bridgeToSwift.mainContext.fetchExisting(objects) as [NSManagedObject] + + fatalError() } - - /** - Fetches the `NSManagedObject` instances in the transaction's context from a list of `NSManagedObjectID`. - - - parameter objectIDs: the `NSManagedObjectID` array for the objects - - returns: the `NSManagedObject` array for objects that exists in the transaction - */ + @objc public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] { - - return self.bridgeToSwift.mainContext.fetchExisting(objectIDs) as [NSManagedObject] + + fatalError() } - - /** - Fetches the first `NSManagedObject` instance that satisfies the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `From` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: the first `NSManagedObject` instance that satisfies the specified `CSFetchClause`s - */ + @objc public func fetchOneFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> Any? { - - Internals.assert( - Thread.isMainThread, - "Attempted to fetch from a \(Internals.typeName(self)) outside the main thread." - ) - return (try? self.bridgeToSwift.mainContext.fetchOne(from, fetchClauses))? - .flatMap({ $0 }) + + fatalError() } - - /** - Fetches all `NSManagedObject` instances that satisfy the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: all `NSManagedObject` instances that satisfy the specified `CSFetchClause`s - */ + @objc public func fetchAllFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> [Any]? { - - Internals.assert( - Thread.isMainThread, - "Attempted to fetch from a \(Internals.typeName(self)) outside the main thread." - ) - return (try? self.bridgeToSwift.mainContext.fetchAll(from, fetchClauses)) - .flatMap({ $0 }) + + fatalError() } - - /** - Fetches the number of `NSManagedObject`s that satisfy the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: the number `NSManagedObject`s that satisfy the specified `CSFetchClause`s - */ + @objc public func fetchCountFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSNumber? { - - Internals.assert( - Thread.isMainThread, - "Attempted to fetch from a \(Internals.typeName(self)) outside the main thread." - ) - return (try? self.bridgeToSwift.mainContext.fetchCount(from, fetchClauses)) - .flatMap({ NSNumber(value: $0) }) + + fatalError() } - - /** - Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `CSFetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `CSFetchClause`s - */ + @objc public func fetchObjectIDFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSManagedObjectID? { - - Internals.assert( - Thread.isMainThread, - "Attempted to fetch from a \(Internals.typeName(self)) outside the main thread." - ) - return (try? self.bridgeToSwift.mainContext.fetchObjectID(from, fetchClauses))? - .flatMap({ $0 }) + + fatalError() } - - /** - Fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `CSFetchClause`s. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `CSWhere`, `CSOrderBy`, and `CSTweak` clauses. - - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `CSFetchClause`s - */ + @objc public func fetchObjectIDsFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> [NSManagedObjectID]? { - - Internals.assert( - Thread.isMainThread, - "Attempted to fetch from a \(Internals.typeName(self)) outside the main thread." - ) - return (try? self.bridgeToSwift.mainContext.fetchObjectIDs(from, fetchClauses)) - .flatMap({ $0 }) + + fatalError() } - - /** - Queries aggregate values as specified by the `CSQueryClause`s. Requires at least a `CSSelect` clause, and optional `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter selectClause: a `CSSelect` clause indicating the properties to fetch, and with the generic type indicating the return type. - - parameter queryClauses: a series of `CSQueryClause` instances for the query request. Accepts `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - returns: the result of the the query. The type of the return value is specified by the generic type of the `CSSelect` parameter. - */ + @objc public func queryValueFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> Any? { - - Internals.assert( - Thread.isMainThread, - "Attempted to query from a \(Internals.typeName(self)) outside the main thread." - ) - return (try? self.bridgeToSwift.mainContext.queryValue(from, selectClause, queryClauses)) - .flatMap({ $0 }) + + fatalError() } - - /** - Queries a dictionary of attribute values as specified by the `CSQueryClause`s. Requires at least a `CSSelect` clause, and optional `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result. - - - parameter from: a `CSFrom` clause indicating the entity type - - parameter selectClause: a `CSSelect` clause indicating the properties to fetch, and with the generic type indicating the return type. - - parameter queryClauses: a series of `CSQueryClause` instances for the query request. Accepts `CSWhere`, `CSOrderBy`, `CSGroupBy`, and `CSTweak` clauses. - - returns: the result of the the query. The type of the return value is specified by the generic type of the `CSSelect` parameter. - */ + @objc public func queryAttributesFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> [[String: Any]]? { - - Internals.assert( - Thread.isMainThread, - "Attempted to query from a \(Internals.typeName(self)) outside the main thread." - ) - return (try? self.bridgeToSwift.mainContext.queryAttributes(from, selectClause, queryClauses)) - .flatMap({ $0 }) + + fatalError() } } diff --git a/Sources/CSDataStack+Transaction.swift b/Sources/CSDataStack+Transaction.swift index e652e33..c8fc145 100644 --- a/Sources/CSDataStack+Transaction.swift +++ b/Sources/CSDataStack+Transaction.swift @@ -28,108 +28,36 @@ import Foundation // MARK: - CSDataStack -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension CSDataStack { - - /** - Begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made. - - - parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`. - */ + @objc public func beginAsynchronous(_ closure: @escaping (_ transaction: CSAsynchronousDataTransaction) -> Void) { - - self.bridgeToSwift.perform( - asynchronous: { (transaction) in - - let csTransaction = transaction.bridgeToObjectiveC - closure(csTransaction) - if !transaction.isCommitted && transaction.hasChanges { - - Internals.log( - .warning, - message: "The closure for the \(Internals.typeName(csTransaction)) completed without being committed. All changes made within the transaction were discarded." - ) - } - try transaction.cancel() - }, - completion: { _ in } - ) + + fatalError() } - - /** - Begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made. - - - parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`. - - parameter error: the `CSError` pointer that indicates the reason in case of an failure - - returns: `YES` if the commit succeeded, `NO` if the commit failed. If `NO`, the `error` argument will hold error information. - */ + @objc public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void, error: NSErrorPointer) -> Bool { - - return bridge(error) { - - do { - - try self.bridgeToSwift.perform( - synchronous: { (transaction) in - - let csTransaction = transaction.bridgeToObjectiveC - closure(csTransaction) - if !transaction.isCommitted && transaction.hasChanges { - - Internals.log( - .warning, - message: "The closure for the \(Internals.typeName(csTransaction)) completed without being committed. All changes made within the transaction were discarded." - ) - } - try transaction.cancel() - } - ) - } - catch CoreStoreError.userCancelled { - - return - } - } + + fatalError() } - - /** - Begins a child transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms. - - To support "undo" methods such as `-undo`, `-redo`, and `-rollback`, use the `-beginSafeWithSupportsUndo:` method passing `YES` to the argument. Without "undo" support, calling those methods will raise an exception. - - returns: a `CSUnsafeDataTransaction` instance where creates, updates, and deletes can be made. - */ + @objc public func beginUnsafe() -> CSUnsafeDataTransaction { - - return bridge { - - self.bridgeToSwift.beginUnsafe() - } + + fatalError() } - - /** - Begins a child transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms. - - - prameter supportsUndo: `-undo`, `-redo`, and `-rollback` methods are only available when this parameter is `YES`, otherwise those method will raise an exception. Note that turning on Undo support may heavily impact performance especially on iOS or watchOS where memory is limited. - - returns: a `CSUnsafeDataTransaction` instance where creates, updates, and deletes can be made. - */ + @objc public func beginUnsafeWithSupportsUndo(_ supportsUndo: Bool) -> CSUnsafeDataTransaction { - - return bridge { - - self.bridgeToSwift.beginUnsafe(supportsUndo: supportsUndo) - } + + fatalError() } - - /** - Refreshes all registered objects `NSManagedObject`s in the `DataStack`. - */ + @objc public func refreshAndMergeAllObjects() { - - self.bridgeToSwift.refreshAndMergeAllObjects() + + fatalError() } } diff --git a/Sources/CSDataStack.swift b/Sources/CSDataStack.swift index d4878a1..b53c057 100644 --- a/Sources/CSDataStack.swift +++ b/Sources/CSDataStack.swift @@ -29,170 +29,84 @@ import CoreData // MARK: - CSDataStack -/** - The `CSDataStack` serves as the Objective-C bridging type for `DataStack`. - - - SeeAlso: `DataStack` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSDataStack: NSObject, CoreStoreObjectiveCType { - - /** - Initializes a `CSDataStack` with default settings. CoreStore searches for .xcdatamodeld from the main `NSBundle` and loads an `NSManagedObjectModel` from it. An assertion is raised if the model could not be found. - */ + @objc public convenience override init() { - self.init(DataStack()) + fatalError() } - - /** - Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`. - - - parameter xcodeModelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set. - - parameter bundle: an optional bundle to load .xcdatamodeld models from. If not specified, the main bundle will be used. - - parameter versionChain: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack. - */ + @objc public convenience init(xcodeModelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) { - - self.init( - DataStack( - xcodeModelName: xcodeModelName ?? DataStack.applicationName, - bundle: bundle ?? Bundle.main, - migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil - ) - ) + + fatalError() } - - /** - Returns the stack's model version. The version string is the same as the name of the version-specific .xcdatamodeld file. - */ + @objc public var modelVersion: String { - - return self.bridgeToSwift.modelVersion + + fatalError() } - - /** - Returns the entity name-to-class type mapping from the `CSDataStack`'s model. - */ + @objc public func entityTypesByNameForType(_ type: NSManagedObject.Type) -> [EntityName: NSManagedObject.Type] { - - return self.bridgeToSwift.entityTypesByName(for: type) + + fatalError() } - - /** - Returns the `NSEntityDescription` for the specified `NSManagedObject` subclass from stack's model. - */ + @objc public func entityDescriptionForClass(_ type: NSManagedObject.Type) -> NSEntityDescription? { - - return self.bridgeToSwift.entityDescription(for: type) + + fatalError() } - - /** - Creates an `CSInMemoryStore` with default parameters and adds it to the stack. This method blocks until completion. - ``` - CSSQLiteStore *storage = [dataStack addInMemoryStorageAndWaitAndReturnError:&error]; - ``` - - parameter error: the `NSError` pointer that indicates the reason in case of an failure - - returns: the `CSInMemoryStore` added to the stack - */ + @objc @discardableResult public func addInMemoryStorageAndWaitAndReturnError(_ error: NSErrorPointer) -> CSInMemoryStore? { - - return bridge(error) { - - try self.bridgeToSwift.addStorageAndWait(InMemoryStore()) - } + + fatalError() } - - /** - Creates an `CSSQLiteStore` with default parameters and adds it to the stack. This method blocks until completion. - ``` - CSSQLiteStore *storage = [dataStack addSQLiteStorageAndWaitAndReturnError:&error]; - ``` - - parameter error: the `NSError` pointer that indicates the reason in case of an failure - - returns: the `CSSQLiteStore` added to the stack - */ + @objc @discardableResult public func addSQLiteStorageAndWaitAndReturnError(_ error: NSErrorPointer) -> CSSQLiteStore? { - - return bridge(error) { - - try self.bridgeToSwift.addStorageAndWait(SQLiteStore()) - } + + fatalError() } - - /** - Adds a `CSInMemoryStore` to the stack and blocks until completion. - ``` - NSError *error; - CSInMemoryStore *storage = [dataStack - addStorageAndWait: [[CSInMemoryStore alloc] initWithConfiguration: @"Config1"] - error: &error]; - ``` - - parameter storage: the `CSInMemoryStore` - - parameter error: the `NSError` pointer that indicates the reason in case of an failure - - returns: the `CSInMemoryStore` added to the stack - */ + @objc @discardableResult public func addInMemoryStorageAndWait(_ storage: CSInMemoryStore, error: NSErrorPointer) -> CSInMemoryStore? { - - return bridge(error) { - - try self.bridgeToSwift.addStorageAndWait(storage.bridgeToSwift) - } + + fatalError() } - - /** - Adds a `CSSQLiteStore` to the stack and blocks until completion. - ``` - NSError *error; - CSSQLiteStore *storage = [dataStack - addStorageAndWait: [[CSSQLiteStore alloc] initWithConfiguration: @"Config1"] - error: &error]; - ``` - - parameter storage: the `CSSQLiteStore` - - parameter error: the `NSError` pointer that indicates the reason in case of an failure - - returns: the `CSSQLiteStore` added to the stack - */ + @objc @discardableResult public func addSQLiteStorageAndWait(_ storage: CSSQLiteStore, error: NSErrorPointer) -> CSSQLiteStore? { - - return bridge(error) { - - try self.bridgeToSwift.addStorageAndWait(storage.bridgeToSwift) - } + + fatalError() } // MARK: NSObject public override var hash: Int { - - return ObjectIdentifier(self.bridgeToSwift).hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSDataStack else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -201,22 +115,21 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType { public let bridgeToSwift: DataStack public init(_ swiftValue: DataStack) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - DataStack -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension DataStack: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSDataStack { - - return CSDataStack(self) + + fatalError() } } diff --git a/Sources/CSDynamicSchema.swift b/Sources/CSDynamicSchema.swift index 735b0e0..43299b4 100644 --- a/Sources/CSDynamicSchema.swift +++ b/Sources/CSDynamicSchema.swift @@ -29,23 +29,13 @@ import Foundation // MARK: - CSDynamicSchema -/** - The `CSDynamicSchema` serves as the Objective-C bridging type for `DynamicSchema`. - - - SeeAlso: `DynamicSchema` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSDynamicSchema { - - /** - The version string for this model schema. - */ + @objc var modelVersion: ModelVersion { get } - /** - Do not call this directly. The `NSManagedObjectModel` for this schema may be created lazily and using this method directly may affect the integrity of the model. - */ @objc func rawModel() -> NSManagedObjectModel } diff --git a/Sources/CSError.swift b/Sources/CSError.swift index 96b5ad0..ff8954e 100644 --- a/Sources/CSError.swift +++ b/Sources/CSError.swift @@ -29,281 +29,75 @@ import CoreData // MARK: - CSError -/** - All errors thrown from CoreStore are expressed in `CSError`s. - - - SeeAlso: `CoreStoreError` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSError: NSError { - - /** - The `NSError` error domain for `CSError`. - - - SeeAlso: `CoreStoreErrorErrorDomain` - */ + + // MARK: Public + @objc public static let errorDomain = CoreStoreErrorDomain public var bridgeToSwift: CoreStoreError { - if let swift = self.swiftError { - - return swift - } - let swift = CoreStoreError(_bridgedNSError: self) ?? .unknown - self.swiftError = swift - return swift + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSError else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } - - /** - Do not call directly! - */ + public init(_ swiftValue: CoreStoreError) { - - self.swiftError = swiftValue - super.init(domain: CoreStoreError.errorDomain, code: swiftValue.errorCode, userInfo: swiftValue.errorUserInfo) + + fatalError() } public required init?(coder aDecoder: NSCoder) { - - super.init(coder: aDecoder) - } - - - // MARK: Private - - private var swiftError: CoreStoreError? -} -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -extension CSError: CoreStoreObjectiveCType {} + fatalError() + } +} // MARK: - CSErrorCode -/** - The `NSError` error codes for `CSError.Domain`. - - - SeeAlso: `CSError` - - SeeAlso: `CoreStoreError` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public enum CSErrorCode: Int { - - /** - A failure occured because of an unknown error. - */ + case unknownError - - /** - The `NSPersistentStore` could note be initialized because another store existed at the specified `NSURL`. - */ case differentStorageExistsAtURL - - /** - An `NSMappingModel` could not be found for a specific source and destination model versions. - */ case mappingModelNotFound - - /** - Progressive migrations are disabled for a store, but an `NSMappingModel` could not be found for a specific source and destination model versions. - */ case progressiveMigrationRequired - - /** - An internal SDK call failed with the specified "NSError" userInfo key. - */ case internalError - - /** - The transaction was terminated by a user-thrown error with the specified "Error" userInfo key. - */ case userError - - /** - The transaction was cancelled by the user. - */ case userCancelled } // MARK: - CoreStoreError -extension CoreStoreError: _ObjectiveCBridgeableError { - - // MARK: _ObjectiveCBridgeableError - - public init?(_bridgedNSError error: NSError) { - - guard error.domain == CoreStoreErrorDomain else { - - if error is CSError { - - self = .internalError(NSError: error) - return - } - return nil - } - - guard let code = CoreStoreErrorCode(rawValue: error.code) else { - - if error is CSError { - - self = .unknown - return - } - return nil - } - - let info = error.userInfo - switch code { - - case .unknownError: - self = .unknown - - case .differentStorageExistsAtURL: - guard case let existingPersistentStoreURL as URL = info["existingPersistentStoreURL"] else { - - self = .unknown - return - } - self = .differentStorageExistsAtURL(existingPersistentStoreURL: existingPersistentStoreURL) - - case .mappingModelNotFound: - guard let localStoreURL = info["localStoreURL"] as? URL, - let targetModel = info["targetModel"] as? NSManagedObjectModel, - let targetModelVersion = info["targetModelVersion"] as? String else { - - self = .unknown - return - } - self = .mappingModelNotFound(localStoreURL: localStoreURL, targetModel: targetModel, targetModelVersion: targetModelVersion) - - case .progressiveMigrationRequired: - guard let localStoreURL = info["localStoreURL"] as? URL else { - - self = .unknown - return - } - self = .progressiveMigrationRequired(localStoreURL: localStoreURL) - - case .asynchronousMigrationRequired: - guard - let localStoreURL = info["localStoreURL"] as? URL, - case let nsError as NSError = info["NSError"] - else { - - self = .unknown - return - } - self = .asynchronousMigrationRequired(localStoreURL: localStoreURL, NSError: nsError) - - case .internalError: - guard case let nsError as NSError = info["NSError"] else { - - self = .unknown - return - } - self = .internalError(NSError: nsError) - - case .userError: - guard case let error as Error = info["Error"] else { - - self = .unknown - return - } - self = .userError(error: error) - - case .userCancelled: - self = .userCancelled - - case .persistentStoreNotFound: - guard let entity = info["entity"] as? DynamicObject.Type else { - - self = .unknown - return - } - self = .persistentStoreNotFound(entity: entity) - } - } -} - - -// MARK: - Error - -extension Error { - - // MARK: Internal - - internal var bridgeToSwift: CoreStoreError { - - switch self { - - case let error as CoreStoreError: - return error - - case let error as CSError: - return error.bridgeToSwift - - case let error as NSError where Self.self is NSError.Type: - return .internalError(NSError: error) - - default: - return .unknown - } - } - - @available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") - internal var bridgeToObjectiveC: NSError { - - switch self { - - case let error as CoreStoreError: - return error.bridgeToObjectiveC - - case let error as CSError: - return error - - default: - return self as NSError - } - } -} - - -// MARK: - CoreStoreError - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension CoreStoreError: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSError { - - return CSError(self) + + fatalError() } } diff --git a/Sources/CSFrom.swift b/Sources/CSFrom.swift index ced12dd..0023ab3 100644 --- a/Sources/CSFrom.swift +++ b/Sources/CSFrom.swift @@ -29,115 +29,46 @@ import CoreData // MARK: - CSFrom -/** - The `CSFrom` serves as the Objective-C bridging type for `From`. - - - SeeAlso: `From` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSFrom: NSObject { - - /** - The associated `NSManagedObject` entity class - */ + @objc public var entityClass: AnyClass { - - return self.bridgeToSwift.entityClass + + fatalError() } - - /** - The `NSPersistentStore` configuration names to associate objects from. - May contain `NSString` instances to pertain to named configurations, or `NSNull` to pertain to the default configuration - */ + @objc public var configurations: [Any]? { - - return self.bridgeToSwift.configurations?.map { - - switch $0 { - - case nil: return NSNull() - case let string as NSString: return string - } - } + + fatalError() } - - /** - Initializes a `CSFrom` clause with the specified entity class. - ``` - MyPersonEntity *people = [transaction fetchAllFrom:CSFromClass([MyPersonEntity class])]; - ``` - - parameter entityClass: the `NSManagedObject` class type to be created - */ + @objc public convenience init(entityClass: NSManagedObject.Type) { - - self.init(From(entityClass)) + + fatalError() } - - /** - Initializes a `CSFrom` clause with the specified configurations. - ``` - MyPersonEntity *people = [transaction fetchAllFrom: - CSFromClass([MyPersonEntity class], @"Config1")]; - ``` - - parameter entityClass: the associated `NSManagedObject` entity class - - parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration. - */ + @objc public convenience init(entityClass: NSManagedObject.Type, configuration: Any) { - - switch configuration { - - case let string as String: - self.init(From(entityClass, string)) - - case is NSNull: - self.init(From(entityClass, nil)) - - default: - Internals.abort("The configuration argument only accepts NSString and NSNull values") - } + + fatalError() } - - /** - Initializes a `CSFrom` clause with the specified configurations. - ``` - MyPersonEntity *people = [transaction fetchAllFrom: - CSFromClass([MyPersonEntity class], - @[[NSNull null], @"Config1"])]; - ``` - - parameter entityClass: the associated `NSManagedObject` entity class - - parameter configurations: an array of the `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration. - */ + @objc public convenience init(entityClass: NSManagedObject.Type, configurations: [Any]) { - - var arguments = [ModelConfiguration]() - for configuration in configurations { - - switch configuration { - - case let string as String: - arguments.append(string) - - case is NSNull: - arguments.append(nil) - - default: - Internals.abort("The configurations argument only accepts NSString and NSNull values") - } - } - self.init(From(entityClass, arguments)) + + fatalError() } // MARK: NSObject public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -146,33 +77,21 @@ public final class CSFrom: NSObject { public let bridgeToSwift: From public init(_ swiftValue: From) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - From +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension From where O: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSFrom { - - return CSFrom(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> From { - - return From( - entityClass: self.entityClass, - configurations: self.configurations, - findPersistentStores: self.findPersistentStores - ) + + fatalError() } } diff --git a/Sources/CSGroupBy.swift b/Sources/CSGroupBy.swift index 9a7cff9..c39d9c0 100644 --- a/Sources/CSGroupBy.swift +++ b/Sources/CSGroupBy.swift @@ -29,65 +29,44 @@ import CoreData // MARK: - CSGroupBy -/** - The `CSGroupBy` serves as the Objective-C bridging type for `GroupBy`. - - - SeeAlso: `GroupBy` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSGroupBy: NSObject, CSQueryClause { - /** - The list of key path strings to group results with - */ @objc public var keyPaths: [KeyPathString] { - - return self.bridgeToSwift.keyPaths + + fatalError() } - - /** - Initializes a `CSGroupBy` clause with a key path string - - - parameter keyPath: a key path string to group results with - */ + @objc public convenience init(keyPath: KeyPathString) { - - self.init(GroupBy(keyPath)) + + fatalError() } - - /** - Initializes a `CSGroupBy` clause with a list of key path strings - - - parameter keyPaths: a list of key path strings to group results with - */ + @objc public convenience init(keyPaths: [KeyPathString]) { - - self.init(GroupBy(keyPaths)) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSGroupBy else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -95,8 +74,8 @@ public final class CSGroupBy: NSObject, CSQueryClause { @objc public func applyToFetchRequest(_ fetchRequest: NSFetchRequest) { - - self.bridgeToSwift.applyToFetchRequest(fetchRequest) + + fatalError() } @@ -105,29 +84,21 @@ public final class CSGroupBy: NSObject, CSQueryClause { public let bridgeToSwift: GroupBy public init(_ swiftValue: GroupBy) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - GroupBy +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension GroupBy where O: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSGroupBy { - - return CSGroupBy(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> GroupBy { - - return GroupBy(self.keyPaths) + + fatalError() } } diff --git a/Sources/CSInMemoryStore.swift b/Sources/CSInMemoryStore.swift index 440c56d..7b12308 100644 --- a/Sources/CSInMemoryStore.swift +++ b/Sources/CSInMemoryStore.swift @@ -29,82 +29,56 @@ import CoreData // MARK: - CSInMemoryStore -/** - The `CSInMemoryStore` serves as the Objective-C bridging type for `InMemoryStore`. - - - SeeAlso: `InMemoryStore` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSInMemoryStore: NSObject, CSStorageInterface, CoreStoreObjectiveCType { - - /** - Initializes a `CSInMemoryStore` for the specified configuration - - - parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. - */ + @objc public convenience init(configuration: ModelConfiguration) { - - self.init(InMemoryStore(configuration: configuration)) + + fatalError() } - - /** - Initializes a `CSInMemoryStore` with the "Default" configuration - */ + @objc public convenience override init() { - - self.init(InMemoryStore()) + + fatalError() } // MARK: StorageInterface - - /** - The string identifier for the `NSPersistentStore`'s `type` property. For `CSInMemoryStore`s, this is always set to `NSInMemoryStoreType`. - */ + @objc public static let storeType = NSInMemoryStoreType - - /** - The configuration name in the model file - */ + @objc public var configuration: ModelConfiguration { - - return self.bridgeToSwift.configuration + + fatalError() } - /** - The options dictionary for the `NSPersistentStore`. For `CSInMemoryStore`s, this is always set to `nil`. - */ @objc public var storeOptions: [AnyHashable: Any]? { - - return self.bridgeToSwift.storeOptions + + fatalError() } // MARK: NSObject public override var hash: Int { - - return ObjectIdentifier(self.bridgeToSwift).hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSInMemoryStore else { - - return false - } - return self.bridgeToSwift === object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -113,22 +87,21 @@ public final class CSInMemoryStore: NSObject, CSStorageInterface, CoreStoreObjec public let bridgeToSwift: InMemoryStore public required init(_ swiftValue: InMemoryStore) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - InMemoryStore -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension InMemoryStore: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSInMemoryStore { - - return CSInMemoryStore(self) + + fatalError() } } diff --git a/Sources/CSInto.swift b/Sources/CSInto.swift index a49e602..c9b8c3e 100644 --- a/Sources/CSInto.swift +++ b/Sources/CSInto.swift @@ -29,82 +29,50 @@ import CoreData // MARK: - CSInto -/** - The `CSInto` serves as the Objective-C bridging type for `Into`. - - - SeeAlso: `Into` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSInto: NSObject { - - /** - The associated `NSManagedObject` entity class - */ + @objc public var entityClass: NSManagedObject.Type { - - return self.bridgeToSwift.entityClass + + fatalError() } - - /** - The `NSPersistentStore` configuration name to associate objects from. - May contain a `String` to pertain to a named configuration, or `nil` to pertain to the default configuration - */ + @objc public var configuration: ModelConfiguration { - - return self.bridgeToSwift.configuration + + fatalError() } - - /** - Initializes a `CSInto` clause with the specified entity class. - ``` - MyPersonEntity *person = [transaction createInto: - CSIntoClass([MyPersonEntity class])]; - ``` - - parameter entityClass: the `NSManagedObject` class type to be created - */ + @objc public convenience init(entityClass: NSManagedObject.Type) { - - self.init(Into(entityClass)) + + fatalError() } - - /** - Initializes a `CSInto` clause with the specified configuration. - ``` - MyPersonEntity *person = [transaction createInto: - CSIntoClass([MyPersonEntity class])]; - ``` - - parameter entityClass: the `NSManagedObject` class type to be created - - parameter configuration: the `NSPersistentStore` configuration name to associate the object to. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration. - */ + @objc public convenience init(entityClass: NSManagedObject.Type, configuration: ModelConfiguration) { - - self.init(Into(entityClass, configuration)) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSInto else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -113,9 +81,8 @@ public final class CSInto: NSObject { public let bridgeToSwift: Into public required init(_ swiftValue: Into) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } @@ -125,21 +92,10 @@ public final class CSInto: NSObject { extension Into where O: NSManagedObject { // MARK: CoreStoreSwiftType - + + @available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") public var bridgeToObjectiveC: CSInto { - - return CSInto(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> Into { - - return Into( - entityClass: self.entityClass, - configuration: self.configuration, - inferStoreIfPossible: self.inferStoreIfPossible - ) + + fatalError() } } diff --git a/Sources/CSListMonitor.swift b/Sources/CSListMonitor.swift index f4a5d67..eef9a04 100644 --- a/Sources/CSListMonitor.swift +++ b/Sources/CSListMonitor.swift @@ -29,503 +29,201 @@ import CoreData // MARK: - CSListMonitor -/** - The `CSListMonitor` serves as the Objective-C bridging type for `ListMonitor`. - - - SeeAlso: `ListMonitor` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSListMonitor: NSObject { // MARK: Public (Accessors) - /** - Returns the object at the given index within the first section. This subscript indexer is typically used for `CSListMonitor`s created without section groupings. - - - parameter index: the index of the object. Using an index above the valid range will raise an exception. - - returns: the `NSManagedObject` at the specified index - */ @objc public subscript(index: Int) -> Any { - - return self.bridgeToSwift[index] + + fatalError() } - - /** - Returns the object at the given index, or `nil` if out of bounds. This indexer is typically used for `CSListMonitor`s created without section groupings. - - - parameter index: the index for the object. Using an index above the valid range will return `nil`. - - returns: the `NSManagedObject` at the specified index, or `nil` if out of bounds - */ + @objc public func objectAtSafeIndex(_ index: Int) -> Any? { - - return self.bridgeToSwift[safeIndex: index] + + fatalError() } - - /** - Returns the object at the given `sectionIndex` and `itemIndex`. This indexer is typically used for `CSListMonitor`s created as sectioned lists. - - - parameter sectionIndex: the section index for the object. Using a `sectionIndex` with an invalid range will raise an exception. - - parameter itemIndex: the index for the object within the section. Using an `itemIndex` with an invalid range will raise an exception. - - returns: the `NSManagedObject` at the specified section and item index - */ + @objc public func objectAtSectionIndex(_ sectionIndex: Int, itemIndex: Int) -> Any { - - return self.bridgeToSwift[sectionIndex, itemIndex] - } /** - Returns the object at the given section and item index, or `nil` if out of bounds. This indexer is typically used for `CSListMonitor`s created as sectioned lists. - - - parameter sectionIndex: the section index for the object. Using a `sectionIndex` with an invalid range will return `nil`. - - parameter itemIndex: the index for the object within the section. Using an `itemIndex` with an invalid range will return `nil`. - - returns: the `NSManagedObject` at the specified section and item index, or `nil` if out of bounds - */ + + fatalError() + } + @objc public func objectAtSafeSectionIndex(_ sectionIndex: Int, safeItemIndex itemIndex: Int) -> Any? { - - return self.bridgeToSwift[safeSectionIndex: sectionIndex, safeItemIndex: itemIndex] + + fatalError() } - - /** - Returns the object at the given `NSIndexPath`. This subscript indexer is typically used for `CSListMonitor`s created as sectioned lists. - - - parameter indexPath: the `NSIndexPath` for the object. Using an `indexPath` with an invalid range will raise an exception. - - returns: the `NSManagedObject` at the specified index path - */ + @objc public func objectAtIndexPath(_ indexPath: IndexPath) -> Any { - - return self.bridgeToSwift[indexPath] + + fatalError() } - - /** - Returns the object at the given `NSIndexPath`, or `nil` if out of bounds. This subscript indexer is typically used for `CSListMonitor`s created as sectioned lists. - - - parameter indexPath: the `NSIndexPath` for the object. Using an `indexPath` with an invalid range will return `nil`. - - returns: the `NSManagedObject` at the specified index path, or `nil` if out of bounds - */ + @objc public func objectAtSafeIndexPath(_ indexPath: IndexPath) -> Any? { - - return self.bridgeToSwift[safeIndexPath: indexPath] + + fatalError() } - - /** - Checks if the `CSListMonitor` has at least one object in any section. - - - returns: `YES` if at least one object in any section exists, `NO` otherwise - */ + @objc public func hasObjects() -> Bool { - - return self.bridgeToSwift.hasObjects() + + fatalError() } - - /** - Checks if the `CSListMonitor` has at least one object the specified section. - - - parameter section: the section index. Using an index outside the valid range will return `NO`. - - returns: `YES` if at least one object in the specified section exists, `NO` otherwise - */ + @objc public func hasObjectsInSection(_ section: Int) -> Bool { - - return self.bridgeToSwift.hasObjects(in: section) + + fatalError() } - - /** - Returns all objects in all sections - - - returns: all objects in all sections - */ + @objc public func objectsInAllSections() -> [NSManagedObject] { - - return self.bridgeToSwift.objectsInAllSections() + + fatalError() } - - /** - Returns all objects in the specified section - - - parameter section: the section index. Using an index outside the valid range will raise an exception. - - returns: all objects in the specified section - */ + @objc public func objectsInSection(_ section: Int) -> [NSManagedObject] { - - return self.bridgeToSwift.objects(in: section) + + fatalError() } - - /** - Returns all objects in the specified section, or `nil` if out of bounds. - - - parameter section: the section index. Using an index outside the valid range will return `nil`. - - returns: all objects in the specified section, or `nil` if out of bounds - */ + @objc public func objectsInSafeSection(safeSectionIndex section: Int) -> [NSManagedObject]? { - - return self.bridgeToSwift.objects(safelyIn: section) + + fatalError() } - /** - Returns the number of sections - - - returns: the number of sections - */ @objc public func numberOfSections() -> Int { - - return self.bridgeToSwift.numberOfSections() - } - - /** - Returns the number of objects in all sections - - - returns: the number of objects in all sections - */ - @objc - public func numberOfObjects() -> Int { - - return self.bridgeToSwift.numberOfObjects() + + fatalError() + } + + @objc + public func numberOfObjects() -> Int { + + fatalError() } - /** - Returns the number of objects in the specified section - - - parameter section: the section index. Using an index outside the valid range will raise an exception. - - returns: the number of objects in the specified section - */ @objc public func numberOfObjectsInSection(_ section: Int) -> Int { - - return self.bridgeToSwift.numberOfObjects(in: section) + + fatalError() } - - /** - Returns the number of objects in the specified section, or `nil` if out of bounds. - - - parameter section: the section index. Using an index outside the valid range will return `nil`. - - returns: the number of objects in the specified section, or `nil` if out of bounds - */ + @objc public func numberOfObjectsInSafeSection(safeSectionIndex section: Int) -> NSNumber? { - - return self.bridgeToSwift - .numberOfObjects(safelyIn: section) - .flatMap { NSNumber(value: $0) } + + fatalError() } - - /** - Returns the `NSFetchedResultsSectionInfo` for the specified section - - - parameter section: the section index. Using an index outside the valid range will raise an exception. - - returns: the `NSFetchedResultsSectionInfo` for the specified section - */ + @objc public func sectionInfoAtIndex(_ section: Int) -> NSFetchedResultsSectionInfo { - - return self.bridgeToSwift.sectionInfo(at: section) + + fatalError() } - - /** - Returns the `NSFetchedResultsSectionInfo` for the specified section, or `nil` if out of bounds. - - - parameter section: the section index. Using an index outside the valid range will return `nil`. - - returns: the `NSFetchedResultsSectionInfo` for the specified section, or `nil` if the section index is out of bounds. - */ + @objc public func sectionInfoAtSafeSectionIndex(safeSectionIndex section: Int) -> NSFetchedResultsSectionInfo? { - - return self.bridgeToSwift.sectionInfo(safelyAt: section) + + fatalError() } - - /** - Returns the `NSFetchedResultsSectionInfo`s for all sections - - - returns: the `NSFetchedResultsSectionInfo`s for all sections - */ + @objc public func sections() -> [NSFetchedResultsSectionInfo] { - - return self.bridgeToSwift.sections() + + fatalError() } - - /** - Returns the target section for a specified "Section Index" title and index. - - - parameter title: the title of the Section Index - - parameter index: the index of the Section Index - - returns: the target section for the specified "Section Index" title and index. - */ + @objc public func targetSectionForSectionIndexTitle(title: String, index: Int) -> Int { - - return self.bridgeToSwift.targetSection(forSectionIndexTitle: title, at: index) + + fatalError() } - - /** - Returns the section index titles for all sections - - - returns: the section index titles for all sections - */ + @objc public func sectionIndexTitles() -> [String] { - - return self.bridgeToSwift.sectionIndexTitles() + + fatalError() } - - /** - Returns the index of the `NSManagedObject` if it exists in the `CSListMonitor`'s fetched objects, or `nil` if not found. - - - parameter object: the `NSManagedObject` to search the index of - - returns: the index of the `NSManagedObject` if it exists in the `CSListMonitor`'s fetched objects, or `nil` if not found. - */ + @objc public func indexOf(_ object: NSManagedObject) -> NSNumber? { - - return self.bridgeToSwift - .index(of: object) - .flatMap { NSNumber(value: $0) } + + fatalError() } - - /** - Returns the `NSIndexPath` of the `NSManagedObject` if it exists in the `CSListMonitor`'s fetched objects, or `nil` if not found. - - - parameter object: the `NSManagedObject` to search the index of - - returns: the `NSIndexPath` of the `NSManagedObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found. - */ + @objc public func indexPathOf(_ object: NSManagedObject) -> IndexPath? { - - return self.bridgeToSwift.indexPath(of: object) + + fatalError() } // MARK: Public (Observers) - - /** - Registers a `CSListObserver` to be notified when changes to the receiver's list occur. - - To prevent retain-cycles, `CSListMonitor` only keeps `weak` references to its observers. - - For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread. - - Calling `-addListObserver:` multiple times on the same observer is safe, as `CSListMonitor` unregisters previous notifications to the observer before re-registering them. - - - parameter observer: a `CSListObserver` to send change notifications to - */ + @objc public func addListObserver(_ observer: CSListObserver) { - - let swift = self.bridgeToSwift - swift.unregisterObserver(observer) - swift.registerObserver( - observer, - willChange: { (observer, monitor) in - - observer.listMonitorWillChange?(monitor.bridgeToObjectiveC) - }, - didChange: { (observer, monitor) in - - observer.listMonitorDidChange?(monitor.bridgeToObjectiveC) - }, - willRefetch: { (observer, monitor) in - - observer.listMonitorWillRefetch?(monitor.bridgeToObjectiveC) - }, - didRefetch: { (observer, monitor) in - - observer.listMonitorDidRefetch?(monitor.bridgeToObjectiveC) - } - ) + + fatalError() } - - /** - Registers a `CSListObjectObserver` to be notified when changes to the receiver's list occur. - - To prevent retain-cycles, `CSListMonitor` only keeps `weak` references to its observers. - - For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread. - - Calling `-addListObjectObserver:` multiple times on the same observer is safe, as `ListMonitor` unregisters previous notifications to the observer before re-registering them. - - - parameter observer: a `CSListObjectObserver` to send change notifications to - */ + public func addListObjectObserver(_ observer: CSListObjectObserver) { - - let swift = self.bridgeToSwift - swift.unregisterObserver(observer) - swift.registerObserver( - observer, - willChange: { (observer, monitor) in - - observer.listMonitorWillChange?(monitor.bridgeToObjectiveC) - }, - didChange: { (observer, monitor) in - - observer.listMonitorDidChange?(monitor.bridgeToObjectiveC) - }, - willRefetch: { (observer, monitor) in - - observer.listMonitorWillRefetch?(monitor.bridgeToObjectiveC) - }, - didRefetch: { (observer, monitor) in - - observer.listMonitorDidRefetch?(monitor.bridgeToObjectiveC) - } - ) - swift.registerObserver( - observer, - didInsertObject: { (observer, monitor, object, toIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didInsertObject: object, toIndexPath: toIndexPath) - }, - didDeleteObject: { (observer, monitor, object, fromIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didDeleteObject: object, fromIndexPath: fromIndexPath) - }, - didUpdateObject: { (observer, monitor, object, atIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didUpdateObject: object, atIndexPath: atIndexPath) - }, - didMoveObject: { (observer, monitor, object, fromIndexPath, toIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didMoveObject: object, fromIndexPath: fromIndexPath, toIndexPath: toIndexPath) - } - ) + + fatalError() } - - /** - Registers a `CSListSectionObserver` to be notified when changes to the receiver's list occur. - - To prevent retain-cycles, `CSListMonitor` only keeps `weak` references to its observers. - - For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread. - - Calling `-addListSectionObserver:` multiple times on the same observer is safe, as `ListMonitor` unregisters previous notifications to the observer before re-registering them. - - - parameter observer: a `CSListSectionObserver` to send change notifications to - */ + @objc public func addListSectionObserver(_ observer: CSListSectionObserver) { - - let swift = self.bridgeToSwift - swift.unregisterObserver(observer) - swift.registerObserver( - observer, - willChange: { (observer, monitor) in - - observer.listMonitorWillChange?(monitor.bridgeToObjectiveC) - }, - didChange: { (observer, monitor) in - - observer.listMonitorDidChange?(monitor.bridgeToObjectiveC) - }, - willRefetch: { (observer, monitor) in - - observer.listMonitorWillRefetch?(monitor.bridgeToObjectiveC) - }, - didRefetch: { (observer, monitor) in - - observer.listMonitorDidRefetch?(monitor.bridgeToObjectiveC) - } - ) - swift.registerObserver( - observer, - didInsertObject: { (observer, monitor, object, toIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didInsertObject: object, toIndexPath: toIndexPath) - }, - didDeleteObject: { (observer, monitor, object, fromIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didDeleteObject: object, fromIndexPath: fromIndexPath) - }, - didUpdateObject: { (observer, monitor, object, atIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didUpdateObject: object, atIndexPath: atIndexPath) - }, - didMoveObject: { (observer, monitor, object, fromIndexPath, toIndexPath) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didMoveObject: object, fromIndexPath: fromIndexPath, toIndexPath: toIndexPath) - } - ) - swift.registerObserver( - observer, - didInsertSection: { (observer, monitor, sectionInfo, toIndex) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didInsertSection: sectionInfo, toSectionIndex: toIndex) - }, - didDeleteSection: { (observer, monitor, sectionInfo, fromIndex) in - - observer.listMonitor?(monitor.bridgeToObjectiveC, didDeleteSection: sectionInfo, fromSectionIndex: fromIndex) - } - ) + + fatalError() } - - /** - Unregisters a `CSListObserver` from receiving notifications for changes to the receiver's list. - - For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread. - - - parameter observer: a `CSListObserver` to unregister notifications to - */ + @objc public func removeListObserver(_ observer: CSListObserver) { - - self.bridgeToSwift.unregisterObserver(observer) + + fatalError() } // MARK: Public (Refetching) - - /** - Returns `YES` if a call to `-refetch:` was made to the `CSListMonitor` and is currently waiting for the fetching to complete. Returns `NO` otherwise. - */ + @objc public var isPendingRefetch: Bool { - - return self.bridgeToSwift.isPendingRefetch + + fatalError() } - - /** - Asks the `CSListMonitor` to refetch its objects using the specified series of `CSFetchClause`s. Note that this method does not execute the fetch immediately; the actual fetching will happen after the `NSFetchedResultsController`'s last `controllerDidChangeContent(_:)` notification completes. - - `refetch(...)` broadcasts `listMonitorWillRefetch(...)` to its observers immediately, and then `listMonitorDidRefetch(...)` after the new fetch request completes. - - - parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - - Important: Starting CoreStore 4.0, all `CSFetchClause`s required by the `CSListMonitor` should be provided in the arguments list of `refetch(...)`. - */ + @objc public func refetch(_ fetchClauses: [CSFetchClause]) { - - self.bridgeToSwift.refetch { (fetchRequest) in - - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - } + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSListMonitor else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -536,33 +234,21 @@ public final class CSListMonitor: NSObject { @nonobjc public required init(_ swiftValue: ListMonitor) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - ListMonitor +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension ListMonitor where ListMonitor.ObjectType: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSListMonitor { - - return CSListMonitor(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> ListMonitor { - - func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { - - return unsafeBitCast(x, to: type) - } - return noWarnUnsafeBitCast(self, to: ListMonitor.self) + + fatalError() } } diff --git a/Sources/CSListObserver.swift b/Sources/CSListObserver.swift index 8c48e7f..2f1723a 100644 --- a/Sources/CSListObserver.swift +++ b/Sources/CSListObserver.swift @@ -29,49 +29,19 @@ import CoreData // MARK: - CSListObserver -/** - Implement the `CSListObserver` protocol to observe changes to a list of `NSManagedObject`s. `CSListObserver`s may register themselves to a `CSListMonitor`'s `-addListObserver:` method: - ``` - CSListMonitor *monitor = [CSCoreStore - monitorListFrom:[CSFrom entityClass:[MyPersonEntity class]] - fetchClauses:@[[CSOrderBy sortDescriptor:[CSSortKey withKeyPath:@"lastName" ascending:YES]]]]; - [monitor addListObserver:self]; - ``` - - - SeeAlso: `ListObserver` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSListObserver: AnyObject { - - /** - Handles processing just before a change to the observed list occurs - - - parameter monitor: the `CSListMonitor` monitoring the list being observed - */ + @objc optional func listMonitorWillChange(_ monitor: CSListMonitor) - - /** - Handles processing right after a change to the observed list occurs - - - parameter monitor: the `CSListMonitor` monitoring the object being observed - */ + @objc optional func listMonitorDidChange(_ monitor: CSListMonitor) - - /** - This method is broadcast from within the `CSListMonitor`'s `-refetchWithFetchClauses:` method to let observers prepare for the internal `NSFetchedResultsController`'s pending change to its predicate, sort descriptors, etc. Note that the actual refetch will happen after the `NSFetchedResultsController`'s last `-controllerDidChangeContent:` notification completes. - - - parameter monitor: the `CSListMonitor` monitoring the object being observed - */ + @objc optional func listMonitorWillRefetch(_ monitor: CSListMonitor) - - /** - After the `CSListMonitor`'s `-refetchWithFetchClauses:` method is called, this method is broadcast after the `NSFetchedResultsController`'s last `-controllerDidChangeContent:` notification completes. - - - parameter monitor: the `CSListMonitor` monitoring the object being observed - */ + @objc optional func listMonitorDidRefetch(_ monitor: CSListMonitor) } @@ -79,58 +49,19 @@ public protocol CSListObserver: AnyObject { // MARK: - ListObjectObserver -/** - Implement the `CSListObjectObserver` protocol to observe detailed changes to a list's object. `CSListObjectObserver`s may register themselves to a `CSListMonitor`'s `-addListObjectObserver(_:)` method: - ``` - CSListMonitor *monitor = [CSCoreStore - monitorListFrom:[CSFrom entityClass:[MyPersonEntity class]] - fetchClauses:@[[CSOrderBy sortDescriptor:[CSSortKey withKeyPath:@"lastName" ascending:YES]]]]; - [monitor addListObjectObserver:self]; - ``` - - - SeeAlso: `ListObjectObserver` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSListObjectObserver: CSListObserver { - - /** - Notifies that an object was inserted to the specified `NSIndexPath` in the list - - - parameter monitor: the `CSListMonitor` monitoring the list being observed - - parameter object: the entity type for the inserted object - - parameter indexPath: the new `NSIndexPath` for the inserted object - */ + @objc optional func listMonitor(_ monitor: CSListMonitor, didInsertObject object: Any, toIndexPath indexPath: IndexPath) - - /** - Notifies that an object was deleted from the specified `NSIndexPath` in the list - - - parameter monitor: the `CSListMonitor` monitoring the list being observed - - parameter object: the entity type for the deleted object - - parameter indexPath: the `NSIndexPath` for the deleted object - */ + @objc optional func listMonitor(_ monitor: CSListMonitor, didDeleteObject object: Any, fromIndexPath indexPath: IndexPath) - - /** - Notifies that an object at the specified `NSIndexPath` was updated - - - parameter monitor: the `CSListMonitor` monitoring the list being observed - - parameter object: the entity type for the updated object - - parameter indexPath: the `NSIndexPath` for the updated object - */ + @objc optional func listMonitor(_ monitor: CSListMonitor, didUpdateObject object: Any, atIndexPath indexPath: IndexPath) - - /** - Notifies that an object's index changed - - - parameter monitor: the `CSListMonitor` monitoring the list being observed - - parameter object: the entity type for the moved object - - parameter fromIndexPath: the previous `NSIndexPath` for the moved object - - parameter toIndexPath: the new `NSIndexPath` for the moved object - */ + @objc optional func listMonitor(_ monitor: CSListMonitor, didMoveObject object: Any, fromIndexPath: IndexPath, toIndexPath: IndexPath) } @@ -138,38 +69,13 @@ public protocol CSListObjectObserver: CSListObserver { // MARK: - CSListSectionObserver -/** - Implement the `CSListSectionObserver` protocol to observe changes to a list's section info. `CSListSectionObserver`s may register themselves to a `CSListMonitor`'s `-addListSectionObserver:` method: - ``` - CSListMonitor *monitor = [CSCoreStore - monitorSectionedListFrom:[CSFrom entityClass:[MyPersonEntity class]] - sectionBy:[CSSectionBy keyPath:@"age"] - fetchClauses:@[[CSOrderBy sortDescriptor:[CSSortKey withKeyPath:@"lastName" ascending:YES]]]]; - [monitor addListSectionObserver:self]; - ``` - - - SeeAlso: `ListSectionObserver` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSListSectionObserver: CSListObjectObserver { - - /** - Notifies that a section was inserted at the specified index - - - parameter monitor: the `CSListMonitor` monitoring the list being observed - - parameter sectionInfo: the `NSFetchedResultsSectionInfo` for the inserted section - - parameter sectionIndex: the new section index for the new section - */ + @objc optional func listMonitor(_ monitor: CSListMonitor, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) - /** - Notifies that a section was inserted at the specified index - - - parameter monitor: the `CSListMonitor` monitoring the list being observed - - parameter sectionInfo: the `NSFetchedResultsSectionInfo` for the deleted section - - parameter sectionIndex: the previous section index for the deleted section - */ @objc optional func listMonitor(_ monitor: CSListMonitor, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) } diff --git a/Sources/CSMigrationResult.swift b/Sources/CSMigrationResult.swift index 54cea1e..2d1ac06 100644 --- a/Sources/CSMigrationResult.swift +++ b/Sources/CSMigrationResult.swift @@ -29,134 +29,68 @@ import CoreData // MARK: - CSMigrationResult -/** - The `CSMigrationResult` serves as the Objective-C bridging type for `MigrationResult`. - - - SeeAlso: `MigrationResult` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType { - - /** - `YES` if the migration succeeded, `NO` otherwise - */ + @objc public var isSuccess: Bool { - - return (try? self.bridgeToSwift.get()) != nil + + fatalError() } - - /** - `YES` if the migration failed, `NO` otherwise - */ + @objc public var isFailure: Bool { return !self.isSuccess } - - /** - `YES` if the migration succeeded, `NO` otherwise - */ + @objc public var migrationTypes: [CSMigrationType]? { - - guard case .success(let migrationTypes) = self.bridgeToSwift else { - - return nil - } - return migrationTypes.map { $0.bridgeToObjectiveC } + + fatalError() } - - /** - The `NSError` for a failed migration, or `nil` if the migration succeeded - */ + @objc public var error: NSError? { - - guard case .failure(let error) = self.bridgeToSwift else { - - return nil - } - return error.bridgeToObjectiveC + + fatalError() } - - /** - If the result was a success, the `success` block is executed with an array of `CSMigrationType`s that indicates the migration steps completed. If the result was a failure, the `failure` block is executed with an `NSError` argument pertaining to the actual error. - - The blocks are executed immediately as `@noescape` and will not be retained. - - - parameter success: the block to execute on success. The block passes an array of `CSMigrationType`s that indicates the migration steps completed. - - parameter failure: the block to execute on failure. The block passes an `NSError` argument that pertains to the actual error. - */ + @objc public func handleSuccess(_ success: (_ migrationTypes: [CSMigrationType]) -> Void, failure: (_ error: NSError) -> Void) { - - switch self.bridgeToSwift { - - case .success(let migrationTypes): - success(migrationTypes.map { $0.bridgeToObjectiveC }) - - case .failure(let error): - failure(error.bridgeToObjectiveC) - } + + fatalError() } - - /** - If the result was a success, the `success` block is executed with an array of `CSMigrationType`s that indicates the migration steps completed. If the result was a failure, this method does nothing. - - The block is executed immediately as `@noescape` and will not be retained. - - - parameter success: the block to execute on success. The block passes an array of `CSMigrationType`s that indicates the migration steps completed. - */ + @objc public func handleSuccess(_ success: (_ migrationTypes: [CSMigrationType]) -> Void) { - - guard case .success(let migrationTypes) = self.bridgeToSwift else { - - return - } - success(migrationTypes.map { $0.bridgeToObjectiveC }) + + fatalError() } - - /** - If the result was a failure, the `failure` block is executed with an `NSError` argument pertaining to the actual error. If the result was a success, this method does nothing. - - The block is executed immediately as `@noescape` and will not be retained. - - - parameter failure: the block to execute on failure. The block passes an `NSError` argument that pertains to the actual error. - */ + @objc public func handleFailure(_ failure: (_ error: NSError) -> Void) { - - guard case .failure(let error) = self.bridgeToSwift else { - - return - } - failure(error.bridgeToObjectiveC) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSMigrationResult else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -165,22 +99,21 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType { public let bridgeToSwift: MigrationResult public required init(_ swiftValue: MigrationResult) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - MigrationResult -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension MigrationResult { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSMigrationResult { - - return CSMigrationResult(self) + + fatalError() } } diff --git a/Sources/CSMigrationType.swift b/Sources/CSMigrationType.swift index 9669c32..129321a 100644 --- a/Sources/CSMigrationType.swift +++ b/Sources/CSMigrationType.swift @@ -29,80 +29,56 @@ import CoreData // MARK: - CSMigrationType -/** - The `CSMigrationType` serves as the Objective-C bridging type for `MigrationType`. - - - SeeAlso: `MigrationType` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSMigrationType: NSObject, CoreStoreObjectiveCType { - - /** - Returns `YES` if the `CSMigrationType`'s `sourceVersion` and `destinationVersion` do not match. Returns `NO` otherwise. - */ + @objc public var needsMigration: Bool { - - return self.bridgeToSwift.hasMigration + + fatalError() } - - /** - Returns the source model version for the migration type. If no migration is required, `sourceVersion` will be equal to the `destinationVersion`. - */ + @objc public var sourceVersion: String { - - return self.bridgeToSwift.sourceVersion + + fatalError() } - - /** - Returns the destination model version for the migration type. If no migration is required, `destinationVersion` will be equal to the `sourceVersion`. - */ + @objc public var destinationVersion: String { - - return self.bridgeToSwift.destinationVersion + + fatalError() } - - /** - Returns `YES` if the `CSMigrationType` is a lightweight migration. Used as syntactic sugar. - */ + @objc public var isLightweightMigration: Bool { - - return self.bridgeToSwift.isLightweightMigration + + fatalError() } - - /** - Returns `YES` if the `CSMigrationType` is a heavyweight migration. Used as syntactic sugar. - */ + @objc public var isHeavyweightMigration: Bool { - - return self.bridgeToSwift.isHeavyweightMigration + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSMigrationType else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -111,22 +87,21 @@ public final class CSMigrationType: NSObject, CoreStoreObjectiveCType { public let bridgeToSwift: MigrationType public required init(_ swiftValue: MigrationType) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - MigrationType -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension MigrationType: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSMigrationType { - - return CSMigrationType(self) + + fatalError() } } diff --git a/Sources/CSObjectMonitor.swift b/Sources/CSObjectMonitor.swift index 41f78c5..e2d466d 100644 --- a/Sources/CSObjectMonitor.swift +++ b/Sources/CSObjectMonitor.swift @@ -29,72 +29,28 @@ import CoreData // MARK: - CSObjectMonitor -/** - The `CSObjectMonitor` serves as the Objective-C bridging type for `ObjectMonitor`. - - - SeeAlso: `ObjectMonitor` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSObjectMonitor: NSObject { - /** - Returns the `NSManagedObject` instance being observed, or `nil` if the object was already deleted. - */ public var object: Any? { - - return self.bridgeToSwift.object + + fatalError() } - - /** - Returns `YES` if the `NSManagedObject` instance being observed still exists, or `NO` if the object was already deleted. - */ + public var isObjectDeleted: Bool { - - return self.bridgeToSwift.isObjectDeleted + + fatalError() } - - /** - Registers a `CSObjectObserver` to be notified when changes to the receiver's `object` are made. - - To prevent retain-cycles, `CSObjectMonitor` only keeps `weak` references to its observers. - - For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread. - - Calling `-addObjectObserver:` multiple times on the same observer is safe, as `CSObjectMonitor` unregisters previous notifications to the observer before re-registering them. - - - parameter observer: an `CSObjectObserver` to send change notifications to - */ + public func addObjectObserver(_ observer: CSObjectObserver) { - - let swift = self.bridgeToSwift - swift.unregisterObserver(observer) - swift.registerObserver( - observer, - willChangeObject: { (observer, monitor, object) in - - observer.objectMonitor?(monitor.bridgeToObjectiveC, willUpdateObject: object) - }, - didDeleteObject: { (observer, monitor, object) in - - observer.objectMonitor?(monitor.bridgeToObjectiveC, didDeleteObject: object) - }, - didUpdateObject: { (observer, monitor, object, changedPersistentKeys) in - - observer.objectMonitor?(monitor.bridgeToObjectiveC, didUpdateObject: object, changedPersistentKeys: changedPersistentKeys) - } - ) + + fatalError() } - - /** - Unregisters an `CSObjectObserver` from receiving notifications for changes to the receiver's `object`. - - For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread. - - - parameter observer: an `CSObjectObserver` to unregister notifications to - */ + public func removeObjectObserver(_ observer: CSObjectObserver) { - - self.bridgeToSwift.unregisterObserver(observer) + + fatalError() } @@ -102,23 +58,17 @@ public final class CSObjectMonitor: NSObject { public override var hash: Int { - var hasher = Hasher() - self.bridgeToSwift.hash(into: &hasher) - return hasher.finalize() + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSObjectMonitor else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -129,33 +79,21 @@ public final class CSObjectMonitor: NSObject { @nonobjc public required init(_ swiftValue: ObjectMonitor) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - ObjectMonitor +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension ObjectMonitor where ObjectMonitor.ObjectType: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSObjectMonitor { - - return CSObjectMonitor(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> ObjectMonitor { - - func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { - - return unsafeBitCast(x, to: type) - } - return noWarnUnsafeBitCast(self, to: ObjectMonitor.self) + + fatalError() } } diff --git a/Sources/CSObjectObserver.swift b/Sources/CSObjectObserver.swift index 3490882..5ad1006 100644 --- a/Sources/CSObjectObserver.swift +++ b/Sources/CSObjectObserver.swift @@ -29,43 +29,16 @@ import CoreData // MARK: - CSObjectObserver -/** - Implement the `CSObjectObserver` protocol to observe changes to a single `NSManagedObject` instance. `CSObjectObserver`s may register themselves to a `CSObjectMonitor`'s `-addObjectObserver:` method: - ``` - CSObjectMonitor *monitor = [CSCoreStore monitorObject:myObject]; - [monitor addObjectObserver:self]; - ``` - - - SeeAlso: `ObjectObserver` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSObjectObserver: AnyObject { - /** - Handles processing just before a change to the observed `object` occurs - - - parameter monitor: the `CSObjectMonitor` monitoring the object being observed - - parameter object: the `NSManagedObject` instance being observed - */ @objc optional func objectMonitor(_ monitor: CSObjectMonitor, willUpdateObject object: Any) - - /** - Handles processing right after a change to the observed `object` occurs - - - parameter monitor: the `CSObjectMonitor` monitoring the object being observed - - parameter object: the `NSManagedObject` instance being observed - - parameter changedPersistentKeys: an `NSSet` of key paths for the attributes that were changed. Note that `changedPersistentKeys` only contains keys for attributes/relationships present in the persistent store, thus transient properties will not be reported. - */ + @objc optional func objectMonitor(_ monitor: CSObjectMonitor, didUpdateObject object: Any, changedPersistentKeys: Set) - - /** - Handles processing right after `object` is deleted - - - parameter monitor: the `CSObjectMonitor` monitoring the object being observed - - parameter object: the `NSManagedObject` instance being observed - */ + @objc optional func objectMonitor(_ monitor: CSObjectMonitor, didDeleteObject object: Any) } diff --git a/Sources/CSOrderBy.swift b/Sources/CSOrderBy.swift index 7355596..ee74ce0 100644 --- a/Sources/CSOrderBy.swift +++ b/Sources/CSOrderBy.swift @@ -29,73 +29,44 @@ import CoreData // MARK: - CSOrderBy -/** - The `CSOrderBy` serves as the Objective-C bridging type for `OrderBy`. - - - SeeAlso: `OrderBy` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause { - /** - The list of sort descriptors - */ @objc public var sortDescriptors: [NSSortDescriptor] { - - return self.bridgeToSwift.sortDescriptors + + fatalError() } - - /** - Initializes a `CSOrderBy` clause with a single sort descriptor - ``` - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderByKey(CSSortAscending(@"fullname"))]]]; - ``` - - parameter sortDescriptor: a `NSSortDescriptor` - */ + @objc public convenience init(sortDescriptor: NSSortDescriptor) { - - self.init(OrderBy(sortDescriptor)) + + fatalError() } - - /** - Initializes a `CSOrderBy` clause with a list of sort descriptors - ``` - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderByKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]]; - ``` - - parameter sortDescriptors: an array of `NSSortDescriptor`s - */ + @objc public convenience init(sortDescriptors: [NSSortDescriptor]) { - - self.init(OrderBy(sortDescriptors)) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSOrderBy else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -103,8 +74,8 @@ public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteCl @objc public func applyToFetchRequest(_ fetchRequest: NSFetchRequest) { - - self.bridgeToSwift.applyToFetchRequest(fetchRequest) + + fatalError() } @@ -113,29 +84,21 @@ public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteCl public let bridgeToSwift: OrderBy public init(_ swiftValue: OrderBy) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - OrderBy +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension OrderBy where O: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSOrderBy { - - return CSOrderBy(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> OrderBy { - - return OrderBy(self.sortDescriptors) + + fatalError() } } diff --git a/Sources/CSSQliteStore.swift b/Sources/CSSQliteStore.swift index b786bf3..b6fdf5a 100644 --- a/Sources/CSSQliteStore.swift +++ b/Sources/CSSQliteStore.swift @@ -29,157 +29,88 @@ import CoreData // MARK: - CSSQLiteStore -/** - The `CSSQLiteStore` serves as the Objective-C bridging type for `SQLiteStore`. - - - SeeAlso: `SQLiteStore` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCType { - - /** - Initializes an SQLite store interface from the given SQLite file URL. When this instance is passed to the `CSDataStack`'s `-addStorage*:` methods, a new SQLite file will be created if it does not exist. - - - Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property. - - parameter fileURL: the local file URL for the target SQLite persistent store. Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them. - - parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them. - - parameter localStorageOptions: When the `CSSQLiteStore` is passed to the `CSDataStack`'s `addStorage()` methods, tells the `CSDataStack` how to setup the persistent store. Defaults to `CSLocalStorageOptionsNone`. - */ + @objc public convenience init(fileURL: URL, configuration: ModelConfiguration, localStorageOptions: Int) { - - self.init( - SQLiteStore( - fileURL: fileURL, - configuration: configuration, - localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions) - ) - ) + + fatalError() } - - /** - Initializes an SQLite store interface from the given SQLite file name. When this instance is passed to the `CSDataStack`'s `-addStorage*:` methods, a new SQLite file will be created if it does not exist. - - - Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property. - - parameter fileName: the local filename for the SQLite persistent store in the "Application Support/" directory (or the "Caches/" directory on tvOS). Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them. - - parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them. - - parameter localStorageOptions: When the `CSSQLiteStore` is passed to the `CSDataStack`'s `addStorage()` methods, tells the `CSDataStack` how to setup the persistent store. Defaults to `[CSLocalStorageOptions none]`. - */ + @objc public convenience init(fileName: String, configuration: ModelConfiguration, localStorageOptions: Int) { - - self.init( - SQLiteStore( - fileName: fileName, - configuration: configuration, - localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions) - ) - ) + + fatalError() } - - /** - Initializes an `CSSQLiteStore` with an all-default settings: a `fileURL` pointing to a ".sqlite" file in the "Application Support/" directory (or the "Caches/" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, and `localStorageOptions` set to `[CSLocalStorageOptions none]`. - - - Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property. - */ + @objc public convenience override init() { - - self.init(SQLiteStore()) + + fatalError() } // MAKR: CSLocalStorage - - /** - The `NSURL` that points to the SQLite file - */ + @objc public var fileURL: URL { - - return self.bridgeToSwift.fileURL as URL + + fatalError() } - - /** - An array of `SchemaMappingProvider`s that provides the complete mapping models for custom migrations. This is currently only supported for Swift code. - */ + @objc public var migrationMappingProviders: [Any] { - - return self.bridgeToSwift.migrationMappingProviders + + fatalError() } - - /** - Options that tell the `CSDataStack` how to setup the persistent store - */ + @objc public var localStorageOptions: Int { - - return self.bridgeToSwift.localStorageOptions.rawValue + + fatalError() } // MARK: CSStorageInterface - - /** - The string identifier for the `NSPersistentStore`'s `type` property. For `CSSQLiteStore`s, this is always set to `NSSQLiteStoreType`. - */ + @objc public static let storeType = NSSQLiteStoreType - - /** - The configuration name in the model file - */ + public var configuration: ModelConfiguration { - - return self.bridgeToSwift.configuration + + fatalError() } - - /** - The options dictionary for the `NSPersistentStore`. For `CSSQLiteStore`s, this is always set to - ``` - [NSSQLitePragmasOption: ["journal_mode": "WAL"]] - ``` - */ + @objc public var storeOptions: [AnyHashable: Any]? { - - return self.bridgeToSwift.storeOptions + + fatalError() } - - /** - Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `CSSQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file. - */ + @objc public func cs_eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool { - - return bridge(error) { - - try self.bridgeToSwift.cs_eraseStorageAndWait(metadata: metadata as! [String: Any], soureModelHint: soureModelHint) - } + + fatalError() } // MARK: NSObject public override var hash: Int { - - return ObjectIdentifier(self.bridgeToSwift).hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSSQLiteStore else { - - return false - } - return self.bridgeToSwift === object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -188,22 +119,21 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT public let bridgeToSwift: SQLiteStore public required init(_ swiftValue: SQLiteStore) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - SQLiteStore -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension SQLiteStore: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSSQLiteStore { - - return CSSQLiteStore(self) + + fatalError() } } diff --git a/Sources/CSSectionBy.swift b/Sources/CSSectionBy.swift index b7363c6..4777132 100644 --- a/Sources/CSSectionBy.swift +++ b/Sources/CSSectionBy.swift @@ -29,50 +29,28 @@ import CoreData // MARK: - CSSectionBy -/** - The `CSSectionBy` serves as the Objective-C bridging type for `SectionBy`. - - - SeeAlso: `SectionBy` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSSectionBy: NSObject { - - /** - Initializes a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections - - - parameter sectionKeyPath: the key path to use to group the objects into sections - - returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections - */ + @objc public static func keyPath(_ sectionKeyPath: KeyPathString) -> CSSectionBy { - - return self.init(SectionBy(sectionKeyPath)) + + fatalError() } - - /** - Initializes a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title - - - parameter sectionKeyPath: the key path to use to group the objects into sections - - parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title - - returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections - */ + @objc public static func keyPath(_ sectionKeyPath: KeyPathString, sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> CSSectionBy { - - return self.init( - SectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - ) + + fatalError() } // MARK: NSObject public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -81,32 +59,21 @@ public final class CSSectionBy: NSObject { public let bridgeToSwift: SectionBy public init(_ swiftValue: SectionBy) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - SectionBy +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension SectionBy { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSSectionBy { - - return CSSectionBy(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> SectionBy { - - return SectionBy( - self.sectionKeyPath, - sectionIndexTransformer: self.sectionIndexTransformer - ) + + fatalError() } } diff --git a/Sources/CSSelect.swift b/Sources/CSSelect.swift index d41371f..4de397d 100644 --- a/Sources/CSSelect.swift +++ b/Sources/CSSelect.swift @@ -29,147 +29,63 @@ import CoreData // MARK: - CSSelectTerm -/** - The `CSSelectTerm` serves as the Objective-C bridging type for `SelectTerm`. - - - SeeAlso: `SelectTerm` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSSelectTerm: NSObject { - - /** - Provides a `CSSelectTerm` to a `CSSelect` clause for querying an entity attribute. - ``` - NSString *fullName = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:CSSelectString(CSAttribute(@"fullname")) - fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; - ``` - - parameter keyPath: the attribute name - */ + @objc public convenience init(keyPath: KeyPathString) { - self.init(.attribute(keyPath)) + fatalError() } - /** - Provides a `CSSelectTerm` to a `CSSelect` clause for querying the average value of an attribute. - ``` - NSNumber *averageAge = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect numberForTerm:[CSSelectTerm average:@"age" as:nil]]]; - ``` - - parameter keyPath: the attribute name - - parameter `as`: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "average()" is used - - returns: a `CSSelectTerm` to a `CSSelect` clause for querying the average value of an attribute - */ @objc public static func average(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm { - - return self.init(.average(keyPath, as: alias)) + + fatalError() } - /** - Provides a `CSSelectTerm` to a `CSSelect` clause for a count query. - ``` - NSNumber *numberOfEmployees = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect numberForTerm:[CSSelectTerm count:@"employeeID" as:nil]]]; - ``` - - parameter keyPath: the attribute name - - parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "count()" is used - - returns: a `SelectTerm` to a `Select` clause for a count query - */ @objc public static func count(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm { - - return self.init(.count(keyPath, as: alias)) + + fatalError() } - /** - Provides a `CSSelectTerm` to a `CSSelect` clause for querying the maximum value for an attribute. - ``` - NSNumber *maximumAge = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect numberForTerm:[CSSelectTerm maximum:@"age" as:nil]]]; - ``` - - parameter keyPath: the attribute name - - parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "max()" is used - - returns: a `CSSelectTerm` to a `CSSelect` clause for querying the maximum value for an attribute - */ @objc public static func maximum(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm { - - return self.init(.maximum(keyPath, as: alias)) + + fatalError() } - /** - Provides a `CSSelectTerm` to a `CSSelect` clause for querying the minimum value for an attribute. - ``` - NSNumber *minimumAge = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect numberForTerm:[CSSelectTerm minimum:@"age" as:nil]]]; - ``` - - parameter keyPath: the attribute name - - parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "min()" is used - - returns: a `CSSelectTerm` to a `CSSelect` clause for querying the minimum value for an attribute - */ @objc public static func minimum(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm { - - return self.init(.minimum(keyPath, as: alias)) + + fatalError() } - /** - Provides a `CSSelectTerm` to a `CSSelect` clause for querying the sum value for an attribute. - ``` - NSNumber *totalAge = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect numberForTerm:[CSSelectTerm sum:@"age" as:nil]]]; - ``` - - parameter keyPath: the attribute name - - parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "sum()" is used - - returns: a `CSSelectTerm` to a `CSSelect` clause for querying the sum value for an attribute - */ @objc public static func sum(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm { - - return self.init(.sum(keyPath, as: alias)) + + fatalError() } - - /** - Provides a `CSSelectTerm` to a `CSSelect` clause for querying the `NSManagedObjectID`. - ``` - NSManagedObjectID *objectID = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect objectIDForTerm:[CSSelectTerm objectIDAs:nil]] - fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; - ``` - - parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "objecID" is used - - returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute - */ + @objc public static func objectIDAs(_ alias: KeyPathString? = nil) -> CSSelectTerm { - - return self.init(.objectID(as: alias)) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSSelectTerm else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } @@ -178,344 +94,122 @@ public final class CSSelectTerm: NSObject { public let bridgeToSwift: SelectTerm public init(_ swiftValue: SelectTerm) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - SelectTerm +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension SelectTerm where O: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSSelectTerm { - - return CSSelectTerm(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> SelectTerm { - - switch self { - - case ._attribute(let keyPath): - return SelectTerm._attribute(keyPath) - - case ._aggregate(let function, let keyPath, let alias, let nativeType): - return SelectTerm._aggregate(function: function, keyPath: keyPath, alias: alias, nativeType: nativeType) - - case ._identity(let alias, let nativeType): - return SelectTerm._identity(alias: alias, nativeType: nativeType) - } + + fatalError() } } // MARK: - CSSelect -/** - The `CSSelect` serves as the Objective-C bridging type for `Select`. - - - SeeAlso: `Select` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSSelect: NSObject { - - /** - Creates a `CSSelect` clause for querying `NSNumber` values. - ``` - NSNumber *maxAge = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectNumber(CSAggregateMax(@"age")) - // ... - ``` - - parameter numberTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query - */ + @objc public convenience init(numberTerm: CSSelectTerm) { - - self.init(Select(numberTerm.bridgeToSwift)) + + fatalError() } - - /** - Creates a `CSSelect` clause for querying `NSDecimalNumber` values. - ``` - NSDecimalNumber *averagePrice = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectDecimal(CSAggregateAverage(@"price")) - // ... - ``` - - parameter decimalTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query - */ + @objc public convenience init(decimalTerm: CSSelectTerm) { - - self.init(Select(decimalTerm.bridgeToSwift)) + + fatalError() } - - /** - Creates a `CSSelect` clause for querying `NSString` values. - ``` - NSString *fullname = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectString(CSAttribute(@"fullname")) - // ... - ``` - - parameter stringTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query - */ + @objc public convenience init(stringTerm: CSSelectTerm) { - - self.init(Select(stringTerm.bridgeToSwift)) + + fatalError() } - - /** - Creates a `CSSelect` clause for querying `NSDate` values. - ``` - NSDate *lastUpdate = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectDate(CSAggregateMax(@"updatedDate")) - // ... - ``` - - parameter dateTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query - */ + @objc public convenience init(dateTerm: CSSelectTerm) { - - self.init(Select(dateTerm.bridgeToSwift)) + + fatalError() } - - /** - Creates a `CSSelect` clause for querying `NSData` values. - ``` - NSData *imageData = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectData(CSAttribute(@"imageData")) - // ... - ``` - - parameter dataTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query - */ + @objc public convenience init(dataTerm: CSSelectTerm) { - - self.init(Select(dataTerm.bridgeToSwift)) + + fatalError() } - - /** - Creates a `CSSelect` clause for querying `NSManagedObjectID` values. - ``` - NSManagedObjectID *objectID = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectObjectID() - // ... - ``` - */ + @objc public convenience init(objectIDTerm: ()) { - - self.init(Select(.objectID())) + + fatalError() } - - /** - Creates a `CSSelect` clause for querying `NSDictionary` of an entity's attribute keys and values. - ``` - NSDictionary *keyValues = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect dictionaryForTerm:[CSSelectTerm maximum:@"age" as:nil]]]; - ``` - - parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - - returns: a `CSSelect` clause for querying an entity attribute - */ + @objc public static func dictionaryForTerm(_ term: CSSelectTerm) -> CSSelect { - - return self.init(Select(term.bridgeToSwift)) + + fatalError() } - - /** - Creates a `CSSelect` clause for querying `NSDictionary` of an entity's attribute keys and values. - ``` - NSDictionary *keyValues = [CSCoreStore - queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect dictionaryForTerms:@[ - [CSSelectTerm attribute:@"name" as:nil], - [CSSelectTerm attribute:@"age" as:nil] - ]]]; - ``` - - parameter terms: the `CSSelectTerm`s specifying the attribute/aggregate values to query - - returns: a `CSSelect` clause for querying an entity attribute - */ + @objc public static func dictionaryForTerms(_ terms: [CSSelectTerm]) -> CSSelect { - - return self.init(Select(terms.map { $0.bridgeToSwift })) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.attributeType.hashValue - ^ self.selectTerms.map { $0.hashValue }.reduce(0, ^) + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSSelect else { - - return false - } - return self.attributeType == object.attributeType - && self.selectTerms == object.selectTerms + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } // MARK: CoreStoreObjectiveCType public init(_ swiftValue: Select) { - - self.attributeType = T.cs_rawAttributeType - self.selectTerms = swiftValue.selectTerms.map({ $0.downcast() }) - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } public init(_ swiftValue: Select) { - - self.attributeType = .undefinedAttributeType - self.selectTerms = swiftValue.selectTerms.map({ $0.downcast() }) - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } - - - // MARK: Internal - - internal let attributeType: NSAttributeType - internal let selectTerms: [SelectTerm] - - - // MARK: Internal - - internal func applyToFetchRequest(_ fetchRequest: NSFetchRequest) { - - fetchRequest.includesPendingChanges = false - fetchRequest.resultType = .dictionaryResultType - - func attributeDescription(for keyPath: String, in entity: NSEntityDescription) -> NSAttributeDescription? { - - let components = keyPath.components(separatedBy: ".") - switch components.count { - - case 0: - return nil - - case 1: - return entity.attributesByName[components[0]] - - default: - guard let relationship = entity.relationshipsByName[components[0]], - let destinationEntity = relationship.destinationEntity else { - - return nil - } - return attributeDescription( - for: components.dropFirst().joined(separator: "."), - in: destinationEntity - ) - } - } - - var propertiesToFetch = [Any]() - for term in self.selectTerms { - - switch term { - - case ._attribute(let keyPath): - propertiesToFetch.append(keyPath) - - case ._aggregate(let function, let keyPath, let alias, let nativeType): - let entityDescription = fetchRequest.entity! - if let attributeDescription = attributeDescription(for: keyPath, in: entityDescription) { - - let expressionDescription = NSExpressionDescription() - expressionDescription.name = alias - if nativeType == .undefinedAttributeType { - - expressionDescription.expressionResultType = attributeDescription.attributeType - } - else { - - expressionDescription.expressionResultType = nativeType - } - expressionDescription.expression = NSExpression( - forFunction: function, - arguments: [NSExpression(forKeyPath: keyPath)] - ) - propertiesToFetch.append(expressionDescription) - } - else { - - Internals.log( - .warning, - message: "The key path \"\(keyPath)\" could not be resolved in entity \(Internals.typeName(entityDescription.managedObjectClassName)) as an attribute and will be ignored by \(Internals.typeName(self)) query clause." - ) - } - - case ._identity(let alias, let nativeType): - let expressionDescription = NSExpressionDescription() - expressionDescription.name = alias - if nativeType == .undefinedAttributeType { - - expressionDescription.expressionResultType = .objectIDAttributeType - } - else { - - expressionDescription.expressionResultType = nativeType - } - expressionDescription.expression = NSExpression.expressionForEvaluatedObject() - - propertiesToFetch.append(expressionDescription) - } - } - - fetchRequest.propertiesToFetch = propertiesToFetch - } - - - // MARK: Private - - private let bridgeToSwift: CoreStoreDebugStringConvertible } // MARK: - Select +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension Select where O: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSSelect { - - return CSSelect(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> Select { - - return Select(self.selectTerms.map({ $0.downcast() })) + + fatalError() } } diff --git a/Sources/CSSetupResult.swift b/Sources/CSSetupResult.swift index cf5e788..55bb63d 100644 --- a/Sources/CSSetupResult.swift +++ b/Sources/CSSetupResult.swift @@ -29,162 +29,83 @@ import CoreData // MARK: - CSSetupResult -/** - The `CSSetupResult` serves as the Objective-C bridging type for `SetupResult`. - - - SeeAlso: `SetupResult` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSSetupResult: NSObject { - - /** - `YES` if adding the `CSStorageInterface` to the `CSDataStack` succeeded, `NO` otherwise. - */ + @objc public var isSuccess: Bool { - - return self.storage != nil + + fatalError() } - - /** - `YES` if adding the `CSStorageInterface` to the `CSDataStack` failed, `NO` otherwise. When `YES`, the `error` property returns the actual `NSError` for the failure. - */ + @objc public var isFailure: Bool { - - return self.storage == nil + + fatalError() } - - /** - A `CSStorageInterface` instance if the `commit` operation for the transaction succeeded. Returns `nil` otherwise. - */ + @objc public let storage: CSStorageInterface? - - /** - The `NSError` for a failed `commit` operation, or `nil` if the `commit` succeeded - */ + @objc public let error: NSError? - - /** - If the result was a success, the `success` block is executed with the `CSStorageInterface` instance that was added to the `CSDataStack`. If the result was a failure, the `failure` block is executed with an `NSError` argument pertaining to the actual error. - - The blocks are executed immediately as `@noescape` and will not be retained. - - - parameter success: the block to execute on success. The block passes a `CSStorageInterface` instance that was added to the `CSDataStack`. - - parameter failure: the block to execute on failure. The block passes an `NSError` argument that pertains to the actual error. - */ + @objc public func handleSuccess(_ success: (_ storage: CSStorageInterface) -> Void, failure: (_ error: NSError) -> Void) { - - if let storage = self.storage { - - success(storage) - } - else { - - failure(self.error!) - } + + fatalError() } - - /** - If the result was a success, the `success` block is executed with a `BOOL` argument that indicates if there were any changes made. If the result was a failure, this method does nothing. - - The block is executed immediately as `@noescape` and will not be retained. - - - parameter success: the block to execute on success. The block passes a `BOOL` argument that indicates if there were any changes made. - */ + @objc public func handleSuccess(_ success: (_ storage: CSStorageInterface) -> Void) { - - guard let storage = self.storage else { - - return - } - success(storage) + + fatalError() } - - /** - If the result was a failure, the `failure` block is executed with an `NSError` argument pertaining to the actual error. If the result was a success, this method does nothing. - - The block is executed immediately as `@noescape` and will not be retained. - - - parameter failure: the block to execute on failure. The block passes an `NSError` argument that pertains to the actual error. - */ + @objc public func handleFailure(_ failure: (_ error: NSError) -> Void) { - - guard let error = self.error else { - - return - } - failure(error) + + fatalError() } // MARK: NSObject public override var hash: Int { - - if let storage = self.storage { - - return self.isSuccess.hashValue ^ ObjectIdentifier(storage).hashValue - } - return self.isSuccess.hashValue ^ self.error!.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSSetupResult else { - - return false - } - return self.storage === object.storage - && self.error == object.error + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } // MARK: CoreStoreObjectiveCType public required init(_ swiftValue: SetupResult) where T: CoreStoreSwiftType, T.ObjectiveCType: CSStorageInterface { - - switch swiftValue { - - case .success(let storage): - self.storage = storage.bridgeToObjectiveC - self.error = nil - - case .failure(let error): - self.storage = nil - self.error = error.bridgeToObjectiveC - } - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } - - - // MARK: Private - - private let bridgeToSwift: CoreStoreDebugStringConvertible } // MARK: - SetupResult -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension SetupResult where Success: StorageInterface, Success: CoreStoreSwiftType, Success.ObjectiveCType: CSStorageInterface, Failure == CoreStoreError { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSSetupResult { - - return CSSetupResult(self) + + fatalError() } } diff --git a/Sources/CSStorageInterface.swift b/Sources/CSStorageInterface.swift index d8e0906..4a5d1c0 100644 --- a/Sources/CSStorageInterface.swift +++ b/Sources/CSStorageInterface.swift @@ -29,29 +29,16 @@ import CoreData // MARK: - CSStorageInterface -/** - The `CSStorageInterface` serves as the Objective-C bridging type for `StorageInterface`. - - - SeeAlso: `StorageInterface` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSStorageInterface { - - /** - The string identifier for the `NSPersistentStore`'s `type` property. This is the same string CoreStore will use to create the `NSPersistentStore` from the `NSPersistentStoreCoordinator`'s `addPersistentStoreWithType(...)` method. - */ + @objc static var storeType: String { get } - - /** - The configuration name in the model file - */ + @objc var configuration: ModelConfiguration { get } - - /** - The options dictionary for the `NSPersistentStore` - */ + @objc var storeOptions: [AnyHashable: Any]? { get } } @@ -59,67 +46,32 @@ public protocol CSStorageInterface { // MARK: - CSLocalStorageOptions -/** - The `CSLocalStorageOptions` provides settings that tells the `CSDataStack` how to setup the persistent store for `CSLocalStorage` implementers. - - - SeeAlso: `LocalStorageOptions` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public enum CSLocalStorageOptions: Int { - - /** - Tells the `DataStack` that the store should not be migrated or recreated, and should simply fail on model mismatch - */ + case none = 0 - - /** - Tells the `DataStack` to delete and recreate the store on model mismatch, otherwise exceptions will be thrown on failure instead - */ case recreateStoreOnModelMismatch = 1 - - /** - Tells the `DataStack` to prevent progressive migrations for the store - */ case preventProgressiveMigration = 2 - - /** - Tells the `DataStack` to allow lightweight migration for the store when added synchronously - */ case allowSynchronousLightweightMigration = 4 } // MARK: - CSLocalStorage -/** - The `CSLocalStorage` serves as the Objective-C bridging type for `LocalStorage`. - - - SeeAlso: `LocalStorage` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public protocol CSLocalStorage: CSStorageInterface { - - /** - The `NSURL` that points to the store file - */ + @objc var fileURL: URL { get } - - /** - An array of `SchemaMappingProvider`s that provides the complete mapping models for custom migrations. This is currently only supported for Swift code. - */ + @objc var migrationMappingProviders: [Any] { get } - - /** - Options that tell the `CSDataStack` how to setup the persistent store - */ + @objc var localStorageOptions: Int { get } - /** - Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (SQLite stores for example, can convert WAL journaling mode to DELETE before deleting) - */ @objc func cs_eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool } diff --git a/Sources/CSSynchronousDataTransaction.swift b/Sources/CSSynchronousDataTransaction.swift index bdabd8b..a60e155 100644 --- a/Sources/CSSynchronousDataTransaction.swift +++ b/Sources/CSSynchronousDataTransaction.swift @@ -29,103 +29,54 @@ import CoreData // MARK: - CSSynchronousDataTransaction -/** - The `CSSynchronousDataTransaction` serves as the Objective-C bridging type for `SynchronousDataTransaction`. - - - SeeAlso: `SynchronousDataTransaction` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSSynchronousDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType { - - /** - Saves the transaction changes and waits for completion synchronously. This method should not be used after the `-commitAndWaitWithError:` method was already called once. - - - parameter error: the `CSError` pointer that indicates the reason in case of an failure - - returns: `YES` if the commit succeeded, `NO` if the commit failed. If `NO`, the `error` argument will hold error information. - */ + @objc public func commitAndWait(error: NSErrorPointer) -> Bool { - - return bridge(error) { - - if case (_, let error?) = self.bridgeToSwift.context.saveSynchronously( - waitForMerge: true, - sourceIdentifier: nil - ) { - - throw error - } - } + + fatalError() } // MARK: NSObject public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } // MARK: BaseDataTransaction - - /** - Creates a new `NSManagedObject` with the specified entity type. - - - parameter into: the `CSInto` clause indicating the destination `NSManagedObject` entity type and the destination configuration - - returns: a new `NSManagedObject` instance of the specified entity type. - */ + @objc public override func createInto(_ into: CSInto) -> Any { - - return self.bridgeToSwift.create(into.bridgeToSwift) + + fatalError() } - - /** - Returns an editable proxy of a specified `NSManagedObject`. This method should not be used after the `-commitAndWait` method was already called once. - - - parameter object: the `NSManagedObject` type to be edited - - returns: an editable proxy for the specified `NSManagedObject`. - */ + @objc public override func editObject(_ object: NSManagedObject?) -> Any? { - - return self.bridgeToSwift.edit(object) + + fatalError() } - - /** - Returns an editable proxy of the object with the specified `NSManagedObjectID`. This method should not be used after the `-commitAndWait` method was already called once. - - - parameter into: a `CSInto` clause specifying the entity type - - parameter objectID: the `NSManagedObjectID` for the object to be edited - - returns: an editable proxy for the specified `NSManagedObject`. - */ + @objc public override func editInto(_ into: CSInto, objectID: NSManagedObjectID) -> Any? { - - return self.bridgeToSwift.edit(into.bridgeToSwift, objectID) + + fatalError() } - - /** - Deletes a specified `NSManagedObject`. This method should not be used after the `-commitAndWait` method was already called once. - - - parameter object: the `NSManagedObject` type to be deleted - */ + @objc public override func deleteObject(_ object: NSManagedObject?) { - - return self.bridgeToSwift.delete(object) + + fatalError() } - - /** - Deletes the specified `NSManagedObject`s. - - - parameter objects: the `NSManagedObject`s to be deleted - */ + public override func deleteObjects(_ objects: [NSManagedObject]) { - - self.bridgeToSwift.delete(objects) + + fatalError() } @@ -134,31 +85,26 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction, CoreStor public typealias SwiftType = SynchronousDataTransaction public var bridgeToSwift: SynchronousDataTransaction { - - return super.swiftTransaction as! SynchronousDataTransaction + + fatalError() } public required init(_ swiftValue: SynchronousDataTransaction) { - - super.init(swiftValue as BaseDataTransaction) - } - - public required override init(_ swiftValue: BaseDataTransaction) { - - super.init(swiftValue) + + fatalError() } } // MARK: - SynchronousDataTransaction -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension SynchronousDataTransaction: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSSynchronousDataTransaction { - - return CSSynchronousDataTransaction(self) + + fatalError() } } diff --git a/Sources/CSTweak.swift b/Sources/CSTweak.swift index a852780..4badf1d 100644 --- a/Sources/CSTweak.swift +++ b/Sources/CSTweak.swift @@ -29,42 +29,28 @@ import CoreData // MARK: - CSTweak -/** - The `CSTweak` serves as the Objective-C bridging type for `Tweak`. - - - SeeAlso: `Tweak` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSTweak: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType { - /** - The block to customize the `NSFetchRequest` - */ @objc public var block: (_ fetchRequest: NSFetchRequest) -> Void { - - return self.bridgeToSwift.closure + + fatalError() } - - /** - Initializes a `CSTweak` clause with a closure where the `NSFetchRequest` may be configured. - - - Important: `CSTweak`'s closure is executed only just before the fetch occurs, so make sure that any values captured by the closure is not prone to race conditions. Also, some utilities (such as `CSListMonitor`s) may keep `CSFetchClause`s in memory and may thus introduce retain cycles if reference captures are not handled properly. - - parameter block: the block to customize the `NSFetchRequest` - */ + @objc public convenience init(block: @escaping (_ fetchRequest: NSFetchRequest) -> Void) { - - self.init(Tweak(block)) + + fatalError() } // MARK: NSObject public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -72,8 +58,8 @@ public final class CSTweak: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau @objc public func applyToFetchRequest(_ fetchRequest: NSFetchRequest) { - - self.bridgeToSwift.applyToFetchRequest(fetchRequest) + + fatalError() } @@ -82,22 +68,21 @@ public final class CSTweak: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau public let bridgeToSwift: Tweak public init(_ swiftValue: Tweak) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - Tweak -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension Tweak: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSTweak { - - return CSTweak(self) + + fatalError() } } diff --git a/Sources/CSUnsafeDataModelSchema.swift b/Sources/CSUnsafeDataModelSchema.swift index f0a3a39..3be207a 100644 --- a/Sources/CSUnsafeDataModelSchema.swift +++ b/Sources/CSUnsafeDataModelSchema.swift @@ -29,50 +29,32 @@ import Foundation // MARK: - CSUnsafeDataModelSchema -/** - The `CSUnsafeDataModelSchema` serves as the Objective-C bridging type for `UnsafeDataModelSchema`. - - - SeeAlso: `UnsafeDataModelSchema` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSUnsafeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType { - /** - Initializes a `CSUnsafeDataModelSchema` from an `NSManagedObjectModel`. - - - parameter modelName: the model version, typically the file name of an *.xcdatamodeld file (without the file extension) - - parameter model: the `NSManagedObjectModel` - */ @objc public required init(modelName: ModelVersion, model: NSManagedObjectModel) { - - self.bridgeToSwift = UnsafeDataModelSchema( - modelName: modelName, - model: model - ) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return ObjectIdentifier(self.bridgeToSwift).hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSUnsafeDataModelSchema else { - - return false - } - return self.bridgeToSwift === object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -80,14 +62,14 @@ public final class CSUnsafeDataModelSchema: NSObject, CSDynamicSchema, CoreStore @objc public var modelVersion: ModelVersion { - - return self.bridgeToSwift.modelVersion + + fatalError() } @objc public func rawModel() -> NSManagedObjectModel { - - return self.bridgeToSwift.rawModel() + + fatalError() } @@ -96,22 +78,21 @@ public final class CSUnsafeDataModelSchema: NSObject, CSDynamicSchema, CoreStore public let bridgeToSwift: UnsafeDataModelSchema public required init(_ swiftValue: UnsafeDataModelSchema) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - UnsafeDataModelSchema -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension UnsafeDataModelSchema: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSUnsafeDataModelSchema { - - return CSUnsafeDataModelSchema(self) + + fatalError() } } diff --git a/Sources/CSUnsafeDataTransaction.swift b/Sources/CSUnsafeDataTransaction.swift index 455e5ae..524af7f 100644 --- a/Sources/CSUnsafeDataTransaction.swift +++ b/Sources/CSUnsafeDataTransaction.swift @@ -29,166 +29,76 @@ import CoreData // MARK: - CSUnsafeDataTransaction -/** - The `CSUnsafeDataTransaction` serves as the Objective-C bridging type for `UnsafeDataTransaction`. - - - SeeAlso: `UnsafeDataTransaction` - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSUnsafeDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType { - /** - Saves the transaction changes asynchronously. For a `CSUnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread. - - - parameter success: the block executed if the save succeeds. - - parameter failure: the block executed if the save fails. A `CSError` is reported as the argument of the block. - */ + @objc public func commitWithSuccess(_ success: (() -> Void)?, _ failure: ((CSError) -> Void)?) { - - self.bridgeToSwift.context.saveAsynchronously( - sourceIdentifier: nil, - completion: { (_, error) in - defer { - - withExtendedLifetime(self, {}) - } - if let error = error { - - failure?(error.bridgeToObjectiveC) - } - else { - - success?() - } - } - ) + fatalError() } - - /** - Saves the transaction changes and waits for completion synchronously. For a `CSUnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread. - - - parameter error: the `CSError` pointer that indicates the reason in case of an failure - - returns: `YES` if the commit succeeded, `NO` if the commit failed. If `NO`, the `error` argument will hold error information. - */ + @objc public func commitAndWait(error: NSErrorPointer) -> Bool { - return bridge(error) { - - if case (_, let error?) = self.bridgeToSwift.context.saveSynchronously( - waitForMerge: true, - sourceIdentifier: nil - ) { - - throw error - } - } + fatalError() } - - /** - Rolls back the transaction. - */ + @objc public func rollback() { - - self.bridgeToSwift.rollback() + + fatalError() } - - /** - Undo's the last change made to the transaction. - */ + @objc public func undo() { - - self.bridgeToSwift.undo() + + fatalError() } - - /** - Redo's the last undone change to the transaction. - */ + @objc public func redo() { - - self.bridgeToSwift.redo() + + fatalError() } - - /** - Immediately flushes all pending changes to the transaction's observers. This is useful in conjunction with `ListMonitor`s and `ObjectMonitor`s created from `UnsafeDataTransaction`s used to manage temporary "scratch" data. - - - Important: Note that unlike `commit()`, `flush()` does not propagate/save updates to the `DataStack` and the persistent store. However, the flushed changes will be seen by children transactions created further from the current transaction (i.e. through `transaction.beginUnsafe()`) - */ + @objc public func flush() { - - self.bridgeToSwift.flush() + + fatalError() } - - /** - Flushes all pending changes to the transaction's observers at the end of the `closure`'s execution. This is useful in conjunction with `ListMonitor`s and `ObjectMonitor`s created from `UnsafeDataTransaction`s used to manage temporary "scratch" data. - - - Important: Note that unlike `commit()`, `flush()` does not propagate/save updates to the `DataStack` and the persistent store. However, the flushed changes will be seen by children transactions created further from the current transaction (i.e. through `transaction.beginUnsafe()`) - - parameter block: the block where changes can be made prior to the flush - */ + @objc public func flush(_ block: () -> Void) { - - self.bridgeToSwift.flush { - - block() - } + + fatalError() } - - /** - Begins a child transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms. - - To support "undo" methods such as `-undo`, `-redo`, and `-rollback`, use the `-beginSafeWithSupportsUndo:` method passing `YES` to the argument. Without "undo" support, calling those methods will raise an exception. - - returns: a `CSUnsafeDataTransaction` instance where creates, updates, and deletes can be made. - */ + @objc public func beginUnsafe() -> CSUnsafeDataTransaction { - - return bridge { - - self.bridgeToSwift.beginUnsafe() - } + + fatalError() } - - /** - Begins a child transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms. - - - prameter supportsUndo: `-undo`, `-redo`, and `-rollback` methods are only available when this parameter is `YES`, otherwise those method will raise an exception. Note that turning on Undo support may heavily impact performance especially on iOS or watchOS where memory is limited. - - returns: a `CSUnsafeDataTransaction` instance where creates, updates, and deletes can be made. - */ + @objc public func beginUnsafeWithSupportsUndo(_ supportsUndo: Bool) -> CSUnsafeDataTransaction { - - return bridge { - - self.bridgeToSwift.beginUnsafe(supportsUndo: supportsUndo) - } + + fatalError() } - - /** - Returns the `NSManagedObjectContext` for this unsafe transaction. Use only for cases where external frameworks need an `NSManagedObjectContext` instance to work with. - - Note that it is the developer's responsibility to ensure the following: - - that the `CSUnsafeDataTransaction` that owns this context should be strongly referenced and prevented from being deallocated during the context's lifetime - - that all saves will be done either through the `CSUnsafeDataTransaction`'s `-commit:` or `-commitAndWait` method, or by calling `-save:` manually on the context, its parent, and all other ancestor contexts if there are any. - */ + @objc public func unsafeContext() -> NSManagedObjectContext { - - return self.bridgeToSwift.context + + fatalError() } // MARK: NSObject public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -197,31 +107,26 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction, CoreStoreObje public typealias SwiftType = UnsafeDataTransaction public var bridgeToSwift: UnsafeDataTransaction { - - return super.swiftTransaction as! UnsafeDataTransaction + + fatalError() } public required init(_ swiftValue: UnsafeDataTransaction) { - - super.init(swiftValue as BaseDataTransaction) - } - - public required override init(_ swiftValue: BaseDataTransaction) { - - super.init(swiftValue) + + fatalError() } } // MARK: - UnsafeDataTransaction -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension UnsafeDataTransaction: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSUnsafeDataTransaction { - - return CSUnsafeDataTransaction(self) + + fatalError() } } diff --git a/Sources/CSWhere.swift b/Sources/CSWhere.swift index b77aeeb..f916ab4 100644 --- a/Sources/CSWhere.swift +++ b/Sources/CSWhere.swift @@ -29,112 +29,62 @@ import CoreData // MARK: - CSWhere -/** - The `CSWhere` serves as the Objective-C bridging type for `Where`. - - - SeeAlso: `Where` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause { - /** - The internal `NSPredicate` instance for the `Where` clause - */ @objc public var predicate: NSPredicate { - - return self.bridgeToSwift.predicate + + fatalError() } - /** - Initializes a `CSWhere` clause with a predicate that always evaluates to the specified boolean value - ``` - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSWhereValue(YES)]]]; - ``` - - parameter value: the boolean value for the predicate - */ @objc public convenience init(value: Bool) { - - self.init(Where(value)) + + fatalError() } - - /** - Initializes a `CSWhere` clause with a predicate using the specified string format and arguments - ``` - NSPredicate *predicate = // ... - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSWherePredicate(predicate)]]; - ``` - - parameter format: the format string for the predicate - - parameter argumentArray: the arguments for `format` - */ + @objc public convenience init(format: String, argumentArray: [NSObject]?) { - - self.init(Where(format, argumentArray: argumentArray)) + + fatalError() } - - /** - Initializes a `CSWhere` clause that compares equality - - - parameter keyPath: the keyPath to compare with - - parameter value: the arguments for the `==` operator - */ + @objc public convenience init(keyPath: KeyPathString, isEqualTo value: CoreDataNativeType?) { - - self.init(value == nil || value is NSNull - ? Where("\(keyPath) == nil") - : Where("\(keyPath) == %@", value!)) + + fatalError() } - - /** - Initializes a `CSWhere` clause that compares membership - - - parameter keyPath: the keyPath to compare with - - parameter list: the array to check membership of - */ + @objc public convenience init(keyPath: KeyPathString, isMemberOf list: [CoreDataNativeType]) { - - self.init(Where("\(keyPath) IN %@", list as NSArray)) + + fatalError() } - - /** - Initializes a `CSWhere` clause with an `NSPredicate` - - - parameter predicate: the `NSPredicate` for the fetch or query - */ + @objc public convenience init(predicate: NSPredicate) { - - self.init(Where(predicate)) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return self.bridgeToSwift.hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSWhere else { - - return false - } - return self.bridgeToSwift == object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -142,8 +92,8 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau @objc public func applyToFetchRequest(_ fetchRequest: NSFetchRequest) { - - self.bridgeToSwift.applyToFetchRequest(fetchRequest) + + fatalError() } @@ -152,29 +102,21 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau public let bridgeToSwift: Where public init(_ swiftValue: Where) { - - self.bridgeToSwift = swiftValue.downcast() - super.init() + + fatalError() } } // MARK: - Where +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension Where where O: NSManagedObject { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSWhere { - - return CSWhere(self) - } - - - // MARK: FilePrivate - - fileprivate func downcast() -> Where { - - return Where(self.predicate) + + fatalError() } } diff --git a/Sources/CSXcodeDataModelSchema.swift b/Sources/CSXcodeDataModelSchema.swift index 8b4f428..a6318c7 100644 --- a/Sources/CSXcodeDataModelSchema.swift +++ b/Sources/CSXcodeDataModelSchema.swift @@ -29,50 +29,32 @@ import Foundation // MARK: - CSXcodeDataModelSchema -/** - The `CSXcodeDataModelSchema` serves as the Objective-C bridging type for `XcodeDataModelSchema`. - - - SeeAlso: `XcodeDataModelSchema` - */ +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") @objc -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") public final class CSXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType { - /** - Initializes an `CSXcodeDataModelSchema` from an *.xcdatamodeld file URL. - - - parameter modelName: the model version, typically the file name of an *.xcdatamodeld file (without the file extension) - - parameter modelVersionFileURL: the file URL that points to the .xcdatamodeld's "momd" file. - */ @objc public required init(modelName: ModelVersion, modelVersionFileURL: URL) { - - self.bridgeToSwift = XcodeDataModelSchema( - modelName: modelName, - modelVersionFileURL: modelVersionFileURL - ) + + fatalError() } // MARK: NSObject public override var hash: Int { - - return ObjectIdentifier(self.bridgeToSwift).hashValue + + fatalError() } public override func isEqual(_ object: Any?) -> Bool { - - guard let object = object as? CSXcodeDataModelSchema else { - - return false - } - return self.bridgeToSwift === object.bridgeToSwift + + fatalError() } public override var description: String { - - return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)" + + fatalError() } @@ -80,14 +62,14 @@ public final class CSXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreO @objc public var modelVersion: ModelVersion { - - return self.bridgeToSwift.modelVersion + + fatalError() } @objc public func rawModel() -> NSManagedObjectModel { - - return self.bridgeToSwift.rawModel() + + fatalError() } @@ -96,22 +78,21 @@ public final class CSXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreO public let bridgeToSwift: XcodeDataModelSchema public required init(_ swiftValue: XcodeDataModelSchema) { - - self.bridgeToSwift = swiftValue - super.init() + + fatalError() } } // MARK: - XcodeDataModelSchema -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension XcodeDataModelSchema: CoreStoreSwiftType { // MARK: CoreStoreSwiftType public var bridgeToObjectiveC: CSXcodeDataModelSchema { - - return CSXcodeDataModelSchema(self) + + fatalError() } } diff --git a/Sources/CoreStoreBridge.h b/Sources/CoreStoreBridge.h index e7a4715..c67d4e5 100644 --- a/Sources/CoreStoreBridge.h +++ b/Sources/CoreStoreBridge.h @@ -37,7 +37,7 @@ #error CoreStore Objective-C utilities can only be used on platforms that support C function overloading #endif -#define CORESTORE_EXTERN extern __deprecated_msg("CoreStore Objective-C API will be removed soon.") +#define CORESTORE_EXTERN extern __deprecated_msg("CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") #define CORESTORE_OVERLOADABLE __attribute__((__overloadable__)) #define CORESTORE_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0, 1))) #define CORESTORE_RETURNS_RETAINED __attribute__((ns_returns_retained)) @@ -46,12 +46,14 @@ #pragma mark - KeyPathString Utilities #define CSKeyPath(type, property) ({ \ + CORESTORE_OBJC_OBSOLETE; \ type *_je_keypath_dummy __attribute__((unused)); \ typeof(_je_keypath_dummy.property) _je_keypath_dummy_property __attribute__((unused)); \ @#property; \ }) #define CSKeyPathOperator(operator, type, property) ({ \ + CORESTORE_OBJC_OBSOLETE; \ type *_je_keypath_dummy __attribute__((unused)); \ typeof(_je_keypath_dummy.property) _je_keypath_dummy_property __attribute__((unused)); \ @"@" #operator "." #property; \ @@ -65,85 +67,19 @@ @class CSFrom; -/** - @abstract - Initializes a CSFrom clause with the specified entity class. - - @code - MyPersonEntity *people = [transaction fetchAllFrom: - CSFromClass([MyPersonEntity class])]; - @endcode - - @param entityClass - the NSManagedObject class type to be created - - @result - a CSFrom clause with the specified entity class - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSFrom clause with the specified configuration. - - @code - MyPersonEntity *people = [transaction fetchAllFrom: - CSFromClass([MyPersonEntity class], @"Configuration1")]; - @endcode - - @param entityClass - the NSManagedObject class type to be created - - @param configuration - an NSPersistentStore configuration name to associate objects from. This parameter is required if multiple configurations contain the created NSManagedObject's entity type. Set to [NSNull null] to use the default configuration. - - @result - a CSFrom clause with the specified configuration - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSFrom clause with the specified configuration. - - @code - MyPersonEntity *people = [transaction fetchAllFrom: - CSFromClass([MyPersonEntity class], @"Configuration1")]; - @endcode - - @param entityClass - the NSManagedObject class type to be created - - @param configuration - an NSPersistentStore configuration name to associate objects from. This parameter is required if multiple configurations contain the created NSManagedObject's entity type. Set to [NSNull null] to use the default configuration. - - @result - a CSFrom clause with the specified configuration - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSFrom clause with the specified configurations. - - @code - MyPersonEntity *people = [transaction fetchAllFrom: - CSFromClass([MyPersonEntity class], - @[[NSNull null], @"Configuration1"])]; - @endcode - - @param entityClass - the NSManagedObject class type to be created - - @param configurations - an array of the NSPersistentStore configuration names to associate objects from. This parameter is required if multiple configurations contain the created NSManagedObject's entity type. Set to [NSNull null] to use the default configuration. - - @result - a CSFrom clause with the specified configurations - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull configurations) CORESTORE_RETURNS_RETAINED; @@ -152,42 +88,15 @@ CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull c @class CSGroupBy; -/** - @abstract - Initializes a CSGroupBy clause with a key path string - - @param keyPath - a key path string to group results with - - @result - a CSGroupBy clause with a key path string - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSGroupBy clause with a list of key path strings - - @param keyPath - a nil-terminated list of key path strings to group results with - - @result - a CSGroupBy clause with a list of key path strings - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSGroupBy clause with a list of key path strings - - @param keyPaths - a list of key path strings to group results with - - @result - a CSGroupBy clause with a list of key path strings - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray *_Nonnull keyPaths) CORESTORE_RETURNS_RETAINED; @@ -196,63 +105,15 @@ CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray *_Nonnull keyPaths) CO @class CSInto; -/** - @abstract - Initializes a CSInto clause with the specified entity class. - - @code - MyPersonEntity *people = [transaction createInto: - CSIntoClass([MyPersonEntity class])]; - @endcode - - @param entityClass - the NSManagedObject class type to be created - - @result - a CSInto clause with the specified entity class - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSInto clause with the specified entity class. - - @code - MyPersonEntity *people = [transaction createInto: - CSIntoClass([MyPersonEntity class], [NSNull null])]; - @endcode - - @param entityClass - the NSManagedObject class type to be created - - @param configuration - an NSPersistentStore configuration name to associate objects from. This parameter is required if multiple configurations contain the created NSManagedObject's entity type. Set to [NSNull null] to use the default configuration. - - @result - a CSInto clause with the specified entity class - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSInto clause with the specified entity class. - - @code - MyPersonEntity *people = [transaction createInto: - CSIntoClass([MyPersonEntity class], @"Configuration1")]; - @endcode - - @param entityClass - the NSManagedObject class type to be created - - @param configuration - an NSPersistentStore configuration name to associate objects from. This parameter is required if multiple configurations contain the created NSManagedObject's entity type. Set to [NSNull null] to use the default configuration. - - @result - a CSInto clause with the specified entity class - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; @@ -261,98 +122,23 @@ CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSString *_Nonnull conf @class CSOrderBy; -/** - @abstract - Syntax sugar for initializing an ascending NSSortDescriptor for use with CSOrderBy - - @code - MyPersonEntity *people = [CSCoreStore - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderByKey(CSSortAscending(@"fullname"))]]]; - @endcode - - @param key - the attribute key to sort with - - @result - an NSSortDescriptor for use with CSOrderBy - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN NSSortDescriptor *_Nonnull CSSortAscending(NSString *_Nonnull key) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Syntax sugar for initializing a descending NSSortDescriptor for use with CSOrderBy - - @code - MyPersonEntity *people = [CSCoreStore - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderByKey(CSSortDescending(@"fullname"))]]]; - @endcode - - @param key - the attribute key to sort with - - @result - an NSSortDescriptor for use with CSOrderBy - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN NSSortDescriptor *_Nonnull CSSortDescending(NSString *_Nonnull key) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSOrderBy clause with a single sort descriptor - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderByKey(CSSortAscending(@"fullname"))]]]; - @endcode - - @param sortDescriptor - an NSSortDescriptor - - @result - a CSOrderBy clause with a single sort descriptor - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSOrderBy *_Nonnull CSOrderByKey(NSSortDescriptor *_Nonnull sortDescriptor) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSOrderBy clause with a list of sort descriptors - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderByKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]]; - @endcode - - @param sortDescriptor - a nil-terminated array of NSSortDescriptors - - @result - a CSOrderBy clause with a list of sort descriptors - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSOrderBy *_Nonnull CSOrderByKeys(NSSortDescriptor *_Nonnull sortDescriptor, ...) CORESTORE_RETURNS_RETAINED CORESTORE_REQUIRES_NIL_TERMINATION; -/** - @abstract - Initializes a CSOrderBy clause with a list of sort descriptors - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderByKeys(@[CSSortAscending(@"fullname"), CSSortDescending(@"age")]))]]]; - @endcode - - @param sortDescriptors - an array of NSSortDescriptors - - @result - a CSOrderBy clause with a list of sort descriptors - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSOrderBy *_Nonnull CSOrderByKeys(NSArray *_Nonnull sortDescriptors) CORESTORE_RETURNS_RETAINED; @@ -362,120 +148,27 @@ CSOrderBy *_Nonnull CSOrderByKeys(NSArray *_Nonnull sortDesc @class CSSelect; @class CSSelectTerm; -/** - @abstract - Creates a CSSelect clause for querying an NSNumber value - - @code - NSNumber *maxAge = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectNumber(CSAggregateMax(@"age")) - // ... - @endcode - - @param selectTerm - the CSSelectTerm specifying the attribute/aggregate value to query - - @result - a CSSelect clause for querying an NSNumber value - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Creates a CSSelect clause for querying an NSDecimalNumber value - - @code - NSDecimalNumber *averagePrice = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectDecimal(CSAggregateAverage(@"price")) - // ... - @endcode - - @param selectTerm - the CSSelectTerm specifying the attribute/aggregate value to query - - @result - a CSSelect clause for querying an NSDecimalNumber value - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Creates a CSSelect clause for querying an NSString value - - @code - NSString *fullname = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectString(CSAttribute(@"fullname")) - // ... - @endcode - - @param selectTerm - the CSSelectTerm specifying the attribute/aggregate value to query - - @result - a CSSelect clause for querying an NSString value - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Creates a CSSelect clause for querying an NSDate value - - @code - NSDate *lastUpdate = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectDate(CSAggregateMax(@"updatedDate")) - // ... - @endcode - - @param selectTerm - the CSSelectTerm specifying the attribute/aggregate value to query - - @result - a CSSelect clause for querying an NSDate value - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Creates a CSSelect clause for querying an NSData value - - @code - NSData *imageData = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectData(CSAttribute(@"imageData")) - // ... - @endcode - - @param selectTerm - the CSSelectTerm specifying the attribute/aggregate value to query - - @result - a CSSelect clause for querying an NSData value - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Creates a CSSelect clause for querying an NSManagedObjectID value - - @code - NSManagedObjectID *objectID = [CSCoreStore - queryValueFrom:CSFromClass([MyPersonEntity class]) - select:CSSelectObjectID() - // ... - @endcode - - @result - a CSSelect clause for querying an NSManagedObjectID value - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSSelect *_Nonnull CSSelectObjectID(void) CORESTORE_RETURNS_RETAINED; @@ -484,19 +177,7 @@ CSSelect *_Nonnull CSSelectObjectID(void) CORESTORE_RETURNS_RETAINED; @class CSTweak; -/** - @abstract - Initializes a CSTweak clause with a block where the NSFetchRequest may be configured. - - @important - CSTweak's closure is executed only just before the fetch occurs, so make sure that any values captured by the closure is not prone to race conditions. Also, some utilities (such as CSListMonitors) may keep CSFetchClauses in memory and may thus introduce retain cycles if reference captures are not handled properly. - - @param block - the block to customize the NSFetchRequest - - @result - a CSTweak clause with the NSFetchRequest configuration block - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CORESTORE_OVERLOADABLE CSTweak *_Nonnull CSTweakRequest(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CORESTORE_RETURNS_RETAINED; @@ -505,61 +186,15 @@ CSTweak *_Nonnull CSTweakRequest(void (^_Nonnull block)(NSFetchRequest *_Nonnull @class CSWhere; -/** - @abstract - Initializes a CSWhere clause with a predicate that always evaluates to the specified boolean value - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSWhereValue(YES)]]; - @endcode - - @param value - the boolean value for the predicate - - @result - a CSWhere clause with a predicate that always evaluates to the specified boolean value - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSWhere *_Nonnull CSWhereValue(BOOL value) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSWhere clause with a predicate using the specified string format and arguments - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSWhereFormat(@"%K == %@", @"key", @"value")]]; - @endcode - - @param format - the format string for the predicate, followed by an optional comma-separated argument list - - @result - a CSWhere clause with a predicate using the specified string format and arguments - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CORESTORE_RETURNS_RETAINED; -/** - @abstract - Initializes a CSWhere clause with an NSPredicate - - @code - NSPredicate *predicate = // ... - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSWherePredicate(predicate)]]; - @endcode - - @param predicate - the NSPredicate for the fetch or query - - @result - a CSWhere clause with an NSPredicate - */ +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_EXTERN CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RETURNS_RETAINED; diff --git a/Sources/CoreStoreBridge.m b/Sources/CoreStoreBridge.m index 3254b86..52ce1a2 100644 --- a/Sources/CoreStoreBridge.m +++ b/Sources/CoreStoreBridge.m @@ -33,81 +33,79 @@ #pragma mark CSFrom +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED { - - return [[CSFrom alloc] initWithEntityClass:entityClass]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { - - return [[CSFrom alloc] initWithEntityClass:entityClass configuration:configuration]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { - - return [[CSFrom alloc] initWithEntityClass:entityClass configuration:configuration]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull configurations) CORESTORE_RETURNS_RETAINED { - - return [[CSFrom alloc] initWithEntityClass:entityClass configurations:configurations]; + + abort(); } #pragma mark CSGroupBy +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CORESTORE_RETURNS_RETAINED { - - return [[CSGroupBy alloc] initWithKeyPath:keyPath]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CORESTORE_RETURNS_RETAINED { - - va_list args; - va_start(args, keyPath); - - NSMutableArray *keyPaths = [NSMutableArray new]; - [keyPaths addObject:keyPath]; - - NSString *next; - while ((next = va_arg(args, NSString *)) != nil) { - - [keyPaths addObject:next]; - } - va_end(args); - return [[CSGroupBy alloc] initWithKeyPaths:keyPaths]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray *_Nonnull keyPaths) CORESTORE_RETURNS_RETAINED { - - return [[CSGroupBy alloc] initWithKeyPaths:keyPaths]; + + abort(); } #pragma mark CSInto +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED { - - return [[CSInto alloc] initWithEntityClass:entityClass]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { - - return [[CSInto alloc] initWithEntityClass:entityClass configuration:nil]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { - - return [[CSInto alloc] initWithEntityClass:entityClass configuration:configuration]; + + abort(); } @@ -115,106 +113,104 @@ CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSString *_Nonnull conf @class CSOrderBy; +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. NSSortDescriptor *_Nonnull CSSortAscending(NSString *_Nonnull key) { - - return [[NSSortDescriptor alloc] initWithKey:key ascending:YES]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. NSSortDescriptor *_Nonnull CSSortDescending(NSString *_Nonnull key) { - - return [[NSSortDescriptor alloc] initWithKey:key ascending:NO]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSOrderBy *_Nonnull CSOrderByKey(NSSortDescriptor *_Nonnull sortDescriptor) CORESTORE_RETURNS_RETAINED { - - return [[CSOrderBy alloc] initWithSortDescriptor:sortDescriptor]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSOrderBy *_Nonnull CSOrderByKeys(NSSortDescriptor *_Nonnull sortDescriptor, ...) CORESTORE_RETURNS_RETAINED { - - va_list args; - va_start(args, sortDescriptor); - - NSMutableArray *sortDescriptors = [NSMutableArray new]; - [sortDescriptors addObject:sortDescriptor]; - - NSSortDescriptor *next; - while ((next = va_arg(args, NSSortDescriptor *)) != nil) { - - [sortDescriptors addObject:next]; - } - va_end(args); - return [[CSOrderBy alloc] initWithSortDescriptors:sortDescriptors]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSOrderBy *_Nonnull CSOrderByKeys(NSArray *_Nonnull sortDescriptors) CORESTORE_RETURNS_RETAINED { - - return [[CSOrderBy alloc] initWithSortDescriptors:sortDescriptors]; + + abort(); } #pragma mark CSSelect +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { - - return [[CSSelect alloc] initWithNumberTerm:selectTerm]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { - - return [[CSSelect alloc] initWithDecimalTerm:selectTerm]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { - - return [[CSSelect alloc] initWithStringTerm:selectTerm]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { - - return [[CSSelect alloc] initWithDateTerm:selectTerm]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { - - return [[CSSelect alloc] initWithDataTerm:selectTerm]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSSelect *_Nonnull CSSelectObjectID() CORESTORE_RETURNS_RETAINED { - - return [[CSSelect alloc] initWithObjectIDTerm]; + + abort(); } #pragma mark CSTweak +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CORESTORE_OVERLOADABLE CSTweak *_Nonnull CSTweakRequest(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CORESTORE_RETURNS_RETAINED { - - return [[CSTweak alloc] initWithBlock:block]; + + abort(); } #pragma mark CSWhere +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSWhere *_Nonnull CSWhereValue(BOOL value) CORESTORE_RETURNS_RETAINED { - - return [[CSWhere alloc] initWithValue:value]; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CORESTORE_RETURNS_RETAINED { - - CSWhere *where; - va_list args; - va_start(args, format); - where = [[CSWhere alloc] initWithPredicate:[NSPredicate predicateWithFormat:format arguments:args]]; - va_end(args); - return where; + + abort(); } +NS_UNAVAILABLE // CoreStore Objective-C is now obsoleted in preparation for Swift concurrency. CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RETURNS_RETAINED { - - return [[CSWhere alloc] initWithPredicate:predicate]; + + abort(); } diff --git a/Sources/CoreStoreBridge.swift b/Sources/CoreStoreBridge.swift index b2c1dfc..13ff99c 100644 --- a/Sources/CoreStoreBridge.swift +++ b/Sources/CoreStoreBridge.swift @@ -28,157 +28,23 @@ import Foundation // MARK: - CoreStoreObjectiveCType -/** - `CoreStoreObjectiveCType`s are Objective-C accessible classes that represent CoreStore's Swift types. - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") public protocol CoreStoreObjectiveCType: AnyObject { - - /** - The corresponding Swift type - */ + associatedtype SwiftType - - /** - The bridged Swift instance - */ + var bridgeToSwift: SwiftType { get } - - /** - Initializes this instance with the Swift instance to bridge from - */ + init(_ swiftValue: SwiftType) } // MARK: - CoreStoreSwiftType -/** - `CoreStoreSwiftType`s are CoreStore's Swift types that are bridgeable to Objective-C. - */ -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") public protocol CoreStoreSwiftType { - - /** - The corresponding Objective-C type - */ + associatedtype ObjectiveCType - /** - The bridged Objective-C instance - */ var bridgeToObjectiveC: ObjectiveCType { get } } - - -// MARK: - Internal - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ closure: () -> T) -> T.ObjectiveCType { - - return closure().bridgeToObjectiveC -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ closure: () -> [T]) -> [T.ObjectiveCType] { - - return closure().map { $0.bridgeToObjectiveC } -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ closure: () -> T?) -> T.ObjectiveCType? { - - return closure()?.bridgeToObjectiveC -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ closure: () throws -> T) throws -> T.ObjectiveCType { - - do { - - return try closure().bridgeToObjectiveC - } - catch { - - throw error.bridgeToObjectiveC - } -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ closure: () throws -> Void) throws { - - do { - - try closure() - } - catch { - - throw error.bridgeToObjectiveC - } -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ error: NSErrorPointer, _ closure: () throws -> T) -> T.ObjectiveCType? { - - do { - - let result = try closure() - error?.pointee = nil - return result.bridgeToObjectiveC - } - catch let swiftError { - - error?.pointee = swiftError.bridgeToObjectiveC - return nil - } -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ error: NSErrorPointer, _ closure: () throws -> Void) -> Bool { - - do { - - try closure() - error?.pointee = nil - return true - } - catch let swiftError { - - error?.pointee = swiftError.bridgeToObjectiveC - return false - } -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ error: NSErrorPointer, _ closure: () throws -> T?) -> T? { - - do { - - let result = try closure() - error?.pointee = nil - return result - } - catch let swiftError { - - error?.pointee = swiftError.bridgeToObjectiveC - return nil - } -} - -@available(*, deprecated, message: "CoreStore Objective-C API will be removed soon.") -internal func bridge(_ error: NSErrorPointer, _ closure: () throws -> [T]) -> [T.ObjectiveCType]? { - - do { - - let result = try closure() - error?.pointee = nil - return result.map { $0.bridgeToObjectiveC } - } - catch let swiftError { - - error?.pointee = swiftError.bridgeToObjectiveC - return nil - } -} - - diff --git a/Sources/CoreStoreError.swift b/Sources/CoreStoreError.swift index e2a5dd9..b0c155c 100644 --- a/Sources/CoreStoreError.swift +++ b/Sources/CoreStoreError.swift @@ -258,8 +258,23 @@ public enum CoreStoreError: Error, CustomNSError, Hashable { // MARK: Internal internal init(_ error: Error?) { - - self = error.flatMap({ $0.bridgeToSwift }) ?? .unknown + + guard let error = error else { + + self = .unknown + return + } + switch error { + + case let error as CoreStoreError: + self = error + + case let error as NSError: + self = .internalError(NSError: error) + + default: + self = .unknown + } } } diff --git a/Sources/CustomSchemaMappingProvider.swift b/Sources/CustomSchemaMappingProvider.swift index afcacfa..d8b4525 100644 --- a/Sources/CustomSchemaMappingProvider.swift +++ b/Sources/CustomSchemaMappingProvider.swift @@ -216,7 +216,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider { */ public subscript(attribute: KeyPathString) -> Any? { - return self.rawObject.cs_accessValueForKVCKey(attribute) + return self.rawObject.getValue(forKvcKey: attribute) } /** @@ -224,7 +224,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider { */ public subscript(attribute: NSAttributeDescription) -> Any? { - return self.rawObject.cs_accessValueForKVCKey(attribute.name) + return self.rawObject.getValue(forKvcKey: attribute.name) } /** @@ -273,8 +273,8 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider { */ public subscript(attribute: KeyPathString) -> Any? { - get { return self.rawObject.cs_accessValueForKVCKey(attribute) } - set { self.rawObject.cs_setValue(newValue, forKVCKey: attribute) } + get { return self.rawObject.getValue(forKvcKey: attribute) } + set { self.rawObject.setValue(newValue, forKvcKey: attribute) } } /** @@ -282,8 +282,8 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider { */ public subscript(attribute: NSAttributeDescription) -> Any? { - get { return self.rawObject.cs_accessValueForKVCKey(attribute.name) } - set { self.rawObject.cs_setValue(newValue, forKVCKey: attribute.name) } + get { return self.rawObject.getValue(forKvcKey: attribute.name) } + set { self.rawObject.setValue(newValue, forKvcKey: attribute.name) } } /** diff --git a/Sources/DataStack.AddStoragePublisher.swift b/Sources/DataStack.AddStoragePublisher.swift index ddc1763..85cf5d5 100644 --- a/Sources/DataStack.AddStoragePublisher.swift +++ b/Sources/DataStack.AddStoragePublisher.swift @@ -199,7 +199,7 @@ extension DataStack { ) if let progress = progress { - progress.cs_setProgressHandler { [weak self] progress in + progress.setProgressHandler { [weak self] progress in guard let self = self, diff --git a/Sources/NSManagedObject+ObjectiveC.swift b/Sources/NSManagedObject+ObjectiveC.swift index 9806c78..091070d 100644 --- a/Sources/NSManagedObject+ObjectiveC.swift +++ b/Sources/NSManagedObject+ObjectiveC.swift @@ -29,47 +29,30 @@ import CoreData // MARK: - NSManagedObject +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension NSManagedObject { - /** - Provides a convenience wrapper for accessing `-primitiveValueForKey:` with proper calls to `-willAccessValueForKey:` and `-didAccessValueForKey:`. This is useful when implementing accessor methods for transient attributes. - - - parameter KVCKey: the KVC key - - returns: the primitive value for the KVC key - */ @objc public func cs_accessValueForKVCKey(_ KVCKey: KeyPathString) -> Any? { - - return self.getValue(forKvcKey: KVCKey) + + fatalError() } - - /** - Provides a convenience wrapper for setting `-setPrimitiveValue:` with proper calls to `-willChangeValueForKey:` and `-didChangeValueForKey:`. This is useful when implementing mutator methods for transient attributes. - - - parameter value: the value to set the KVC key with - - parameter KVCKey: the KVC key - */ + @objc public func cs_setValue(_ value: Any?, forKVCKey KVCKey: KeyPathString) { - - self.setValue(value, forKvcKey: KVCKey) + + fatalError() } - - /** - Re-faults the object to use the latest values from the persistent store - */ + @objc public func cs_refreshAsFault() { - - self.refreshAsFault() + + fatalError() } - - /** - Re-faults the object to use the latest values from the persistent store and merges previously pending changes back - */ + @nonobjc public func cs_refreshAndMerge() { - - self.refreshAndMerge() + + fatalError() } } diff --git a/Sources/NSManagedObjectContext+ObjectiveC.swift b/Sources/NSManagedObjectContext+ObjectiveC.swift deleted file mode 100644 index 76c3e9d..0000000 --- a/Sources/NSManagedObjectContext+ObjectiveC.swift +++ /dev/null @@ -1,142 +0,0 @@ -// -// NSManagedObjectContext+ObjectiveC.swift -// CoreStore -// -// Copyright © 2018 John Rommel Estropia -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -import CoreData - - -// MARK: - NSManagedObjectContext - -extension NSManagedObjectContext { - - // MARK: Internal - - @nonobjc - internal func fetchOne(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> NSManagedObject? { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 1 - fetchRequest.resultType = .managedObjectResultType - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.fetchOne(fetchRequest) - } - - @nonobjc - internal func fetchAll(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> [T] { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 0 - fetchRequest.resultType = .managedObjectResultType - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.fetchAll(fetchRequest) - } - - @nonobjc - internal func fetchCount(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> Int { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.resultType = .countResultType - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.fetchCount(fetchRequest) - } - - @nonobjc - internal func fetchObjectID(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> NSManagedObjectID? { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 1 - fetchRequest.resultType = .managedObjectIDResultType - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.fetchObjectID(fetchRequest) - } - - @nonobjc - internal func fetchObjectIDs(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> [NSManagedObjectID] { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 0 - fetchRequest.resultType = .managedObjectIDResultType - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.fetchObjectIDs(fetchRequest) - } - - @nonobjc - internal func deleteAll(_ from: CSFrom, _ deleteClauses: [CSDeleteClause]) throws -> Int { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 0 - fetchRequest.resultType = .managedObjectResultType - fetchRequest.returnsObjectsAsFaults = true - fetchRequest.includesPropertyValues = false - deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.deleteAll(fetchRequest) - } - - @nonobjc - internal func queryValue(_ from: CSFrom, _ selectClause: CSSelect, _ queryClauses: [CSQueryClause]) throws -> Any? { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 0 - - selectClause.applyToFetchRequest(fetchRequest) - queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.queryValue(selectClause.selectTerms, fetchRequest: fetchRequest) - } - - @nonobjc - internal func queryAttributes(_ from: CSFrom, _ selectClause: CSSelect, _ queryClauses: [CSQueryClause]) throws -> [[String: Any]] { - - let fetchRequest = Internals.CoreStoreFetchRequest() - try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 0 - - selectClause.applyToFetchRequest(fetchRequest) - queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - return try self.queryAttributes(fetchRequest) - } -} diff --git a/Sources/Progress+ObjectiveC.swift b/Sources/Progress+ObjectiveC.swift index e913ff8..af0ff79 100644 --- a/Sources/Progress+ObjectiveC.swift +++ b/Sources/Progress+ObjectiveC.swift @@ -28,16 +28,12 @@ import Foundation // MARK: - Progress +@available(*, unavailable, message: "CoreStore Objective-C is now obsoleted in preparation for Swift concurrency.") extension Progress { - - /** - Sets a closure that the `NSProgress` calls whenever its `fractionCompleted` changes. You can use this instead of setting up KVO. - - - parameter closure: the closure to execute on progress change - */ + @objc dynamic public func cs_setProgressHandler(_ closure: ((_ progress: Progress) -> Void)?) { - - self.setProgressHandler(closure) + + fatalError() } }