From c0ae129b22baf0b71b76555f8377d2b3d4bc217f Mon Sep 17 00:00:00 2001 From: John Estropia Date: Fri, 7 Apr 2017 20:14:13 +0900 Subject: [PATCH] NSManagedObject features are now fully supported for CoreStoreObject types. MacOSX 10.12 onwards now support ListMonitors and ObjectMonitors --- CoreStore.xcodeproj/project.pbxproj | 92 +++--- .../Palette.swift | 4 +- .../MigrationsDemoViewController.swift | 2 +- CoreStoreTests/ConvenienceTests.swift | 5 +- CoreStoreTests/DynamicModelTests.swift | 76 +++-- CoreStoreTests/ListObserverTests.swift | 43 +-- CoreStoreTests/ObjectObserverTests.swift | 28 +- CoreStoreTests/SectionByTests.swift | 5 +- CoreStoreTests/TransactionTests.swift | 7 +- .../CoreStoreObject+Convenience.swift | 99 +++++++ ...FetchedResultsController+Convenience.swift | 6 +- .../NSManagedObject+Convenience.swift | 176 ++++++++---- .../Attribute+Querying.swift | 29 +- .../BaseDataTransaction+Querying.swift | 40 +-- .../Concrete Clauses/From.swift | 18 +- .../Concrete Clauses/Where.swift | 8 +- .../CoreStore+Querying.swift | 36 +-- .../DataStack+Querying.swift | 36 +-- .../FetchableSource.swift | 28 +- .../QueryableSource.swift | 8 +- .../BaseDataTransaction+Importing.swift | 10 +- Sources/Importing/ImportableObject.swift | 11 +- .../Importing/ImportableUniqueObject.swift | 37 +-- .../CoreStoreFetchedResultsController.swift | 9 +- .../FetchedResultsControllerDelegate.swift | 8 +- .../NSManagedObjectContext+Querying.swift | 115 ++++---- ...reStore+CustomDebugStringConvertible.swift | 14 +- .../CSBaseDataTransaction+Querying.swift | 8 +- .../ObjectiveC/CSCoreStore+Observing.swift | 5 +- .../ObjectiveC/CSDataStack+Observing.swift | 52 ++-- Sources/ObjectiveC/CSDataStack+Querying.swift | 8 +- Sources/ObjectiveC/CSListMonitor.swift | 23 +- Sources/ObjectiveC/CSListObserver.swift | 7 +- Sources/ObjectiveC/CSObjectMonitor.swift | 23 +- Sources/ObjectiveC/CSObjectObserver.swift | 5 +- Sources/ObjectiveC/CSSectionBy.swift | 6 +- ...SFetchedResultsController+ObjectiveC.swift | 7 +- .../NSManagedObject+ObjectiveC.swift | 6 +- Sources/Observing/CoreStore+Observing.swift | 5 +- Sources/Observing/DataStack+Observing.swift | 5 +- Sources/Observing/ListMonitor.swift | 204 +++++++++----- Sources/Observing/ListObserver.swift | 12 +- Sources/Observing/ObjectMonitor.swift | 56 ++-- Sources/Observing/ObjectObserver.swift | 8 +- Sources/Observing/SectionBy.swift | 5 +- .../UnsafeDataTransaction+Observing.swift | 5 +- Sources/Setup/CoreStore+Setup.swift | 6 +- Sources/Setup/DataStack.swift | 18 +- ...agedObject.swift => CoreStoreObject.swift} | 8 +- .../{ObjectModel.swift => DynamicModel.swift} | 36 ++- ...jectProtocol.swift => DynamicObject.swift} | 66 +++-- Sources/Setup/Dynamic Models/Entity.swift | 20 +- .../Setup/Dynamic Models/Relationship.swift | 261 ++++++++++++++---- .../{Attribute.swift => Value.swift} | 90 +++--- .../AsynchronousDataTransaction.swift | 12 +- .../Transactions/BaseDataTransaction.swift | 38 +-- Sources/Transactions/Into.swift | 6 +- .../SynchronousDataTransaction.swift | 14 +- 58 files changed, 1172 insertions(+), 803 deletions(-) create mode 100644 Sources/Convenience/CoreStoreObject+Convenience.swift rename Sources/Setup/Dynamic Models/{ManagedObject.swift => CoreStoreObject.swift} (93%) rename Sources/Setup/Dynamic Models/{ObjectModel.swift => DynamicModel.swift} (91%) rename Sources/Setup/Dynamic Models/{ManagedObjectProtocol.swift => DynamicObject.swift} (74%) rename Sources/Setup/Dynamic Models/{Attribute.swift => Value.swift} (54%) diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 2795cb4..fd28c3b 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -84,6 +84,10 @@ B509C7F51E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; }; B509C7F61E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; }; B509C7F71E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; }; + B512607F1E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; }; + B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; }; + B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; }; + B51260821E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; }; B51BE06A1B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; }; B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; }; B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; }; @@ -413,25 +417,25 @@ B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; }; B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; }; B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; }; - B5D339AF1E925BF200C880DE /* ObjectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* ObjectModel.swift */; }; - B5D339B01E925BF200C880DE /* ObjectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* ObjectModel.swift */; }; - B5D339B11E925BF200C880DE /* ObjectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* ObjectModel.swift */; }; - B5D339B21E925BF200C880DE /* ObjectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* ObjectModel.swift */; }; + B5D339AF1E925BF200C880DE /* DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* DynamicModel.swift */; }; + B5D339B01E925BF200C880DE /* DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* DynamicModel.swift */; }; + B5D339B11E925BF200C880DE /* DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* DynamicModel.swift */; }; + B5D339B21E925BF200C880DE /* DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339AE1E925BF200C880DE /* DynamicModel.swift */; }; B5D339B41E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; }; B5D339B51E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; }; B5D339B61E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; }; - B5D339D81E9489AB00C880DE /* ManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* ManagedObject.swift */; }; - B5D339D91E9489AB00C880DE /* ManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* ManagedObject.swift */; }; - B5D339DA1E9489AB00C880DE /* ManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* ManagedObject.swift */; }; - B5D339DB1E9489AB00C880DE /* ManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* ManagedObject.swift */; }; - B5D339DD1E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* ManagedObjectProtocol.swift */; }; - B5D339DE1E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* ManagedObjectProtocol.swift */; }; - B5D339DF1E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* ManagedObjectProtocol.swift */; }; - B5D339E01E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* ManagedObjectProtocol.swift */; }; - B5D339E21E948C3600C880DE /* Attribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Attribute.swift */; }; - B5D339E31E948C3600C880DE /* Attribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Attribute.swift */; }; - B5D339E41E948C3600C880DE /* Attribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Attribute.swift */; }; - B5D339E51E948C3600C880DE /* Attribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Attribute.swift */; }; + B5D339D81E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; }; + B5D339D91E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; }; + B5D339DA1E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; }; + B5D339DB1E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; }; + B5D339DD1E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; }; + B5D339DE1E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; }; + B5D339DF1E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; }; + B5D339E01E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; }; + B5D339E21E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; }; + B5D339E31E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; }; + B5D339E41E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; }; + B5D339E51E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; }; B5D339E71E9493A500C880DE /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E61E9493A500C880DE /* Entity.swift */; }; B5D339E81E9493A500C880DE /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E61E9493A500C880DE /* Entity.swift */; }; B5D339E91E9493A500C880DE /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E61E9493A500C880DE /* Entity.swift */; }; @@ -648,6 +652,7 @@ B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Transaction.swift"; sourceTree = ""; }; B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Setup.swift"; sourceTree = ""; }; B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportableAttributeType.swift; sourceTree = ""; }; + B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Convenience.swift"; sourceTree = ""; }; B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectModel+Setup.swift"; sourceTree = ""; }; B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+CustomDebugStringConvertible.swift"; sourceTree = ""; }; B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFetchedResultsController+Convenience.swift"; sourceTree = ""; }; @@ -728,11 +733,11 @@ B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = ""; }; B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = ""; }; B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = ""; }; - B5D339AE1E925BF200C880DE /* ObjectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectModel.swift; sourceTree = ""; }; + B5D339AE1E925BF200C880DE /* DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicModel.swift; sourceTree = ""; }; B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicModelTests.swift; sourceTree = ""; }; - B5D339D71E9489AB00C880DE /* ManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedObject.swift; sourceTree = ""; }; - B5D339DC1E9489C700C880DE /* ManagedObjectProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagedObjectProtocol.swift; sourceTree = ""; }; - B5D339E11E948C3600C880DE /* Attribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Attribute.swift; sourceTree = ""; }; + B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreObject.swift; sourceTree = ""; }; + B5D339DC1E9489C700C880DE /* DynamicObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicObject.swift; sourceTree = ""; }; + B5D339E11E948C3600C880DE /* Value.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Value.swift; sourceTree = ""; }; B5D339E61E9493A500C880DE /* Entity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Entity.swift; sourceTree = ""; }; B5D339EB1E9495E500C880DE /* Attribute+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Attribute+Querying.swift"; sourceTree = ""; }; B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreStrings.swift; sourceTree = ""; }; @@ -1086,12 +1091,12 @@ B57358D71E5A7F9B0094B50A /* Dynamic Models */ = { isa = PBXGroup; children = ( - B5D339E11E948C3600C880DE /* Attribute.swift */, - B5D33A001E96012400C880DE /* Relationship.swift */, - B5D339D71E9489AB00C880DE /* ManagedObject.swift */, + B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */, + B5D339AE1E925BF200C880DE /* DynamicModel.swift */, + B5D339DC1E9489C700C880DE /* DynamicObject.swift */, B5D339E61E9493A500C880DE /* Entity.swift */, - B5D339DC1E9489C700C880DE /* ManagedObjectProtocol.swift */, - B5D339AE1E925BF200C880DE /* ObjectModel.swift */, + B5D33A001E96012400C880DE /* Relationship.swift */, + B5D339E11E948C3600C880DE /* Value.swift */, ); path = "Dynamic Models"; sourceTree = ""; @@ -1272,6 +1277,7 @@ isa = PBXGroup; children = ( B5E84F271AFF84920064E85B /* NSManagedObject+Convenience.swift */, + B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */, B5FAD6A81B50A4B300714891 /* Progress+Convenience.swift */, B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */, ); @@ -1631,7 +1637,7 @@ B529C2041CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */, B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */, B5E84F131AFF847B0064E85B /* Where.swift in Sources */, - B5D339D81E9489AB00C880DE /* ManagedObject.swift in Sources */, + B5D339D81E9489AB00C880DE /* CoreStoreObject.swift in Sources */, B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */, B596BBBB1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */, @@ -1641,7 +1647,7 @@ B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */, B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */, - B5D339E21E948C3600C880DE /* Attribute.swift in Sources */, + B5D339E21E948C3600C880DE /* Value.swift in Sources */, B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */, B53FBA0B1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */, B5E84F141AFF847B0064E85B /* DataStack+Querying.swift in Sources */, @@ -1701,7 +1707,7 @@ B5E84F231AFF84860064E85B /* ListMonitor.swift in Sources */, B5E84EF71AFF846E0064E85B /* UnsafeDataTransaction.swift in Sources */, B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */, - B5D339DD1E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */, + B5D339DD1E9489C700C880DE /* DynamicObject.swift in Sources */, B5A5F2661CAEC50F004AB9AF /* CSSelect.swift in Sources */, B5ECDBE51CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */, B5519A4A1CA1F4FB002BEF78 /* CSError.swift in Sources */, @@ -1714,7 +1720,7 @@ B5E222231CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */, B5E84F281AFF84920064E85B /* NSManagedObject+Convenience.swift in Sources */, B51BE06A1B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift in Sources */, - B5D339AF1E925BF200C880DE /* ObjectModel.swift in Sources */, + B5D339AF1E925BF200C880DE /* DynamicModel.swift in Sources */, B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, B5E2222A1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */, B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */, @@ -1728,6 +1734,7 @@ B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */, B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */, B538BA771D15B3E30003A766 /* CoreStoreBridge.m in Sources */, + B512607F1E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */, B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */, B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */, B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */, @@ -1796,7 +1803,7 @@ B529C2061CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */, 82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */, 82BA18AB1C4BBD3100A0916E /* AsynchronousDataTransaction.swift in Sources */, - B5D339D91E9489AB00C880DE /* ManagedObject.swift in Sources */, + B5D339D91E9489AB00C880DE /* CoreStoreObject.swift in Sources */, 82BA18CE1C4BBD7100A0916E /* FetchedResultsControllerDelegate.swift in Sources */, B596BBBC1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */, @@ -1806,7 +1813,7 @@ B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */, B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */, - B5D339E31E948C3600C880DE /* Attribute.swift in Sources */, + B5D339E31E948C3600C880DE /* Value.swift in Sources */, 82BA18C51C4BBD5300A0916E /* ListObserver.swift in Sources */, B53FBA0D1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */, 82BA18C21C4BBD5300A0916E /* ObjectMonitor.swift in Sources */, @@ -1866,7 +1873,7 @@ 82BA18D11C4BBD7100A0916E /* NotificationObserver.swift in Sources */, 82BA18BB1C4BBD4A00A0916E /* Where.swift in Sources */, B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */, - B5D339DE1E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */, + B5D339DE1E9489C700C880DE /* DynamicObject.swift in Sources */, B5ECDBE71CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */, B5519A4B1CA1F4FB002BEF78 /* CSError.swift in Sources */, 82BA18D71C4BBD7100A0916E /* NSManagedObjectModel+Setup.swift in Sources */, @@ -1879,7 +1886,7 @@ 82BA18C41C4BBD5300A0916E /* ListMonitor.swift in Sources */, 82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */, B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, - B5D339B01E925BF200C880DE /* ObjectModel.swift in Sources */, + B5D339B01E925BF200C880DE /* DynamicModel.swift in Sources */, B5E2222C1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */, 82BA18A71C4BBD2900A0916E /* CoreStore+Logging.swift in Sources */, 82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */, @@ -1893,6 +1900,7 @@ B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */, B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */, B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */, + B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */, 82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */, 82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */, B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, @@ -1961,7 +1969,7 @@ B546F9761C9C553300D5AC55 /* SetupResult.swift in Sources */, B53FBA161CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */, B5ECDC271CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */, - B5D339DB1E9489AB00C880DE /* ManagedObject.swift in Sources */, + B5D339DB1E9489AB00C880DE /* CoreStoreObject.swift in Sources */, B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */, B596BBBE1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, B546F9601C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */, @@ -1971,7 +1979,7 @@ B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, B5ECDC2D1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */, - B5D339E51E948C3600C880DE /* Attribute.swift in Sources */, + B5D339E51E948C3600C880DE /* Value.swift in Sources */, B5A5F26A1CAEC50F004AB9AF /* CSSelect.swift in Sources */, B5220E1B1D13079B009BC71E /* CSCoreStore+Observing.swift in Sources */, B5FEC1911C9166E700532541 /* NSPersistentStore+Setup.swift in Sources */, @@ -2031,7 +2039,7 @@ B52DD1CA1BE1F94600949AFE /* NSManagedObjectModel+Setup.swift in Sources */, B52DD1A41BE1F92F00949AFE /* ImportableObject.swift in Sources */, B5220E161D13067C009BC71E /* ObjectMonitor.swift in Sources */, - B5D339E01E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */, + B5D339E01E9489C700C880DE /* DynamicObject.swift in Sources */, B52DD1AE1BE1F93900949AFE /* OrderBy.swift in Sources */, B52DD1BA1BE1F94000949AFE /* MigrationChain.swift in Sources */, B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */, @@ -2044,7 +2052,7 @@ B5220E1A1D130791009BC71E /* CoreStoreFetchedResultsController.swift in Sources */, B53FBA0F1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */, B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */, - B5D339B21E925BF200C880DE /* ObjectModel.swift in Sources */, + B5D339B21E925BF200C880DE /* DynamicModel.swift in Sources */, B52DD19A1BE1F92800949AFE /* CoreStore+Logging.swift in Sources */, B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */, B546F96C1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, @@ -2058,6 +2066,7 @@ B5220E181D130711009BC71E /* ObjectObserver.swift in Sources */, B5220E251D13088E009BC71E /* ListObserver.swift in Sources */, B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */, + B51260821E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */, B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */, B5ECDC331CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */, B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */, @@ -2126,7 +2135,7 @@ B529C2071CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */, B563219D1BD65216006C9394 /* DataStack+Observing.swift in Sources */, B56321961BD65216006C9394 /* From.swift in Sources */, - B5D339DA1E9489AB00C880DE /* ManagedObject.swift in Sources */, + B5D339DA1E9489AB00C880DE /* CoreStoreObject.swift in Sources */, B5ECDC021CA80CBA00C7F112 /* CSWhere.swift in Sources */, B596BBBD1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, B5ECDC081CA8138100C7F112 /* CSOrderBy.swift in Sources */, @@ -2136,7 +2145,7 @@ B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */, B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */, - B5D339E41E948C3600C880DE /* Attribute.swift in Sources */, + B5D339E41E948C3600C880DE /* Value.swift in Sources */, B53FBA0E1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */, B563219E1BD65216006C9394 /* CoreStore+Observing.swift in Sources */, B5D7A5B91CA3BF8F005C752B /* CSInto.swift in Sources */, @@ -2196,7 +2205,7 @@ B563219A1BD65216006C9394 /* GroupBy.swift in Sources */, B5ECDBE81CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */, B5A5F2691CAEC50F004AB9AF /* CSSelect.swift in Sources */, - B5D339DF1E9489C700C880DE /* ManagedObjectProtocol.swift in Sources */, + B5D339DF1E9489C700C880DE /* DynamicObject.swift in Sources */, B5519A4C1CA1F4FB002BEF78 /* CSError.swift in Sources */, B563219B1BD65216006C9394 /* Tweak.swift in Sources */, B56321B51BD6521C006C9394 /* NSManagedObjectModel+Setup.swift in Sources */, @@ -2209,7 +2218,7 @@ B56321A21BD65216006C9394 /* ListObserver.swift in Sources */, B563218A1BD65216006C9394 /* SynchronousDataTransaction.swift in Sources */, B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, - B5D339B11E925BF200C880DE /* ObjectModel.swift in Sources */, + B5D339B11E925BF200C880DE /* DynamicModel.swift in Sources */, B5E2222D1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */, B563219F1BD65216006C9394 /* ObjectMonitor.swift in Sources */, B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */, @@ -2223,6 +2232,7 @@ B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */, B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */, B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */, + B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */, B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */, B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */, B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, diff --git a/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/Palette.swift b/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/Palette.swift index 5dfb3ef..74e4888 100644 --- a/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/Palette.swift +++ b/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/Palette.swift @@ -25,7 +25,7 @@ class Palette: NSManagedObject { get { let KVCKey = #keyPath(Palette.colorName) - if let colorName = self.accessValueForKVCKey(KVCKey) as? String { + if let colorName = self.getValue(forKvcKey: KVCKey) as? String { return colorName } @@ -49,7 +49,7 @@ class Palette: NSManagedObject { } set { - self.setValue(newValue, forKVCKey: #keyPath(Palette.colorName)) + self.setValue(newValue, forKvcKey: #keyPath(Palette.colorName)) } } diff --git a/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift b/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift index 34e149d..8c952ad 100644 --- a/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift +++ b/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift @@ -141,7 +141,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD // MARK: Private - private typealias ModelMetadata = (label: String, version: String, entityType: AnyClass, migrationChain: MigrationChain) + private typealias ModelMetadata = (label: String, version: String, entityType: NSManagedObject.Type, migrationChain: MigrationChain) private let models: [ModelMetadata] = [ ( diff --git a/CoreStoreTests/ConvenienceTests.swift b/CoreStoreTests/ConvenienceTests.swift index 6fea9ba..807d943 100644 --- a/CoreStoreTests/ConvenienceTests.swift +++ b/CoreStoreTests/ConvenienceTests.swift @@ -27,10 +27,9 @@ import CoreStore -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ConvenienceTests +@available(OSX 10.12, *) class ConvenienceTests: BaseTestCase { @objc @@ -90,5 +89,3 @@ class ConvenienceTests: BaseTestCase { } } } - -#endif diff --git a/CoreStoreTests/DynamicModelTests.swift b/CoreStoreTests/DynamicModelTests.swift index e431242..f2369ef 100644 --- a/CoreStoreTests/DynamicModelTests.swift +++ b/CoreStoreTests/DynamicModelTests.swift @@ -2,42 +2,62 @@ // DynamicModelTests.swift // CoreStore // -// Created by John Estropia on 2017/04/03. -// Copyright © 2017 John Rommel Estropia. All rights reserved. +// Copyright © 2017 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 XCTest -import CoreData - -@testable import CoreStore +@testable +import CoreStore -class Animal: ManagedObject { +class Animal: CoreStoreObject { - let species = Attribute.Required("species", default: "Swift") - let master = Relationship.ToOne("master", inverse: { $0.pet }) + let species = Value.Required("species", default: "Swift") + let master = Relationship.ToOne("master") } class Dog: Animal { - let nickname = Attribute.Optional("nickname") - let age = Attribute.Required("age", default: 1) + let nickname = Value.Optional("nickname") + let age = Value.Required("age", default: 1) + let friends = Relationship.ToManyUnordered("friends") + let friends2 = Relationship.ToManyUnordered("friends2", inverse: { $0.friends }) } -class Person: ManagedObject { +class Person: CoreStoreObject { - let name = Attribute.Required("name") - let pet = Relationship.ToOne("pet") + let name = Value.Required("name") + let pet = Relationship.ToOne("pet", inverse: { $0.master }) } +// MARK: - DynamicModelTests + class DynamicModelTests: BaseTestDataTestCase { func testDynamicModels_CanBeDeclaredCorrectly() { let dataStack = DataStack( - dynamicModel: ObjectModel( + dynamicModel: DynamicModel( version: "V1", entities: [ Entity("Animal"), @@ -57,26 +77,28 @@ class DynamicModelTests: BaseTestDataTestCase { let k3 = Dog.keyPath({ $0.nickname }) XCTAssertEqual(k3, "nickname") - let expectation = self.expectation(description: "done") + let updateDone = self.expectation(description: "update-done") + let fetchDone = self.expectation(description: "fetch-done") stack.perform( asynchronous: { (transaction) in let animal = transaction.create(Into()) - XCTAssertEqual(animal.species*, "Swift") - XCTAssertTrue(type(of: animal.species*) == String.self) + XCTAssertEqual(animal.species.value, "Swift") + XCTAssertTrue(type(of: animal.species.value) == String.self) animal.species .= "Sparrow" - XCTAssertEqual(animal.species*, "Sparrow") + XCTAssertEqual(animal.species.value, "Sparrow") let dog = transaction.create(Into()) - XCTAssertEqual(dog.species*, "Swift") - XCTAssertEqual(dog.nickname*, nil) + XCTAssertEqual(dog.species.value, "Swift") + XCTAssertEqual(dog.nickname.value, nil) + XCTAssertEqual(dog.age.value, 1) dog.species .= "Dog" - XCTAssertEqual(dog.species*, "Dog") + XCTAssertEqual(dog.species.value, "Dog") dog.nickname .= "Spot" - XCTAssertEqual(dog.nickname*, "Spot") + XCTAssertEqual(dog.nickname.value, "Spot") let person = transaction.create(Into()) XCTAssertNil(person.pet.value) @@ -89,7 +111,7 @@ class DynamicModelTests: BaseTestDataTestCase { }, success: { - print("done") + updateDone.fulfill() }, failure: { _ in @@ -104,15 +126,15 @@ class DynamicModelTests: BaseTestDataTestCase { let bird = transaction.fetchOne(From(), p1) XCTAssertNotNil(bird) - XCTAssertEqual(bird!.species*, "Sparrow") + XCTAssertEqual(bird!.species.value, "Sparrow") let p2 = Dog.where({ $0.nickname == "Spot" }) XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot")) let dog = transaction.fetchOne(From(), p2) XCTAssertNotNil(dog) - XCTAssertEqual(dog!.nickname*, "Spot") - XCTAssertEqual(dog!.species*, "Dog") + XCTAssertEqual(dog!.nickname.value, "Spot") + XCTAssertEqual(dog!.species.value, "Dog") let person = transaction.fetchOne(From()) XCTAssertNotNil(person) @@ -123,7 +145,7 @@ class DynamicModelTests: BaseTestDataTestCase { }, success: { - expectation.fulfill() + fetchDone.fulfill() withExtendedLifetime(stack, {}) }, failure: { _ in diff --git a/CoreStoreTests/ListObserverTests.swift b/CoreStoreTests/ListObserverTests.swift index b9ff213..5b1d68f 100644 --- a/CoreStoreTests/ListObserverTests.swift +++ b/CoreStoreTests/ListObserverTests.swift @@ -29,27 +29,11 @@ import XCTest import CoreStore -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ListObserverTests +@available(OSX 10.12, *) class ListObserverTests: BaseTestDataTestCase { - @objc - dynamic func test_ThatListObservers_CanDowncast() { - - self.prepareStack { (stack) in - - let monitor = stack.monitorSectionedList( - From(), - SectionBy(#keyPath(TestEntity1.testBoolean)), - OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID))) - ) - let downcast = monitor.downcast() - XCTAssertTrue(monitor == downcast) - } - } - @objc dynamic func test_ThatListObservers_CanReceiveInsertNotifications() { @@ -118,8 +102,8 @@ class ListObserverTests: BaseTestDataTestCase { ) let indexPath = userInfo?["indexPath"] as? NSIndexPath - XCTAssertEqual(indexPath?.section, 0) - XCTAssertEqual(indexPath?.row, 0) + XCTAssertEqual(indexPath?.index(atPosition: 0), 0) + XCTAssertEqual(indexPath?.index(atPosition: 1), 0) let object = userInfo?["object"] as? TestEntity1 XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) @@ -236,8 +220,8 @@ class ListObserverTests: BaseTestDataTestCase { switch object?.testEntityID { case NSNumber(value: 101)?: - XCTAssertEqual(indexPath?.section, 1) - XCTAssertEqual(indexPath?.row, 0) + XCTAssertEqual(indexPath?.index(atPosition: 0), 1) + XCTAssertEqual(indexPath?.index(atPosition: 1), 0) XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) XCTAssertEqual(object?.testNumber, NSNumber(value: 11)) @@ -247,8 +231,8 @@ class ListObserverTests: BaseTestDataTestCase { XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!) case NSNumber(value: 102)?: - XCTAssertEqual(indexPath?.section, 0) - XCTAssertEqual(indexPath?.row, 0) + XCTAssertEqual(indexPath?.index(atPosition: 0), 0) + XCTAssertEqual(indexPath?.index(atPosition: 1), 0) XCTAssertEqual(object?.testBoolean, NSNumber(value: false)) XCTAssertEqual(object?.testNumber, NSNumber(value: 22)) @@ -376,12 +360,12 @@ class ListObserverTests: BaseTestDataTestCase { ) let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath - XCTAssertEqual(fromIndexPath?.section, 0) - XCTAssertEqual(fromIndexPath?.row, 0) + XCTAssertEqual(fromIndexPath?.index(atPosition: 0), 0) + XCTAssertEqual(fromIndexPath?.index(atPosition: 1), 0) let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath - XCTAssertEqual(toIndexPath?.section, 1) - XCTAssertEqual(toIndexPath?.row, 1) + XCTAssertEqual(toIndexPath?.index(atPosition: 0), 1) + XCTAssertEqual(toIndexPath?.index(atPosition: 1), 1) let object = userInfo?["object"] as? TestEntity1 XCTAssertEqual(object?.testEntityID, NSNumber(value: 102)) @@ -488,7 +472,7 @@ class ListObserverTests: BaseTestDataTestCase { let indexPath = userInfo?["indexPath"] as? NSIndexPath XCTAssertEqual(indexPath?.section, 0) - XCTAssert(indexPath?.row == 0 || indexPath?.row == 1) + XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1) let object = userInfo?["object"] as? TestEntity1 XCTAssertEqual(object?.isDeleted, true) @@ -571,6 +555,7 @@ class ListObserverTests: BaseTestDataTestCase { // MARK: TestListObserver +@available(OSX 10.12, *) class TestListObserver: ListSectionObserver { // MARK: ListObserver @@ -693,5 +678,3 @@ class TestListObserver: ListSectionObserver { ) } } - -#endif diff --git a/CoreStoreTests/ObjectObserverTests.swift b/CoreStoreTests/ObjectObserverTests.swift index df3f91e..0b6c3d0 100644 --- a/CoreStoreTests/ObjectObserverTests.swift +++ b/CoreStoreTests/ObjectObserverTests.swift @@ -29,31 +29,10 @@ import XCTest import CoreStore -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ObjectObserverTests - class ObjectObserverTests: BaseTestDataTestCase { - - @objc - dynamic func test_ThatObjectObservers_CanDowncast() { - - self.prepareStack { (stack) in - - self.prepareTestDataForStack(stack) - - guard let object = stack.fetchOne( - From(), - Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else { - - XCTFail() - return - } - let monitor = stack.monitorObject(object) - let downcast = monitor.downcast() - XCTAssertTrue(monitor == downcast) - } - } +@available(OSX 10.12, *) +class ObjectObserverTests: BaseTestDataTestCase { @objc dynamic func test_ThatObjectObservers_CanReceiveUpdateNotifications() { @@ -224,6 +203,7 @@ import CoreStore // MARK: TestObjectObserver +@available(OSX 10.12, *) class TestObjectObserver: ObjectObserver { typealias ObjectEntityType = TestEntity1 @@ -262,5 +242,3 @@ class TestObjectObserver: ObjectObserver { ) } } - -#endif diff --git a/CoreStoreTests/SectionByTests.swift b/CoreStoreTests/SectionByTests.swift index 9a3d6b0..29132e6 100644 --- a/CoreStoreTests/SectionByTests.swift +++ b/CoreStoreTests/SectionByTests.swift @@ -29,10 +29,9 @@ import XCTest import CoreStore -#if os(iOS) || os(watchOS) || os(tvOS) - //MARK: - SectionByTests +@available(OSX 10.12, *) final class SectionByTests: XCTestCase { @objc @@ -53,5 +52,3 @@ final class SectionByTests: XCTestCase { } } } - -#endif diff --git a/CoreStoreTests/TransactionTests.swift b/CoreStoreTests/TransactionTests.swift index f88f5a9..06252cc 100644 --- a/CoreStoreTests/TransactionTests.swift +++ b/CoreStoreTests/TransactionTests.swift @@ -386,8 +386,8 @@ final class TransactionTests: BaseTestCase { } } - #if os(iOS) || os(watchOS) || os(tvOS) + @available(OSX 10.12, *) @objc dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() { @@ -432,8 +432,8 @@ final class TransactionTests: BaseTestCase { ) let indexPath = userInfo?["indexPath"] as? NSIndexPath - XCTAssertEqual(indexPath?.section, 0) - XCTAssertEqual(indexPath?.row, 0) + XCTAssertEqual(indexPath?.index(atPosition: 0), 0) + XCTAssertEqual(indexPath?.index(atPosition: 1), 0) let object = userInfo?["object"] as? TestEntity1 XCTAssertEqual(object?.testBoolean, NSNumber(value: true)) @@ -489,7 +489,6 @@ final class TransactionTests: BaseTestCase { } } - #endif @objc dynamic func test_ThatAsynchronousTransactions_CanPerformCRUDs() { diff --git a/Sources/Convenience/CoreStoreObject+Convenience.swift b/Sources/Convenience/CoreStoreObject+Convenience.swift new file mode 100644 index 0000000..2457c89 --- /dev/null +++ b/Sources/Convenience/CoreStoreObject+Convenience.swift @@ -0,0 +1,99 @@ +// +// CoreStoreObject+Convenience.swift +// CoreStore +// +// Copyright © 2017 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: - CoreStoreObject + +public extension CoreStoreObject { + + /** + Exposes a `FetchableSource` that can fetch sibling objects of this `CoreStoreObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated. + - Warning: Future implementations may change the instance returned by this method depending on the timing or condition that `fetchSource()` was called. Do not make assumptions that the instance will be a specific instance. If the `NSManagedObjectContext` instance is desired, use the `FetchableSource.unsafeContext()` method to get the correct instance. Also, do not assume that the `fetchSource()` and `querySource()` return the same instance all the time. + - returns: a `FetchableSource` that can fetch sibling objects of this `CoreStoreObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the object's parent is already deallocated. + */ + @nonobjc + public func fetchSource() -> FetchableSource? { + + guard let context = self.rawObject!.managedObjectContext else { + + return nil + } + if context.isTransactionContext { + + return context.parentTransaction + } + if context.isDataStackContext { + + return context.parentStack + } + return context + } + + /** + Exposes a `QueryableSource` that can query attributes and aggregate values. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated. + - Warning: Future implementations may change the instance returned by this method depending on the timing or condition that `querySource()` was called. Do not make assumptions that the instance will be a specific instance. If the `NSManagedObjectContext` instance is desired, use the `QueryableSource.unsafeContext()` method to get the correct instance. Also, do not assume that the `fetchSource()` and `querySource()` return the same instance all the time. + - returns: a `QueryableSource` that can query attributes and aggregate values. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the object's parent is already deallocated. + */ + @nonobjc + public func querySource() -> QueryableSource? { + + guard let context = self.rawObject!.managedObjectContext else { + + return nil + } + if context.isTransactionContext { + + return context.parentTransaction + } + if context.isDataStackContext { + + return context.parentStack + } + return context + } + + /** + Re-faults the object to use the latest values from the persistent store + */ + @nonobjc + public func refreshAsFault() { + + let rawObject = self.rawObject! + rawObject.managedObjectContext?.refresh(rawObject, mergeChanges: false) + } + + /** + Re-faults the object to use the latest values from the persistent store and merges previously pending changes back + */ + @nonobjc + public func refreshAndMerge() { + + let rawObject = self.rawObject! + rawObject.managedObjectContext?.refresh(rawObject, mergeChanges: true) + } +} diff --git a/Sources/Convenience/NSFetchedResultsController+Convenience.swift b/Sources/Convenience/NSFetchedResultsController+Convenience.swift index 56d0e37..b57a961 100644 --- a/Sources/Convenience/NSFetchedResultsController+Convenience.swift +++ b/Sources/Convenience/NSFetchedResultsController+Convenience.swift @@ -26,10 +26,10 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) // MARK: - DataStack +@available(OSX 10.12, *) public extension DataStack { /** @@ -114,6 +114,7 @@ public extension DataStack { // MARK: - UnsafeDataTransaction +@available(OSX 10.12, *) public extension UnsafeDataTransaction { /** @@ -199,6 +200,7 @@ public extension UnsafeDataTransaction { // MARK: - Private +@available(OSX 10.12, *) fileprivate func createFRC(fromContext context: NSManagedObjectContext, from: From? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) -> NSFetchedResultsController { let controller = CoreStoreFetchedResultsController( @@ -218,5 +220,3 @@ fileprivate func createFRC(fromContext context: NSManagedObj ) return controller.dynamicCast() } - -#endif diff --git a/Sources/Convenience/NSManagedObject+Convenience.swift b/Sources/Convenience/NSManagedObject+Convenience.swift index c5a7291..fa60a9e 100644 --- a/Sources/Convenience/NSManagedObject+Convenience.swift +++ b/Sources/Convenience/NSManagedObject+Convenience.swift @@ -77,50 +77,43 @@ public extension NSManagedObject { return context } - /** - 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 - */ - @nonobjc - public func accessValueForKVCKey(_ KVCKey: KeyPath) -> Any? { + @nonobjc @inline(__always) + public func getValue(forKvcKey kvcKey: KeyPath) -> Any? { - self.willAccessValue(forKey: KVCKey) + self.willAccessValue(forKey: kvcKey) defer { - self.didAccessValue(forKey: KVCKey) + self.didAccessValue(forKey: kvcKey) } - return self.primitiveValue(forKey: KVCKey) + return self.primitiveValue(forKey: kvcKey) } - /** - 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 - - parameter didAccessPrimitiveValue: the closure to access the value. This is called between `willAccessValueForKey(...)` and `didAccessValueForKey(...)` - - returns: the primitive value for the KVC key - */ + @nonobjc @inline(__always) + public func getValue(forKvcKey kvcKey: KeyPath, didGetValue: (Any?) throws -> T) rethrows -> T { + + self.willAccessValue(forKey: kvcKey) + defer { + + self.didAccessValue(forKey: kvcKey) + } + return try didGetValue(self.primitiveValue(forKey: kvcKey)) + } + + @nonobjc @inline(__always) + public func getValue(forKvcKey kvcKey: KeyPath, willGetValue: () throws -> Void, didGetValue: (Any?) throws -> T) rethrows -> T { + + self.willAccessValue(forKey: kvcKey) + defer { + + self.didAccessValue(forKey: kvcKey) + } + try willGetValue() + return try didGetValue(self.primitiveValue(forKey: kvcKey)) + } + + @nonobjc @inline(__always) @discardableResult - @nonobjc - public func accessValueForKVCKey(_ KVCKey: KeyPath, _ didAccessPrimitiveValue: (Any?) throws -> T) rethrows -> T { - - self.willAccessValue(forKey: KVCKey) - defer { - - self.didAccessValue(forKey: KVCKey) - } - return try didAccessPrimitiveValue(self.primitiveValue(forKey: KVCKey)) - } - - /** - 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 - */ - @nonobjc - public func setValue(_ value: Any?, forKVCKey KVCKey: KeyPath) { + public func setValue(_ value: Any?, forKvcKey KVCKey: KeyPath) -> Any? { self.willChangeValue(forKey: KVCKey) defer { @@ -128,26 +121,33 @@ public extension NSManagedObject { self.didChangeValue(forKey: KVCKey) } self.setPrimitiveValue(value, forKey: KVCKey) + return value } - /** - 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 - - parameter didSetPrimitiveValue: the closure called between `willChangeValueForKey(...)` and `didChangeValueForKey(...)` - */ + @nonobjc @inline(__always) @discardableResult - @nonobjc - public func setValue(_ value: Any?, forKVCKey KVCKey: KeyPath, _ didSetPrimitiveValue: (Any?) throws -> T) rethrows -> T { + public func setValue(_ value: T, forKvcKey KVCKey: KeyPath, willSetValue: (T) throws -> Any?) rethrows -> T { self.willChangeValue(forKey: KVCKey) defer { self.didChangeValue(forKey: KVCKey) } - self.setPrimitiveValue(value, forKey: KVCKey) - return try didSetPrimitiveValue(value) + self.setPrimitiveValue(try willSetValue(value), forKey: KVCKey) + return value + } + + @nonobjc @inline(__always) + @discardableResult + public func setValue(_ value: T, forKvcKey KVCKey: KeyPath, willSetValue: (T) throws -> Any?, didSetValue: (T) -> T = { $0 }) rethrows -> T { + + self.willChangeValue(forKey: KVCKey) + defer { + + self.didChangeValue(forKey: KVCKey) + } + self.setPrimitiveValue(try willSetValue(value), forKey: KVCKey) + return didSetValue(value) } /** @@ -167,4 +167,84 @@ public extension NSManagedObject { self.managedObjectContext?.refresh(self, mergeChanges: true) } + + + // MARK: Deprecated + + /** + 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 + */ + @available(*, deprecated: 3.1, renamed: "getValue(forKvcKey:)") + @nonobjc + public func accessValueForKVCKey(_ KVCKey: KeyPath) -> Any? { + + self.willAccessValue(forKey: KVCKey) + defer { + + self.didAccessValue(forKey: KVCKey) + } + return self.primitiveValue(forKey: KVCKey) + } + + /** + 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 + - parameter didAccessPrimitiveValue: the closure to access the value. This is called between `willAccessValueForKey(...)` and `didAccessValueForKey(...)` + - returns: the primitive value for the KVC key + */ + @available(*, deprecated: 3.1, renamed: "getValue(forKvcKey:didGetValue:)") + @discardableResult + @nonobjc + public func accessValueForKVCKey(_ KVCKey: KeyPath, _ didAccessPrimitiveValue: (Any?) throws -> T) rethrows -> T { + + self.willAccessValue(forKey: KVCKey) + defer { + + self.didAccessValue(forKey: KVCKey) + } + return try didAccessPrimitiveValue(self.primitiveValue(forKey: KVCKey)) + } + + /** + 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 + */ + @available(*, deprecated: 3.1, renamed: "setValue(_:forKvcKey:)") + @nonobjc + public func setValue(_ value: Any?, forKVCKey KVCKey: KeyPath) { + + self.willChangeValue(forKey: KVCKey) + defer { + + self.didChangeValue(forKey: KVCKey) + } + self.setPrimitiveValue(value, forKey: KVCKey) + } + + /** + 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 + - parameter didSetPrimitiveValue: the closure called between `willChangeValueForKey(...)` and `didChangeValueForKey(...)` + */ + @available(*, deprecated: 3.1, renamed: "setValue(_:forKvcKey:didSetValue:)") + @discardableResult + @nonobjc + public func setValue(_ value: Any?, forKVCKey KVCKey: KeyPath, _ didSetPrimitiveValue: (Any?) throws -> T) rethrows -> T { + + self.willChangeValue(forKey: KVCKey) + defer { + + self.didChangeValue(forKey: KVCKey) + } + self.setPrimitiveValue(value, forKey: KVCKey) + return try didSetPrimitiveValue(value) + } } diff --git a/Sources/Fetching and Querying/Attribute+Querying.swift b/Sources/Fetching and Querying/Attribute+Querying.swift index 2fc367d..ad9f4cc 100644 --- a/Sources/Fetching and Querying/Attribute+Querying.swift +++ b/Sources/Fetching and Querying/Attribute+Querying.swift @@ -27,43 +27,48 @@ import CoreData import Foundation -// MARK: - AttributeContainer.Required +// MARK: - ValueContainer.Required -public extension AttributeContainer.Required where V: CVarArg { +public extension ValueContainer.Required { - public static func == (_ attribute: AttributeContainer.Required, _ value: V) -> Where { + public static func == (_ attribute: ValueContainer.Required, _ value: V) -> Where { return Where(attribute.keyPath, isEqualTo: value) } - public static func < (_ attribute: AttributeContainer.Required, _ value: V) -> Where { + public static func < (_ attribute: ValueContainer.Required, _ value: V) -> Where { return Where("%K < %@", attribute.keyPath, value) } - public static func > (_ attribute: AttributeContainer.Required, _ value: V) -> Where { + public static func > (_ attribute: ValueContainer.Required, _ value: V) -> Where { return Where("%K > %@", attribute.keyPath, value) } - public static func <= (_ attribute: AttributeContainer.Required, _ value: V) -> Where { + public static func <= (_ attribute: ValueContainer.Required, _ value: V) -> Where { return Where("%K <= %@", attribute.keyPath, value) } - public static func >= (_ attribute: AttributeContainer.Required, _ value: V) -> Where { + public static func >= (_ attribute: ValueContainer.Required, _ value: V) -> Where { return Where("%K >= %@", attribute.keyPath, value) } - public static func != (_ attribute: AttributeContainer.Required, _ value: V) -> Where { + public static func != (_ attribute: ValueContainer.Required, _ value: V) -> Where { - return Where("%K != %@", attribute.keyPath, value) + return !Where(attribute.keyPath, isEqualTo: value) } } -// MARK: - AttributeContainer.Optional +// MARK: - ValueContainer.Optional -public extension AttributeContainer.Optional where V: CVarArg { +public extension ValueContainer.Optional { - public static func == (_ attribute: AttributeContainer.Optional, _ value: V?) -> Where { + public static func == (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { return Where(attribute.keyPath, isEqualTo: value) } + + public static func != (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { + + return !Where(attribute.keyPath, isEqualTo: value) + } } diff --git a/Sources/Fetching and Querying/BaseDataTransaction+Querying.swift b/Sources/Fetching and Querying/BaseDataTransaction+Querying.swift index 5e07541..fae9971 100644 --- a/Sources/Fetching and Querying/BaseDataTransaction+Querying.swift +++ b/Sources/Fetching and Querying/BaseDataTransaction+Querying.swift @@ -39,7 +39,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - returns: the number of `NSManagedObject`s deleted */ @discardableResult - public func deleteAll(_ from: From, _ deleteClauses: DeleteClause...) -> Int? { + public func deleteAll(_ from: From, _ deleteClauses: DeleteClause...) -> Int? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -57,7 +57,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - returns: the number of `NSManagedObject`s deleted */ @discardableResult - public func deleteAll(_ from: From, _ deleteClauses: [DeleteClause]) -> Int? { + public func deleteAll(_ from: From, _ deleteClauses: [DeleteClause]) -> Int? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -76,7 +76,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - 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. */ - public func fetchExisting(_ object: T) -> T? { + public func fetchExisting(_ object: T) -> T? { return self.context.fetchExisting(object) } @@ -87,7 +87,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter objectID: the `NSManagedObjectID` for the object - returns: the `NSManagedObject` instance if the object exists in the transaction, or `nil` if not found. */ - public func fetchExisting(_ objectID: NSManagedObjectID) -> T? { + public func fetchExisting(_ objectID: NSManagedObjectID) -> T? { return self.context.fetchExisting(objectID) } @@ -98,7 +98,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter objects: an array of `NSManagedObject`s created/fetched outside the transaction - returns: the `NSManagedObject` array for objects that exists in the transaction */ - public func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { + public func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { return self.context.fetchExisting(objects) } @@ -109,7 +109,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter objectIDs: the `NSManagedObjectID` array for the objects - returns: the `NSManagedObject` array for objects that exists in the transaction */ - public func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { + public func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { return self.context.fetchExisting(objectIDs) } @@ -121,7 +121,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - public func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { + public func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -137,7 +137,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - public func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { + public func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -153,7 +153,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - public func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { + public func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -169,7 +169,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - public func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { + public func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -185,7 +185,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { + public func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -201,7 +201,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { + public func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -217,7 +217,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - public func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { + public func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -233,7 +233,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - public func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { + public func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -249,7 +249,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { + public func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -265,7 +265,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { + public func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -287,7 +287,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { + public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -306,7 +306,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { + public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -325,7 +325,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { + public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -344,7 +344,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { + public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { CoreStore.assert( self.isRunningInAllowedQueue(), diff --git a/Sources/Fetching and Querying/Concrete Clauses/From.swift b/Sources/Fetching and Querying/Concrete Clauses/From.swift index e9fa23b..776dc39 100644 --- a/Sources/Fetching and Querying/Concrete Clauses/From.swift +++ b/Sources/Fetching and Querying/Concrete Clauses/From.swift @@ -39,10 +39,10 @@ import CoreData let person = transaction.fetchOne(From("Configuration1")) ``` */ -public struct From { +public struct From { /** - The associated `NSManagedObject` or `ManagedObject` entity class + The associated `NSManagedObject` or `CoreStoreObject` entity class */ public let entityClass: T.Type @@ -68,7 +68,7 @@ public struct From { ``` let people = transaction.fetchAll(From()) ``` - - parameter entity: the associated `NSManagedObject` or `ManagedObject` type + - parameter entity: the associated `NSManagedObject` or `CoreStoreObject` type */ public init(_ entity: T.Type) { @@ -80,7 +80,7 @@ public struct From { ``` let people = transaction.fetchAll(From(nil, "Configuration1")) ``` - - parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `ManagedObject`'s entity type. Set to `nil` to use the default configuration. + - parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `CoreStoreObject`'s entity type. Set to `nil` to use the default configuration. - parameter otherConfigurations: an optional list of other configuration names to associate objects from (see `configuration` parameter) */ public init(_ configuration: ModelConfiguration, _ otherConfigurations: ModelConfiguration...) { @@ -93,7 +93,7 @@ public struct From { ``` let people = transaction.fetchAll(From(["Configuration1", "Configuration2"])) ``` - - parameter configurations: a list of `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `ManagedObject`'s entity type. Set to `nil` to use the default configuration. + - parameter configurations: a list of `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `CoreStoreObject`'s entity type. Set to `nil` to use the default configuration. */ public init(_ configurations: [ModelConfiguration]) { @@ -105,8 +105,8 @@ public struct From { ``` let people = transaction.fetchAll(From(MyPersonEntity.self, nil, "Configuration1")) ``` - - parameter entity: the associated `NSManagedObject` or `ManagedObject` type - - parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `ManagedObject`'s entity type. Set to `nil` to use the default configuration. + - parameter entity: the associated `NSManagedObject` or `CoreStoreObject` type + - parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `CoreStoreObject`'s entity type. Set to `nil` to use the default configuration. - parameter otherConfigurations: an optional list of other configuration names to associate objects from (see `configuration` parameter) */ public init(_ entity: T.Type, _ configuration: ModelConfiguration, _ otherConfigurations: ModelConfiguration...) { @@ -119,8 +119,8 @@ public struct From { ``` let people = transaction.fetchAll(From(MyPersonEntity.self, ["Configuration1", "Configuration1"])) ``` - - parameter entity: the associated `NSManagedObject` or `ManagedObject` type - - parameter configurations: a list of `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `ManagedObject`'s entity type. Set to `nil` to use the default configuration. + - parameter entity: the associated `NSManagedObject` or `CoreStoreObject` type + - parameter configurations: a list of `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject` or `CoreStoreObject`'s entity type. Set to `nil` to use the default configuration. */ public init(_ entity: T.Type, _ configurations: [ModelConfiguration]) { diff --git a/Sources/Fetching and Querying/Concrete Clauses/Where.swift b/Sources/Fetching and Querying/Concrete Clauses/Where.swift index e3e2568..447b37f 100644 --- a/Sources/Fetching and Querying/Concrete Clauses/Where.swift +++ b/Sources/Fetching and Querying/Concrete Clauses/Where.swift @@ -139,7 +139,7 @@ public struct Where: FetchClause, QueryClause, DeleteClause, Hashable { - parameter keyPath: the keyPath to compare with - parameter object: the arguments for the `==` operator */ - public init(_ keyPath: KeyPath, isEqualTo object: T?) { + public init(_ keyPath: KeyPath, isEqualTo object: T?) { switch object { @@ -148,7 +148,7 @@ public struct Where: FetchClause, QueryClause, DeleteClause, Hashable { self.init(NSPredicate(format: "\(keyPath) == nil")) case let object?: - self.init(NSPredicate(format: "\(keyPath) == %@", argumentArray: [object.objectID])) + self.init(NSPredicate(format: "\(keyPath) == %@", argumentArray: [object.cs_toRaw().objectID])) } } @@ -169,9 +169,9 @@ public struct Where: FetchClause, QueryClause, DeleteClause, Hashable { - parameter keyPath: the keyPath to compare with - parameter list: the sequence to check membership of */ - public init(_ keyPath: KeyPath, isMemberOf list: S) where S.Iterator.Element: NSManagedObject { + public init(_ keyPath: KeyPath, isMemberOf list: S) where S.Iterator.Element: DynamicObject { - self.init(NSPredicate(format: "\(keyPath) IN %@", list.map({ $0.objectID }) as NSArray)) + self.init(NSPredicate(format: "\(keyPath) IN %@", list.map({ $0.cs_toRaw().objectID }) as NSArray)) } /** diff --git a/Sources/Fetching and Querying/CoreStore+Querying.swift b/Sources/Fetching and Querying/CoreStore+Querying.swift index 5ea202a..64ffd55 100644 --- a/Sources/Fetching and Querying/CoreStore+Querying.swift +++ b/Sources/Fetching and Querying/CoreStore+Querying.swift @@ -37,7 +37,7 @@ public extension CoreStore { - parameter object: a reference to the object created/fetched outside the `DataStack` - returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found. */ - public static func fetchExisting(_ object: T) -> T? { + public static func fetchExisting(_ object: T) -> T? { return self.defaultStack.fetchExisting(object) } @@ -48,7 +48,7 @@ public extension CoreStore { - parameter objectID: the `NSManagedObjectID` for the object - returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found. */ - public static func fetchExisting(_ objectID: NSManagedObjectID) -> T? { + public static func fetchExisting(_ objectID: NSManagedObjectID) -> T? { return self.defaultStack.fetchExisting(objectID) } @@ -59,7 +59,7 @@ public extension CoreStore { - parameter objects: an array of `NSManagedObject`s created/fetched outside the `DataStack` - returns: the `NSManagedObject` array for objects that exists in the `DataStack` */ - public static func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { + public static func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { return self.defaultStack.fetchExisting(objects) } @@ -70,7 +70,7 @@ public extension CoreStore { - parameter objectIDs: the `NSManagedObjectID` array for the objects - returns: the `NSManagedObject` array for objects that exists in the `DataStack` */ - public static func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { + public static func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { return self.defaultStack.fetchExisting(objectIDs) } @@ -82,7 +82,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - public static func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { + public static func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { return self.defaultStack.fetchOne(from, fetchClauses) } @@ -94,7 +94,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - public static func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { + public static func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { return self.defaultStack.fetchOne(from, fetchClauses) } @@ -106,7 +106,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - public static func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { + public static func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { return self.defaultStack.fetchAll(from, fetchClauses) } @@ -118,7 +118,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - public static func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { + public static func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { return self.defaultStack.fetchAll(from, fetchClauses) } @@ -130,7 +130,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public static func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { + public static func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { return self.defaultStack.fetchCount(from, fetchClauses) } @@ -142,7 +142,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public static func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { + public static func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { return self.defaultStack.fetchCount(from, fetchClauses) } @@ -154,7 +154,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - public static func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { + public static func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { return self.defaultStack.fetchObjectID(from, fetchClauses) } @@ -166,7 +166,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - public static func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { + public static func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { return self.defaultStack.fetchObjectID(from, fetchClauses) } @@ -178,7 +178,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public static func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { + public static func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { return self.defaultStack.fetchObjectIDs(from, fetchClauses) } @@ -190,7 +190,7 @@ public extension CoreStore { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public static func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { + public static func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { return self.defaultStack.fetchObjectIDs(from, fetchClauses) } @@ -205,7 +205,7 @@ public extension CoreStore { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public static func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { + public static func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { return self.defaultStack.queryValue(from, selectClause, queryClauses) } @@ -220,7 +220,7 @@ public extension CoreStore { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public static func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { + public static func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { return self.defaultStack.queryValue(from, selectClause, queryClauses) } @@ -235,7 +235,7 @@ public extension CoreStore { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public static func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { + public static func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { return self.defaultStack.queryAttributes(from, selectClause, queryClauses) } @@ -250,7 +250,7 @@ public extension CoreStore { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public static func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { + public static func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { return self.defaultStack.queryAttributes(from, selectClause, queryClauses) } diff --git a/Sources/Fetching and Querying/DataStack+Querying.swift b/Sources/Fetching and Querying/DataStack+Querying.swift index 3384446..da21ca5 100644 --- a/Sources/Fetching and Querying/DataStack+Querying.swift +++ b/Sources/Fetching and Querying/DataStack+Querying.swift @@ -39,7 +39,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter object: a reference to the object created/fetched outside the `DataStack` - returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found. */ - public func fetchExisting(_ object: T) -> T? { + public func fetchExisting(_ object: T) -> T? { return self.mainContext.fetchExisting(object) } @@ -50,7 +50,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter objectID: the `NSManagedObjectID` for the object - returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found. */ - public func fetchExisting(_ objectID: NSManagedObjectID) -> T? { + public func fetchExisting(_ objectID: NSManagedObjectID) -> T? { return self.mainContext.fetchExisting(objectID) } @@ -61,7 +61,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter objects: an array of `NSManagedObject`s created/fetched outside the `DataStack` - returns: the `NSManagedObject` array for objects that exists in the `DataStack` */ - public func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { + public func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { return self.mainContext.fetchExisting(objects) } @@ -72,7 +72,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter objectIDs: the `NSManagedObjectID` array for the objects - returns: the `NSManagedObject` array for objects that exists in the `DataStack` */ - public func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { + public func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { return self.mainContext.fetchExisting(objectIDs) } @@ -84,7 +84,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - public func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { + public func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { CoreStore.assert( Thread.isMainThread, @@ -100,7 +100,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - public func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { + public func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { CoreStore.assert( Thread.isMainThread, @@ -116,7 +116,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - public func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { + public func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { CoreStore.assert( Thread.isMainThread, @@ -132,7 +132,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - public func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { + public func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { CoreStore.assert( Thread.isMainThread, @@ -148,7 +148,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { + public func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { CoreStore.assert( Thread.isMainThread, @@ -164,7 +164,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { + public func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { CoreStore.assert( Thread.isMainThread, @@ -180,7 +180,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - public func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { + public func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { CoreStore.assert( Thread.isMainThread, @@ -196,7 +196,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - public func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { + public func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { CoreStore.assert( Thread.isMainThread, @@ -212,7 +212,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { + public func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { CoreStore.assert( Thread.isMainThread, @@ -228,7 +228,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - public func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { + public func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { CoreStore.assert( Thread.isMainThread, @@ -250,7 +250,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { + public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { CoreStore.assert( Thread.isMainThread, @@ -269,7 +269,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { + public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { CoreStore.assert( Thread.isMainThread, @@ -288,7 +288,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { + public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { CoreStore.assert( Thread.isMainThread, @@ -307,7 +307,7 @@ extension DataStack: FetchableSource, QueryableSource { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { + public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { CoreStore.assert( Thread.isMainThread, diff --git a/Sources/Fetching and Querying/FetchableSource.swift b/Sources/Fetching and Querying/FetchableSource.swift index 13268ac..a4f2f02 100644 --- a/Sources/Fetching and Querying/FetchableSource.swift +++ b/Sources/Fetching and Querying/FetchableSource.swift @@ -40,7 +40,7 @@ public protocol FetchableSource: class { - parameter object: a reference to the object created/fetched outside the `FetchableSource`'s context - returns: the `NSManagedObject` instance if the object exists in the `FetchableSource`'s context, or `nil` if not found. */ - func fetchExisting(_ object: T) -> T? + func fetchExisting(_ object: T) -> T? /** Fetches the `NSManagedObject` instance in the `FetchableSource`'s context from an `NSManagedObjectID`. @@ -48,7 +48,7 @@ public protocol FetchableSource: class { - parameter objectID: the `NSManagedObjectID` for the object - returns: the `NSManagedObject` instance if the object exists in the `FetchableSource`, or `nil` if not found. */ - func fetchExisting(_ objectID: NSManagedObjectID) -> T? + func fetchExisting(_ objectID: NSManagedObjectID) -> T? /** Fetches the `NSManagedObject` instances in the `FetchableSource`'s context from references created from another managed object context. @@ -56,7 +56,7 @@ public protocol FetchableSource: class { - parameter objects: an array of `NSManagedObject`s created/fetched outside the `FetchableSource`'s context - returns: the `NSManagedObject` array for objects that exists in the `FetchableSource` */ - func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T + func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T /** Fetches the `NSManagedObject` instances in the `FetchableSource`'s context from a list of `NSManagedObjectID`. @@ -64,7 +64,7 @@ public protocol FetchableSource: class { - parameter objectIDs: the `NSManagedObjectID` array for the objects - returns: the `NSManagedObject` array for objects that exists in the `FetchableSource`'s context */ - func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID + func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID /** Fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -73,7 +73,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? + func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? /** Fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -82,7 +82,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s */ - func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? + func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? /** Fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -91,7 +91,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? + func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? /** Fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -100,7 +100,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s */ - func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? + func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? /** Fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -109,7 +109,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? + func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? /** Fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -118,7 +118,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s */ - func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? + func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? /** Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -127,7 +127,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? + func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? /** Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -136,7 +136,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s */ - func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? + func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? /** Fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -145,7 +145,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? + func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? /** Fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses. @@ -154,7 +154,7 @@ public protocol FetchableSource: class { - parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses. - returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s */ - func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? + func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? /** The internal `NSManagedObjectContext` managed by this `FetchableSource`. Using this context directly should typically be avoided, and is provided by CoreStore only for extremely specialized cases. diff --git a/Sources/Fetching and Querying/QueryableSource.swift b/Sources/Fetching and Querying/QueryableSource.swift index b953d09..172e02b 100644 --- a/Sources/Fetching and Querying/QueryableSource.swift +++ b/Sources/Fetching and Querying/QueryableSource.swift @@ -44,7 +44,7 @@ public protocol QueryableSource: class { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? + func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? /** Queries aggregate values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. @@ -56,7 +56,7 @@ public protocol QueryableSource: class { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? + func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? /** Queries a dictionary of attribute values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. @@ -68,7 +68,7 @@ public protocol QueryableSource: class { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? + func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? /** Queries a dictionary of attribute values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. @@ -80,7 +80,7 @@ public protocol QueryableSource: class { - parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses. - returns: the result of the the query. The type of the return value is specified by the generic type of the `Select` parameter. */ - func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? + func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? /** The internal `NSManagedObjectContext` managed by this `QueryableSource`. Using this context directly should typically be avoided, and is provided by CoreStore only for extremely specialized cases. diff --git a/Sources/Importing/BaseDataTransaction+Importing.swift b/Sources/Importing/BaseDataTransaction+Importing.swift index 2fda999..d368f9c 100644 --- a/Sources/Importing/BaseDataTransaction+Importing.swift +++ b/Sources/Importing/BaseDataTransaction+Importing.swift @@ -41,7 +41,7 @@ public extension BaseDataTransaction { */ public func importObject( _ into: Into, - source: T.ImportSource) throws -> T? where T: NSManagedObject, T: ImportableObject { + source: T.ImportSource) throws -> T? where T: DynamicObject, T: ImportableObject { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -71,7 +71,7 @@ public extension BaseDataTransaction { */ public func importObject( _ object: T, - source: T.ImportSource) throws where T: NSManagedObject, T: ImportableObject { + source: T.ImportSource) throws where T: DynamicObject, T: ImportableObject { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -99,7 +99,7 @@ public extension BaseDataTransaction { */ public func importObjects( _ into: Into, - sourceArray: S) throws -> [T] where T: NSManagedObject, T: ImportableObject, S.Iterator.Element == T.ImportSource { + sourceArray: S) throws -> [T] where T: DynamicObject, T: ImportableObject, S.Iterator.Element == T.ImportSource { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -135,7 +135,7 @@ public extension BaseDataTransaction { */ public func importUniqueObject( _ into: Into, - source: T.ImportSource) throws -> T? where T: NSManagedObject, T: ImportableUniqueObject { + source: T.ImportSource) throws -> T? where T: DynamicObject, T: ImportableUniqueObject { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -188,7 +188,7 @@ public extension BaseDataTransaction { public func importUniqueObjects( _ into: Into, sourceArray: S, - preProcess: @escaping (_ mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws -> [T] where T: NSManagedObject, T: ImportableUniqueObject, S.Iterator.Element == T.ImportSource { + preProcess: @escaping (_ mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws -> [T] where T: DynamicObject, T: ImportableUniqueObject, S.Iterator.Element == T.ImportSource { CoreStore.assert( self.isRunningInAllowedQueue(), diff --git a/Sources/Importing/ImportableObject.swift b/Sources/Importing/ImportableObject.swift index 54f6c4c..55174af 100644 --- a/Sources/Importing/ImportableObject.swift +++ b/Sources/Importing/ImportableObject.swift @@ -48,7 +48,7 @@ import CoreData } ``` */ -public protocol ImportableObject: class, NSObjectProtocol, AnyObject { +public protocol ImportableObject: class { /** The data type for the import source. This is most commonly an `NSDictionary` or another external source such as an `NSUserDefaults`. @@ -71,15 +71,6 @@ public protocol ImportableObject: class, NSObjectProtocol, AnyObject { - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. */ func didInsert(from source: ImportSource, in transaction: BaseDataTransaction) throws - - - // MARK: Obsolete (`deprecated` only for reference, please use new methods) - - @available(*, deprecated: 3.0.0, renamed: "shouldInsert(from:in:)") - static func shouldInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool - - @available(*, deprecated: 3.0.0, renamed: "didInsert(from:in:)") - func didInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws } diff --git a/Sources/Importing/ImportableUniqueObject.swift b/Sources/Importing/ImportableUniqueObject.swift index 70a1c1e..97f59fa 100644 --- a/Sources/Importing/ImportableUniqueObject.swift +++ b/Sources/Importing/ImportableUniqueObject.swift @@ -114,24 +114,6 @@ public protocol ImportableUniqueObject: ImportableObject { - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. */ func update(from source: ImportSource, in transaction: BaseDataTransaction) throws - - - // MARK: Obsolete (`deprecated` only for reference, please use new methods) - - @available(*, deprecated: 3.0.0, renamed: "shouldInsert(from:in:)") - static func shouldInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool - - @available(*, deprecated: 3.0.0, renamed: "shouldUpdate(from:in:)") - static func shouldUpdateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool - - @available(*, deprecated: 3.0.0, renamed: "uniqueID(from:in:)") - static func uniqueIDFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -> UniqueIDType? - - @available(*, deprecated: 3.0.0, renamed: "didInsert(from:in:)") - func didInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws - - @available(*, deprecated: 3.0.0, renamed: "update(from:in:)") - func updateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws } @@ -191,22 +173,25 @@ public extension ImportableUniqueObject { // MARK: - ImportableUniqueObject (Default Implementations) -public extension ImportableUniqueObject where Self: NSManagedObject { +public extension ImportableUniqueObject where Self: DynamicObject { var uniqueIDValue: UniqueIDType { get { - return UniqueIDType.cs_fromImportableNativeType( - self.value(forKey: type(of: self).uniqueIDKeyPath) as! UniqueIDType.ImportableNativeType - )! + return self.cs_toRaw().getValue( + forKvcKey: type(of: self).uniqueIDKeyPath, + didGetValue: { UniqueIDType.cs_fromImportableNativeType($0 as! UniqueIDType.ImportableNativeType)! } + ) } set { - self.setValue( - newValue.cs_toImportableNativeType(), - forKey: type(of: self).uniqueIDKeyPath - ) + self.cs_toRaw() + .setValue( + newValue, + forKvcKey: type(of: self).uniqueIDKeyPath, + willSetValue: { $0.cs_toImportableNativeType() } + ) } } } diff --git a/Sources/Internal/CoreStoreFetchedResultsController.swift b/Sources/Internal/CoreStoreFetchedResultsController.swift index 87f376b..4a1c487 100644 --- a/Sources/Internal/CoreStoreFetchedResultsController.swift +++ b/Sources/Internal/CoreStoreFetchedResultsController.swift @@ -27,16 +27,15 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CoreStoreFetchedResultsController +@available(OSX 10.12, *) internal final class CoreStoreFetchedResultsController: NSFetchedResultsController { // MARK: Internal @nonobjc - internal convenience init(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest) -> Void) { + internal convenience init(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest) -> Void) { self.init( context: dataStack.mainContext, @@ -48,7 +47,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll } @nonobjc - internal init(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest) -> Void) { + internal init(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest) -> Void) { _ = from?.applyToFetchRequest( fetchRequest, @@ -115,5 +114,3 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll @nonobjc private let reapplyAffectedStores: (_ fetchRequest: NSFetchRequest, _ context: NSManagedObjectContext) -> Bool } - -#endif diff --git a/Sources/Internal/FetchedResultsControllerDelegate.swift b/Sources/Internal/FetchedResultsControllerDelegate.swift index 6b88a63..395fdfb 100644 --- a/Sources/Internal/FetchedResultsControllerDelegate.swift +++ b/Sources/Internal/FetchedResultsControllerDelegate.swift @@ -27,10 +27,9 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - FetchedResultsControllerHandler +@available(OSX 10.12, *) internal protocol FetchedResultsControllerHandler: class { func controller(_ controller: NSFetchedResultsController, didChangeObject anObject: Any, atIndexPath indexPath: IndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) @@ -47,7 +46,8 @@ internal protocol FetchedResultsControllerHandler: class { // MARK: - FetchedResultsControllerDelegate -internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResultsControllerDelegate { +@available(OSX 10.12, *) +internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResultsControllerDelegate { // MARK: Internal @@ -240,5 +240,3 @@ internal final class FetchedResultsControllerDelegate() } - -#endif diff --git a/Sources/Internal/NSManagedObjectContext+Querying.swift b/Sources/Internal/NSManagedObjectContext+Querying.swift index 9778914..d432367 100644 --- a/Sources/Internal/NSManagedObjectContext+Querying.swift +++ b/Sources/Internal/NSManagedObjectContext+Querying.swift @@ -34,15 +34,16 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { // MARK: FetchableSource @nonobjc - public func fetchExisting(_ object: T) -> T? { + public func fetchExisting(_ object: T) -> T? { - if object.objectID.isTemporaryID { + let rawObject = object.cs_toRaw() + if rawObject.objectID.isTemporaryID { do { try withExtendedLifetime(self) { (context: NSManagedObjectContext) -> Void in - try context.obtainPermanentIDs(for: [object]) + try context.obtainPermanentIDs(for: [rawObject]) } } catch { @@ -56,8 +57,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { } do { - let existingObject = try self.existingObject(with: object.objectID) - return (existingObject as! T) + let existingRawObject = try self.existingObject(with: rawObject.objectID) + if existingRawObject === rawObject { + + return object + } + return T.cs_fromRaw(object: existingRawObject) } catch { @@ -70,11 +75,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { } @nonobjc - public func fetchExisting(_ objectID: NSManagedObjectID) -> T? { + public func fetchExisting(_ objectID: NSManagedObjectID) -> T? { do { - return (try self.existingObject(with: objectID) as! T) + let existingObject = try self.existingObject(with: objectID) + return T.cs_fromRaw(object: existingObject) } catch _ { @@ -83,25 +89,25 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { } @nonobjc - public func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { + public func fetchExisting(_ objects: S) -> [T] where S.Iterator.Element == T { - return objects.flatMap { (try? self.existingObject(with: $0.objectID)) as? T } + return objects.flatMap({ self.fetchExisting($0.cs_toRaw().objectID) }) } @nonobjc - public func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { + public func fetchExisting(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID { - return objectIDs.flatMap { (try? self.existingObject(with: $0)) as? T } + return objectIDs.flatMap({ self.fetchExisting($0) }) } @nonobjc - public func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { + public func fetchOne(_ from: From, _ fetchClauses: FetchClause...) -> T? { return self.fetchOne(from, fetchClauses) } @nonobjc - public func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { + public func fetchOne(_ from: From, _ fetchClauses: [FetchClause]) -> T? { let fetchRequest = CoreStoreFetchRequest() let storeFound = from.applyToFetchRequest(fetchRequest, context: self) @@ -114,18 +120,17 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { return nil } - return self.fetchOne(fetchRequest.dynamicCast()) - .flatMap(from.entityClass.cs_from) + return self.fetchOne(fetchRequest.dynamicCast()).flatMap(from.entityClass.cs_fromRaw) } @nonobjc - public func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { + public func fetchAll(_ from: From, _ fetchClauses: FetchClause...) -> [T]? { return self.fetchAll(from, fetchClauses) } @nonobjc - public func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { + public func fetchAll(_ from: From, _ fetchClauses: [FetchClause]) -> [T]? { let fetchRequest = CoreStoreFetchRequest() let storeFound = from.applyToFetchRequest(fetchRequest, context: self) @@ -138,17 +143,18 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { return nil } - return self.fetchAll(fetchRequest.dynamicCast()) + let entityClass = from.entityClass + return self.fetchAll(fetchRequest.dynamicCast())?.map(entityClass.cs_fromRaw) } @nonobjc - public func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { + public func fetchCount(_ from: From, _ fetchClauses: FetchClause...) -> Int? { return self.fetchCount(from, fetchClauses) } @nonobjc - public func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { + public func fetchCount(_ from: From, _ fetchClauses: [FetchClause]) -> Int? { let fetchRequest = CoreStoreFetchRequest() let storeFound = from.applyToFetchRequest(fetchRequest, context: self) @@ -162,13 +168,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { } @nonobjc - public func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { + public func fetchObjectID(_ from: From, _ fetchClauses: FetchClause...) -> NSManagedObjectID? { return self.fetchObjectID(from, fetchClauses) } @nonobjc - public func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { + public func fetchObjectID(_ from: From, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? { let fetchRequest = CoreStoreFetchRequest() let storeFound = from.applyToFetchRequest(fetchRequest, context: self) @@ -185,13 +191,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { } @nonobjc - public func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { + public func fetchObjectIDs(_ from: From, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? { return self.fetchObjectIDs(from, fetchClauses) } @nonobjc - public func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { + public func fetchObjectIDs(_ from: From, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? { let fetchRequest = CoreStoreFetchRequest() let storeFound = from.applyToFetchRequest(fetchRequest, context: self) @@ -238,13 +244,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { // MARK: QueryableSource @nonobjc - public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { + public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> U? { return self.queryValue(from, selectClause, queryClauses) } @nonobjc - public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { + public func queryValue(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> U? { let fetchRequest = CoreStoreFetchRequest() let storeFound = from.applyToFetchRequest(fetchRequest, context: self) @@ -263,13 +269,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { } @nonobjc - public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { + public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: QueryClause...) -> [[String: Any]]? { return self.queryAttributes(from, selectClause, queryClauses) } @nonobjc - public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { + public func queryAttributes(_ from: From, _ selectClause: Select, _ queryClauses: [QueryClause]) -> [[String: Any]]? { let fetchRequest = CoreStoreFetchRequest() let storeFound = from.applyToFetchRequest(fetchRequest, context: self) @@ -296,6 +302,34 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource { } + // MARK: Deleting + + @nonobjc + internal func deleteAll(_ from: From, _ deleteClauses: DeleteClause...) -> Int? { + + return self.deleteAll(from, deleteClauses) + } + + @nonobjc + internal func deleteAll(_ from: From, _ deleteClauses: [DeleteClause]) -> Int? { + + let fetchRequest = CoreStoreFetchRequest() + let storeFound = from.applyToFetchRequest(fetchRequest, context: self) + + fetchRequest.fetchLimit = 0 + fetchRequest.resultType = .managedObjectResultType + fetchRequest.returnsObjectsAsFaults = true + fetchRequest.includesPropertyValues = false + deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) } + + guard storeFound else { + + return nil + } + return self.deleteAll(fetchRequest.dynamicCast()) + } + + // MARK: Deprecated @available(*, deprecated, renamed: "unsafeContext()") @@ -520,31 +554,6 @@ internal extension NSManagedObjectContext { // MARK: Deleting - @nonobjc - internal func deleteAll(_ from: From, _ deleteClauses: DeleteClause...) -> Int? { - - return self.deleteAll(from, deleteClauses) - } - - @nonobjc - internal func deleteAll(_ from: From, _ deleteClauses: [DeleteClause]) -> Int? { - - let fetchRequest = CoreStoreFetchRequest() - let storeFound = from.applyToFetchRequest(fetchRequest, context: self) - - fetchRequest.fetchLimit = 0 - fetchRequest.resultType = .managedObjectResultType - fetchRequest.returnsObjectsAsFaults = true - fetchRequest.includesPropertyValues = false - deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) } - - guard storeFound else { - - return nil - } - return self.deleteAll(fetchRequest.dynamicCast()) - } - @nonobjc internal func deleteAll(_ fetchRequest: NSFetchRequest) -> Int? { diff --git a/Sources/Logging/CoreStore+CustomDebugStringConvertible.swift b/Sources/Logging/CoreStore+CustomDebugStringConvertible.swift index b50f0e9..ad6f6fe 100644 --- a/Sources/Logging/CoreStore+CustomDebugStringConvertible.swift +++ b/Sources/Logging/CoreStore+CustomDebugStringConvertible.swift @@ -350,10 +350,9 @@ extension LegacySQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringC } -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ListMonitor +@available(OSX 10.12, *) private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertible { let sectionInfo: NSFetchedResultsSectionInfo @@ -368,6 +367,7 @@ private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertib } } +@available(OSX 10.12, *) extension ListMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { // MARK: CustomDebugStringConvertible @@ -390,7 +390,6 @@ extension ListMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvert ) } } -#endif // MARK: - LocalStorageOptions @@ -560,10 +559,9 @@ extension MigrationType: CustomDebugStringConvertible, CoreStoreDebugStringConve } -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ObjectMonitor +@available(OSX 10.12, *) extension ObjectMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { // MARK: CustomDebugStringConvertible @@ -585,7 +583,7 @@ extension ObjectMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConve ) } } -#endif + // MARK: - OrderBy @@ -646,10 +644,9 @@ extension SaveResult: CustomDebugStringConvertible, CoreStoreDebugStringConverti } -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - SectionBy +@available(OSX 10.12, *) extension SectionBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { // MARK: CustomDebugStringConvertible @@ -670,7 +667,6 @@ extension SectionBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertib ) } } -#endif // MARK: - Select diff --git a/Sources/ObjectiveC/CSBaseDataTransaction+Querying.swift b/Sources/ObjectiveC/CSBaseDataTransaction+Querying.swift index 715dafd..e40727a 100644 --- a/Sources/ObjectiveC/CSBaseDataTransaction+Querying.swift +++ b/Sources/ObjectiveC/CSBaseDataTransaction+Querying.swift @@ -40,7 +40,7 @@ public extension CSBaseDataTransaction { @objc public func fetchExistingObject(_ object: NSManagedObject) -> Any? { - return self.bridgeToSwift.context.fetchExisting(object) + return self.bridgeToSwift.context.fetchExisting(object) as NSManagedObject? } /** @@ -52,7 +52,7 @@ public extension CSBaseDataTransaction { @objc public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? { - return self.bridgeToSwift.context.fetchExisting(objectID) + return self.bridgeToSwift.context.fetchExisting(objectID) as NSManagedObject? } /** @@ -64,7 +64,7 @@ public extension CSBaseDataTransaction { @objc public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] { - return self.bridgeToSwift.context.fetchExisting(objects) + return self.bridgeToSwift.context.fetchExisting(objects) as [NSManagedObject] } /** @@ -76,7 +76,7 @@ public extension CSBaseDataTransaction { @objc public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] { - return self.bridgeToSwift.context.fetchExisting(objectIDs) + return self.bridgeToSwift.context.fetchExisting(objectIDs) as [NSManagedObject] } /** diff --git a/Sources/ObjectiveC/CSCoreStore+Observing.swift b/Sources/ObjectiveC/CSCoreStore+Observing.swift index d7bcb22..9652b16 100644 --- a/Sources/ObjectiveC/CSCoreStore+Observing.swift +++ b/Sources/ObjectiveC/CSCoreStore+Observing.swift @@ -27,10 +27,9 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSCoreStore +@available(OSX 10.12, *) public extension CSCoreStore { /** @@ -112,5 +111,3 @@ public extension CSCoreStore { ) } } - -#endif diff --git a/Sources/ObjectiveC/CSDataStack+Observing.swift b/Sources/ObjectiveC/CSDataStack+Observing.swift index 133446b..897d393 100644 --- a/Sources/ObjectiveC/CSDataStack+Observing.swift +++ b/Sources/ObjectiveC/CSDataStack+Observing.swift @@ -27,10 +27,9 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSDataStack +@available(OSX 10.12, *) public extension CSDataStack { /** @@ -42,10 +41,7 @@ public extension CSDataStack { @objc public func monitorObject(_ object: NSManagedObject) -> CSObjectMonitor { - return bridge { - - self.bridgeToSwift.monitorObject(object) - } + return self.bridgeToSwift.monitorObject(object).bridgeToObjectiveC } /** @@ -66,18 +62,15 @@ public extension CSDataStack { fetchClauses.contains { $0 is CSOrderBy }, "A CSListMonitor requires a CSOrderBy clause." ) - return bridge { - - ListMonitor( - dataStack: self.bridgeToSwift, - from: from.bridgeToSwift, - sectionBy: nil, - applyFetchClauses: { (fetchRequest) in - - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest) } - } - ) - } + return ListMonitor( + dataStack: self.bridgeToSwift, + from: from.bridgeToSwift, + sectionBy: nil, + applyFetchClauses: { (fetchRequest) in + + fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest) } + } + ).bridgeToObjectiveC } /** @@ -132,18 +125,15 @@ public extension CSDataStack { fetchClauses.contains { $0 is CSOrderBy }, "A CSListMonitor requires an CSOrderBy clause." ) - return bridge { - - ListMonitor( - dataStack: self.bridgeToSwift, - from: from.bridgeToSwift, - sectionBy: sectionBy.bridgeToSwift, - applyFetchClauses: { (fetchRequest) in - - fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest) } - } - ) - } + return ListMonitor( + dataStack: self.bridgeToSwift, + from: from.bridgeToSwift, + sectionBy: sectionBy.bridgeToSwift, + applyFetchClauses: { (fetchRequest) in + + fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest) } + } + ).bridgeToObjectiveC } /** @@ -179,5 +169,3 @@ public extension CSDataStack { ) } } - -#endif diff --git a/Sources/ObjectiveC/CSDataStack+Querying.swift b/Sources/ObjectiveC/CSDataStack+Querying.swift index 4db3ce1..fadfd8e 100644 --- a/Sources/ObjectiveC/CSDataStack+Querying.swift +++ b/Sources/ObjectiveC/CSDataStack+Querying.swift @@ -40,7 +40,7 @@ public extension CSDataStack { @objc public func fetchExistingObject(_ object: NSManagedObject) -> Any? { - return self.bridgeToSwift.mainContext.fetchExisting(object) + return self.bridgeToSwift.mainContext.fetchExisting(object) as NSManagedObject? } /** @@ -52,7 +52,7 @@ public extension CSDataStack { @objc public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? { - return self.bridgeToSwift.mainContext.fetchExisting(objectID) + return self.bridgeToSwift.mainContext.fetchExisting(objectID) as NSManagedObject? } /** @@ -64,7 +64,7 @@ public extension CSDataStack { @objc public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] { - return self.bridgeToSwift.mainContext.fetchExisting(objects) + return self.bridgeToSwift.mainContext.fetchExisting(objects) as [NSManagedObject] } /** @@ -76,7 +76,7 @@ public extension CSDataStack { @objc public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] { - return self.bridgeToSwift.mainContext.fetchExisting(objectIDs) + return self.bridgeToSwift.mainContext.fetchExisting(objectIDs) as [NSManagedObject] } /** diff --git a/Sources/ObjectiveC/CSListMonitor.swift b/Sources/ObjectiveC/CSListMonitor.swift index 8a9b6c5..071210f 100644 --- a/Sources/ObjectiveC/CSListMonitor.swift +++ b/Sources/ObjectiveC/CSListMonitor.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSListMonitor /** @@ -36,8 +34,9 @@ import CoreData - SeeAlso: `ListMonitor` */ +@available(OSX 10.12, *) @objc -public final class CSListMonitor: NSObject, CoreStoreObjectiveCType { +public final class CSListMonitor: NSObject { // MARK: Public (Accessors) @@ -546,7 +545,8 @@ public final class CSListMonitor: NSObject, CoreStoreObjectiveCType { // MARK: - ListMonitor -extension ListMonitor: CoreStoreSwiftType { +@available(OSX 10.12, *) +extension ListMonitor where T: NSManagedObject { // MARK: CoreStoreSwiftType @@ -554,6 +554,17 @@ extension ListMonitor: CoreStoreSwiftType { return CSListMonitor(self) } + + + // MARK: FilePrivate + + fileprivate func downcast() -> ListMonitor { + + @inline(__always) + func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { + + return unsafeBitCast(x, to: type) + } + return noWarnUnsafeBitCast(self, to: ListMonitor.self) + } } - -#endif diff --git a/Sources/ObjectiveC/CSListObserver.swift b/Sources/ObjectiveC/CSListObserver.swift index a657d6f..ff57b34 100644 --- a/Sources/ObjectiveC/CSListObserver.swift +++ b/Sources/ObjectiveC/CSListObserver.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSListObserver /** @@ -42,6 +40,7 @@ import CoreData - SeeAlso: `ListObserver` */ +@available(OSX 10.12, *) @objc public protocol CSListObserver: class, AnyObject { @@ -92,6 +91,7 @@ public protocol CSListObserver: class, AnyObject { - SeeAlso: `ListObjectObserver` */ +@available(OSX 10.12, *) @objc public protocol CSListObjectObserver: CSListObserver { @@ -152,6 +152,7 @@ public protocol CSListObjectObserver: CSListObserver { - SeeAlso: `ListSectionObserver` */ +@available(OSX 10.12, *) @objc public protocol CSListSectionObserver: CSListObjectObserver { @@ -175,5 +176,3 @@ public protocol CSListSectionObserver: CSListObjectObserver { @objc optional func listMonitor(_ monitor: CSListMonitor, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) } - -#endif diff --git a/Sources/ObjectiveC/CSObjectMonitor.swift b/Sources/ObjectiveC/CSObjectMonitor.swift index 5b8bfc7..aca5a49 100644 --- a/Sources/ObjectiveC/CSObjectMonitor.swift +++ b/Sources/ObjectiveC/CSObjectMonitor.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSObjectMonitor /** @@ -36,8 +34,9 @@ import CoreData - SeeAlso: `ObjectMonitor` */ +@available(OSX 10.12, *) @objc -public final class CSObjectMonitor: NSObject, CoreStoreObjectiveCType { +public final class CSObjectMonitor: NSObject { /** Returns the `NSManagedObject` instance being observed, or `nil` if the object was already deleted. @@ -138,7 +137,8 @@ public final class CSObjectMonitor: NSObject, CoreStoreObjectiveCType { // MARK: - ObjectMonitor -extension ObjectMonitor: CoreStoreSwiftType { +@available(OSX 10.12, *) +extension ObjectMonitor where EntityType: NSManagedObject { // MARK: CoreStoreSwiftType @@ -146,6 +146,17 @@ extension ObjectMonitor: CoreStoreSwiftType { return CSObjectMonitor(self) } + + + // MARK: FilePrivate + + fileprivate func downcast() -> ObjectMonitor { + + @inline(__always) + func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { + + return unsafeBitCast(x, to: type) + } + return noWarnUnsafeBitCast(self, to: ObjectMonitor.self) + } } - -#endif diff --git a/Sources/ObjectiveC/CSObjectObserver.swift b/Sources/ObjectiveC/CSObjectObserver.swift index 7bc0934..32fd3f9 100644 --- a/Sources/ObjectiveC/CSObjectObserver.swift +++ b/Sources/ObjectiveC/CSObjectObserver.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSObjectObserver /** @@ -40,6 +38,7 @@ import CoreData - SeeAlso: `ObjectObserver` */ +@available(OSX 10.12, *) @objc public protocol CSObjectObserver: class, AnyObject { @@ -71,5 +70,3 @@ public protocol CSObjectObserver: class, AnyObject { @objc optional func objectMonitor(_ monitor: CSObjectMonitor, didDeleteObject object: Any) } - -#endif diff --git a/Sources/ObjectiveC/CSSectionBy.swift b/Sources/ObjectiveC/CSSectionBy.swift index 91b578e..6533fa0 100644 --- a/Sources/ObjectiveC/CSSectionBy.swift +++ b/Sources/ObjectiveC/CSSectionBy.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSSectionBy /** @@ -36,6 +34,7 @@ import CoreData - SeeAlso: `SectionBy` */ +@available(OSX 10.12, *) @objc public final class CSSectionBy: NSObject, CoreStoreObjectiveCType { @@ -87,6 +86,7 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType { // MARK: - SectionBy +@available(OSX 10.12, *) extension SectionBy: CoreStoreSwiftType { // MARK: CoreStoreSwiftType @@ -96,5 +96,3 @@ extension SectionBy: CoreStoreSwiftType { return CSSectionBy(self) } } - -#endif diff --git a/Sources/ObjectiveC/NSFetchedResultsController+ObjectiveC.swift b/Sources/ObjectiveC/NSFetchedResultsController+ObjectiveC.swift index bd81d1f..cbbb8fe 100644 --- a/Sources/ObjectiveC/NSFetchedResultsController+ObjectiveC.swift +++ b/Sources/ObjectiveC/NSFetchedResultsController+ObjectiveC.swift @@ -27,10 +27,9 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CSDataStack +@available(OSX 10.12, *) public extension CSDataStack { /** @@ -57,6 +56,7 @@ public extension CSDataStack { // MARK: - CSUnsafeDataTransaction +@available(OSX 10.12, *) public extension CSUnsafeDataTransaction { /** @@ -83,6 +83,7 @@ public extension CSUnsafeDataTransaction { // MARK: - Private +@available(OSX 10.12, *) fileprivate func createFRC(fromContext context: NSManagedObjectContext, from: CSFrom? = nil, sectionBy: CSSectionBy?, fetchClauses: [CSFetchClause]) -> NSFetchedResultsController { let controller = CoreStoreFetchedResultsController( @@ -102,5 +103,3 @@ fileprivate func createFRC(fromContext context: NSManagedObjectContext, from: CS ) return controller.dynamicCast() } - -#endif diff --git a/Sources/ObjectiveC/NSManagedObject+ObjectiveC.swift b/Sources/ObjectiveC/NSManagedObject+ObjectiveC.swift index 05d584c..d695e65 100644 --- a/Sources/ObjectiveC/NSManagedObject+ObjectiveC.swift +++ b/Sources/ObjectiveC/NSManagedObject+ObjectiveC.swift @@ -38,9 +38,9 @@ public extension NSManagedObject { - returns: the primitive value for the KVC key */ @objc - public func cs_accessValueForKVCKey(_ KVCKey: KeyPath) -> Any? { + public func cs_accessValueForKVCKey(_ kvcKey: KeyPath) -> Any? { - return self.accessValueForKVCKey(KVCKey) + return self.getValue(forKvcKey: kvcKey) } /** @@ -52,7 +52,7 @@ public extension NSManagedObject { @objc public func cs_setValue(_ value: Any?, forKVCKey KVCKey: KeyPath) { - self.setValue(value, forKVCKey: KVCKey) + self.setValue(value, forKvcKey: KVCKey) } /** diff --git a/Sources/Observing/CoreStore+Observing.swift b/Sources/Observing/CoreStore+Observing.swift index 72f4b53..86c5a14 100644 --- a/Sources/Observing/CoreStore+Observing.swift +++ b/Sources/Observing/CoreStore+Observing.swift @@ -27,10 +27,9 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - CoreStore +@available(OSX 10.12, *) public extension CoreStore { /** @@ -144,5 +143,3 @@ public extension CoreStore { self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses) } } - -#endif diff --git a/Sources/Observing/DataStack+Observing.swift b/Sources/Observing/DataStack+Observing.swift index 5374b77..c408637 100644 --- a/Sources/Observing/DataStack+Observing.swift +++ b/Sources/Observing/DataStack+Observing.swift @@ -27,10 +27,9 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - DataStack +@available(OSX 10.12, *) public extension DataStack { /** @@ -220,5 +219,3 @@ public extension DataStack { ) } } - -#endif diff --git a/Sources/Observing/ListMonitor.swift b/Sources/Observing/ListMonitor.swift index 200c0fa..4d5a53e 100644 --- a/Sources/Observing/ListMonitor.swift +++ b/Sources/Observing/ListMonitor.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ListMonitor /** @@ -68,7 +66,8 @@ import CoreData ``` In the example above, both `person1` and `person2` will contain the object at section=2, index=3. */ -public final class ListMonitor: Hashable { +@available(OSX 10.12, *) +public final class ListMonitor: Hashable { // MARK: Public (Accessors) @@ -80,7 +79,15 @@ public final class ListMonitor: Hashable { */ public subscript(index: Int) -> T { - return self.objectsInAllSections()[index] + CoreStore.assert( + !self.isPendingRefetch || Thread.isMainThread, + "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." + ) + if self.isSectioned { + + return T.cs_fromRaw(object: self.fetchedResultsController.fetchedObjects![index]) + } + return self[0, index] } /** @@ -91,12 +98,16 @@ public final class ListMonitor: Hashable { */ public subscript(safeIndex index: Int) -> T? { - let objects = self.objectsInAllSections() - guard objects.indices.contains(index) else { + if self.isSectioned { + let fetchedObjects = self.fetchedResultsController.fetchedObjects! + if index < fetchedObjects.count && index >= 0 { + + return T.cs_fromRaw(object: fetchedObjects[index]) + } return nil } - return objects[index] + return self[safeSectionIndex: 0, safeItemIndex: index] } /** @@ -128,7 +139,7 @@ public final class ListMonitor: Hashable { return nil } - return section.objects?[itemIndex] as? T + return T.cs_fromRaw(object: section.objects![itemIndex] as! NSManagedObject) } /** @@ -143,7 +154,7 @@ public final class ListMonitor: Hashable { !self.isPendingRefetch || Thread.isMainThread, "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." ) - return self.fetchedResultsController.object(at: indexPath) as! T + return T.cs_fromRaw(object: self.fetchedResultsController.object(at: indexPath)) } /** @@ -191,42 +202,6 @@ public final class ListMonitor: Hashable { return self.numberOfObjectsInSection(safeSectionIndex: section)! > 0 } - /** - Returns all objects in all sections - - - returns: all objects in all sections - */ - public func objectsInAllSections() -> [T] { - - CoreStore.assert( - !self.isPendingRefetch || Thread.isMainThread, - "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." - ) - return (self.fetchedResultsController.dynamicCast() as NSFetchedResultsController).fetchedObjects ?? [] - } - - /** - 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 - */ - public func objectsInSection(_ section: Int) -> [T] { - - return (self.sectionInfoAtIndex(section).objects as! [T]?) ?? [] - } - - /** - 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 - */ - public func objectsInSection(safeSectionIndex section: Int) -> [T]? { - - return self.sectionInfoAtIndex(safeSectionIndex: section)?.objects as! [T]? - } - /** Returns the number of sections @@ -371,7 +346,11 @@ public final class ListMonitor: Hashable { !self.isPendingRefetch || Thread.isMainThread, "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." ) - return (self.fetchedResultsController.dynamicCast() as NSFetchedResultsController).fetchedObjects?.index(of: object) + if self.isSectioned { + + return self.fetchedResultsController.fetchedObjects?.index(of: object.cs_toRaw()) + } + return self.fetchedResultsController.indexPath(forObject: object.cs_toRaw())?[1] } /** @@ -386,7 +365,7 @@ public final class ListMonitor: Hashable { !self.isPendingRefetch || Thread.isMainThread, "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." ) - return self.fetchedResultsController.indexPath(forObject: object) + return self.fetchedResultsController.indexPath(forObject: object.cs_toRaw()) } @@ -596,22 +575,22 @@ public final class ListMonitor: Hashable { // MARK: Equatable - public static func == (lhs: ListMonitor, rhs: ListMonitor) -> Bool { - - return lhs === rhs - } - - public static func == (lhs: ListMonitor, rhs: ListMonitor) -> Bool { + public static func == (lhs: ListMonitor, rhs: ListMonitor) -> Bool { return lhs.fetchedResultsController === rhs.fetchedResultsController } - public static func ~= (lhs: ListMonitor, rhs: ListMonitor) -> Bool { + public static func == (lhs: ListMonitor, rhs: ListMonitor) -> Bool { - return lhs === rhs + return lhs.fetchedResultsController === rhs.fetchedResultsController } - public static func ~= (lhs: ListMonitor, rhs: ListMonitor) -> Bool { + public static func ~= (lhs: ListMonitor, rhs: ListMonitor) -> Bool { + + return lhs.fetchedResultsController === rhs.fetchedResultsController + } + + public static func ~= (lhs: ListMonitor, rhs: ListMonitor) -> Bool { return lhs.fetchedResultsController === rhs.fetchedResultsController } @@ -675,16 +654,6 @@ public final class ListMonitor: Hashable { ) } - internal func downcast() -> ListMonitor { - - @inline(__always) - func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { - - return unsafeBitCast(x, to: type) - } - return noWarnUnsafeBitCast(self, to: ListMonitor.self) - } - internal func registerChangeNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ListMonitor) -> Void) { cs_setAssociatedRetainedObject( @@ -1001,6 +970,8 @@ public final class ListMonitor: Hashable { fileprivate let taskGroup = DispatchGroup() fileprivate let sectionIndexTransformer: (_ sectionName: KeyPath?) -> String? + private let isSectioned: Bool + private var willChangeListKey: Void? private var didChangeListKey: Void? private var willRefetchListKey: Void? @@ -1014,7 +985,7 @@ public final class ListMonitor: Hashable { private var didInsertSectionKey: Void? private var didDeleteSectionKey: Void? - private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate + private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate private var observerForWillChangePersistentStore: NotificationObserver! private var observerForDidChangePersistentStore: NotificationObserver! private let transactionQueue: DispatchQueue @@ -1043,6 +1014,8 @@ public final class ListMonitor: Hashable { private init(context: NSManagedObjectContext, transactionQueue: DispatchQueue, from: From, sectionBy: SectionBy?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest) -> Void, createAsynchronously: ((ListMonitor) -> Void)?) { + self.isSectioned = (sectionBy != nil) + let fetchRequest = CoreStoreFetchRequest() fetchRequest.fetchLimit = 0 fetchRequest.resultType = .managedObjectResultType @@ -1058,7 +1031,7 @@ public final class ListMonitor: Hashable { applyFetchClauses: applyFetchClauses ) - let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate() + let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate() self.fetchedResultsController = fetchedResultsController self.fetchedResultsControllerDelegate = fetchedResultsControllerDelegate @@ -1150,9 +1123,99 @@ public final class ListMonitor: Hashable { } } + +// MARK: - ListMonitor where T: NSManagedObject + +@available(OSX 10.12, *) +extension ListMonitor where T: NSManagedObject { + + /** + Returns all objects in all sections + + - returns: all objects in all sections + */ + public func objectsInAllSections() -> [T] { + + CoreStore.assert( + !self.isPendingRefetch || Thread.isMainThread, + "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." + ) + return (self.fetchedResultsController.dynamicCast() as NSFetchedResultsController).fetchedObjects ?? [] + } + + /** + 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 + */ + public func objectsInSection(_ section: Int) -> [T] { + + return (self.sectionInfoAtIndex(section).objects as! [T]?) ?? [] + } + + /** + 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 + */ + public func objectsInSection(safeSectionIndex section: Int) -> [T]? { + + return self.sectionInfoAtIndex(safeSectionIndex: section)?.objects as! [T]? + } +} + + +// MARK: - ListMonitor where T: CoreStoreObject + +@available(OSX 10.12, *) +extension ListMonitor where T: CoreStoreObject { + + /** + Returns all objects in all sections + + - returns: all objects in all sections + */ + public func objectsInAllSections() -> [T] { + + CoreStore.assert( + !self.isPendingRefetch || Thread.isMainThread, + "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." + ) + return (self.fetchedResultsController.fetchedObjects ?? []) + .map(T.cs_fromRaw) + } + + /** + 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 + */ + public func objectsInSection(_ section: Int) -> [T] { + + return (self.sectionInfoAtIndex(section).objects ?? []) + .map({ T.cs_fromRaw(object: $0 as! NSManagedObject) }) + } + + /** + 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 + */ + public func objectsInSection(safeSectionIndex section: Int) -> [T]? { + + return (self.sectionInfoAtIndex(safeSectionIndex: section)?.objects)? + .map({ T.cs_fromRaw(object: $0 as! NSManagedObject) }) + } +} + // MARK: - ListMonitor: FetchedResultsControllerHandler +@available(OSX 10.12, *) extension ListMonitor: FetchedResultsControllerHandler { // MARK: FetchedResultsControllerHandler @@ -1259,7 +1322,8 @@ extension ListMonitor: FetchedResultsControllerHandler { // MARK: - Notification Keys - + +@available(OSX 10.12, *) fileprivate extension Notification.Name { fileprivate static let listMonitorWillChangeList = Notification.Name(rawValue: "listMonitorWillChangeList") @@ -1273,5 +1337,3 @@ fileprivate extension Notification.Name { fileprivate static let listMonitorDidInsertSection = Notification.Name(rawValue: "listMonitorDidInsertSection") fileprivate static let listMonitorDidDeleteSection = Notification.Name(rawValue: "listMonitorDidDeleteSection") } - -#endif diff --git a/Sources/Observing/ListObserver.swift b/Sources/Observing/ListObserver.swift index 17c7254..aa0cfd6 100644 --- a/Sources/Observing/ListObserver.swift +++ b/Sources/Observing/ListObserver.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ListObserver /** @@ -41,12 +39,13 @@ import CoreData monitor.addObserver(self) ``` */ +@available(OSX 10.12, *) public protocol ListObserver: class { /** The `NSManagedObject` type for the observed list */ - associatedtype ListEntityType: NSManagedObject + associatedtype ListEntityType: DynamicObject /** Handles processing just before a change to the observed list occurs. (Optional) @@ -85,6 +84,7 @@ public protocol ListObserver: class { // MARK: - ListObserver (Default Implementations) +@available(OSX 10.12, *) public extension ListObserver { public func listMonitorWillChange(_ monitor: ListMonitor) { } @@ -109,6 +109,7 @@ public extension ListObserver { monitor.addObserver(self) ``` */ +@available(OSX 10.12, *) public protocol ListObjectObserver: ListObserver { /** @@ -156,6 +157,7 @@ public protocol ListObjectObserver: ListObserver { // MARK: - ListObjectObserver (Default Implementations) +@available(OSX 10.12, *) public extension ListObjectObserver { public func listMonitor(_ monitor: ListMonitor, didInsertObject object: ListEntityType, toIndexPath indexPath: IndexPath) { } @@ -181,6 +183,7 @@ public extension ListObjectObserver { monitor.addObserver(self) ``` */ +@available(OSX 10.12, *) public protocol ListSectionObserver: ListObjectObserver { /** @@ -207,11 +210,10 @@ public protocol ListSectionObserver: ListObjectObserver { // MARK: - ListSectionObserver (Default Implementations) +@available(OSX 10.12, *) public extension ListSectionObserver { public func listMonitor(_ monitor: ListMonitor, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) { } public func listMonitor(_ monitor: ListMonitor, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) { } } - -#endif diff --git a/Sources/Observing/ObjectMonitor.swift b/Sources/Observing/ObjectMonitor.swift index 88adf35..8ab8047 100644 --- a/Sources/Observing/ObjectMonitor.swift +++ b/Sources/Observing/ObjectMonitor.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ObjectMonitor /** @@ -41,14 +39,18 @@ import CoreData Observers registered via `addObserver(_:)` are not retained. `ObjectMonitor` only keeps a `weak` reference to all observers, thus keeping itself free from retain-cycles. */ -public final class ObjectMonitor: Equatable { +@available(OSX 10.12, *) +public final class ObjectMonitor: Equatable { /** Returns the `NSManagedObject` instance being observed, or `nil` if the object was already deleted. */ public var object: EntityType? { - return self.fetchedResultsController.fetchedObjects?.first as? EntityType + return self.fetchedResultsController + .fetchedObjects? + .first + .flatMap({ EntityType.cs_fromRaw(object: $0) }) } /** @@ -56,7 +58,7 @@ public final class ObjectMonitor: Equatable { */ public var isObjectDeleted: Bool { - return self.object?.managedObjectContext == nil + return self.object?.cs_toRaw().managedObjectContext == nil } /** @@ -105,22 +107,22 @@ public final class ObjectMonitor: Equatable { // MARK: Equatable - public static func == (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { + public static func == (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { return lhs === rhs } - public static func == (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { + public static func == (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { return lhs.fetchedResultsController === rhs.fetchedResultsController } - public static func ~= (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { + public static func ~= (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { return lhs === rhs } - public static func ~= (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { + public static func ~= (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { return lhs.fetchedResultsController === rhs.fetchedResultsController } @@ -190,7 +192,7 @@ public final class ObjectMonitor: Equatable { } let previousCommitedAttributes = self.lastCommittedAttributes - let currentCommitedAttributes = object.committedValues(forKeys: nil) as! [String: NSObject] + let currentCommitedAttributes = object.cs_toRaw().committedValues(forKeys: nil) as! [String: NSObject] var changedKeys = Set() for key in currentCommitedAttributes.keys { @@ -220,16 +222,6 @@ public final class ObjectMonitor: Equatable { cs_setAssociatedRetainedObject(nilValue, forKey: &self.didUpdateObjectKey, inObject: observer) } - internal func downcast() -> ObjectMonitor { - - @inline(__always) - func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { - - return unsafeBitCast(x, to: type) - } - return noWarnUnsafeBitCast(self, to: ObjectMonitor.self) - } - deinit { self.fetchedResultsControllerDelegate.fetchedResultsController = nil @@ -239,7 +231,7 @@ public final class ObjectMonitor: Equatable { // MARK: Private private let fetchedResultsController: CoreStoreFetchedResultsController - private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate + private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate private var lastCommittedAttributes = [String: NSObject]() private var willChangeObjectKey: Void? @@ -248,22 +240,24 @@ public final class ObjectMonitor: Equatable { private init(context: NSManagedObjectContext, object: EntityType) { + let rawObject = object.cs_toRaw() let fetchRequest = CoreStoreFetchRequest() - fetchRequest.entity = object.entity + fetchRequest.entity = rawObject.entity fetchRequest.fetchLimit = 0 fetchRequest.resultType = .managedObjectResultType fetchRequest.sortDescriptors = [] fetchRequest.includesPendingChanges = false fetchRequest.shouldRefreshRefetchedObjects = true - let objectID = object.objectID + let objectID = rawObject.objectID let fetchedResultsController = CoreStoreFetchedResultsController( context: context, fetchRequest: fetchRequest.dynamicCast(), + from: nil as From?, applyFetchClauses: Where("SELF", isEqualTo: objectID).applyToFetchRequest ) - let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate() + let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate() self.fetchedResultsController = fetchedResultsController self.fetchedResultsControllerDelegate = fetchedResultsControllerDelegate @@ -272,7 +266,7 @@ public final class ObjectMonitor: Equatable { fetchedResultsControllerDelegate.fetchedResultsController = fetchedResultsController try! fetchedResultsController.performFetchFromSpecifiedStores() - self.lastCommittedAttributes = (self.object?.committedValues(forKeys: nil) as? [String: NSObject]) ?? [:] + self.lastCommittedAttributes = (self.object?.cs_toRaw().committedValues(forKeys: nil) as? [String: NSObject]) ?? [:] } private func registerChangeNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ObjectMonitor) -> Void) { @@ -281,7 +275,7 @@ public final class ObjectMonitor: Equatable { NotificationObserver( notificationName: name, object: self, - closure: { [weak self] (note) -> Void in + closure: { [weak self] _ in guard let `self` = self else { @@ -301,15 +295,15 @@ public final class ObjectMonitor: Equatable { NotificationObserver( notificationName: name, object: self, - closure: { [weak self] (note) -> Void in + closure: { [weak self] (note) in guard let `self` = self, let userInfo = note.userInfo, - let object = userInfo[String(describing: NSManagedObject.self)] as? EntityType else { + let object = userInfo[String(describing: NSManagedObject.self)] as! NSManagedObject? else { return } - callback(self, object) + callback(self, EntityType.cs_fromRaw(object: object)) } ), forKey: notificationKey, @@ -321,6 +315,7 @@ public final class ObjectMonitor: Equatable { // MARK: - ObjectMonitor: FetchedResultsControllerHandler +@available(OSX 10.12, *) extension ObjectMonitor: FetchedResultsControllerHandler { // MARK: FetchedResultsControllerHandler @@ -370,11 +365,10 @@ extension ObjectMonitor: FetchedResultsControllerHandler { // MARK: - Notification.Name +@available(OSX 10.12, *) fileprivate extension Notification.Name { fileprivate static let objectMonitorWillChangeObject = Notification.Name(rawValue: "objectMonitorWillChangeObject") fileprivate static let objectMonitorDidDeleteObject = Notification.Name(rawValue: "objectMonitorDidDeleteObject") fileprivate static let objectMonitorDidUpdateObject = Notification.Name(rawValue: "objectMonitorDidUpdateObject") } - -#endif diff --git a/Sources/Observing/ObjectObserver.swift b/Sources/Observing/ObjectObserver.swift index b9fac1a..2d51ae3 100644 --- a/Sources/Observing/ObjectObserver.swift +++ b/Sources/Observing/ObjectObserver.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - ObjectObserver /** @@ -38,12 +36,13 @@ import CoreData monitor.addObserver(self) ``` */ +@available(OSX 10.12, *) public protocol ObjectObserver: class { /** The `NSManagedObject` type for the observed object */ - associatedtype ObjectEntityType: NSManagedObject + associatedtype ObjectEntityType: DynamicObject /** Handles processing just before a change to the observed `object` occurs. (Optional) @@ -77,6 +76,7 @@ public protocol ObjectObserver: class { // MARK: - ObjectObserver (Default Implementations) +@available(OSX 10.12, *) public extension ObjectObserver { public func objectMonitor(_ monitor: ObjectMonitor, willUpdateObject object: ObjectEntityType) { } @@ -85,5 +85,3 @@ public extension ObjectObserver { public func objectMonitor(_ monitor: ObjectMonitor, didDeleteObject object: ObjectEntityType) { } } - -#endif diff --git a/Sources/Observing/SectionBy.swift b/Sources/Observing/SectionBy.swift index 63cfc9d..7c99a77 100644 --- a/Sources/Observing/SectionBy.swift +++ b/Sources/Observing/SectionBy.swift @@ -27,8 +27,6 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - SectionBy /** @@ -41,6 +39,7 @@ import CoreData ) ``` */ +@available(OSX 10.12, *) public struct SectionBy { /** @@ -72,5 +71,3 @@ public struct SectionBy { internal let sectionKeyPath: KeyPath internal let sectionIndexTransformer: (_ sectionName: String?) -> String? } - -#endif diff --git a/Sources/Observing/UnsafeDataTransaction+Observing.swift b/Sources/Observing/UnsafeDataTransaction+Observing.swift index 723ad67..7e7ac14 100644 --- a/Sources/Observing/UnsafeDataTransaction+Observing.swift +++ b/Sources/Observing/UnsafeDataTransaction+Observing.swift @@ -27,10 +27,9 @@ import Foundation import CoreData -#if os(iOS) || os(watchOS) || os(tvOS) - // MARK: - UnsafeDataTransaction +@available(OSX 10.12, *) public extension UnsafeDataTransaction { /** @@ -201,5 +200,3 @@ public extension UnsafeDataTransaction { ) } } - -#endif diff --git a/Sources/Setup/CoreStore+Setup.swift b/Sources/Setup/CoreStore+Setup.swift index a30ad63..be0cadd 100644 --- a/Sources/Setup/CoreStore+Setup.swift +++ b/Sources/Setup/CoreStore+Setup.swift @@ -50,7 +50,7 @@ public extension CoreStore { /** Returns the entity name-to-class type mapping from the `defaultStack`'s model. */ - public static func entityTypesByName(for type: ManagedObject.Type) -> [EntityName: ManagedObject.Type] { + public static func entityTypesByName(for type: CoreStoreObject.Type) -> [EntityName: CoreStoreObject.Type] { return self.defaultStack.entityTypesByName(for: type) } @@ -64,9 +64,9 @@ public extension CoreStore { } /** - Returns the `NSEntityDescription` for the specified `ManagedObject` subclass from `defaultStack`'s model. + Returns the `NSEntityDescription` for the specified `CoreStoreObject` subclass from `defaultStack`'s model. */ - public static func entityDescription(for type: ManagedObject.Type) -> NSEntityDescription? { + public static func entityDescription(for type: CoreStoreObject.Type) -> NSEntityDescription? { return self.defaultStack.entityDescription(for: type) } diff --git a/Sources/Setup/DataStack.swift b/Sources/Setup/DataStack.swift index 9812b72..afe8842 100644 --- a/Sources/Setup/DataStack.swift +++ b/Sources/Setup/DataStack.swift @@ -51,12 +51,12 @@ public final class DataStack: Equatable { self.init(model: model, migrationChain: migrationChain) } - public convenience init(dynamicModel: ObjectModel) { + public convenience init(dynamicModel: DynamicModel) { self.init(model: dynamicModel.createModel()) } - public convenience init(dynamicModels: [ObjectModel], migrationChain: MigrationChain = nil) { + public convenience init(dynamicModels: [DynamicModel], migrationChain: MigrationChain = nil) { CoreStore.assert( migrationChain.valid, @@ -130,9 +130,9 @@ public final class DataStack: Equatable { /** Returns the entity name-to-class type mapping from the `DataStack`'s model. */ - public func entityTypesByName(for type: ManagedObject.Type) -> [EntityName: ManagedObject.Type] { + public func entityTypesByName(for type: CoreStoreObject.Type) -> [EntityName: CoreStoreObject.Type] { - var entityTypesByName: [EntityName: ManagedObject.Type] = [:] + var entityTypesByName: [EntityName: CoreStoreObject.Type] = [:] for (entityIdentifier, entityDescription) in self.model.entityDescriptionsByEntityIdentifier { switch entityIdentifier.category { @@ -141,7 +141,11 @@ public final class DataStack: Equatable { continue case .coreStore: - let actualType = NSClassFromString(entityDescription.managedObjectClassName!)! as! ManagedObject.Type + guard let anyEntity = entityDescription.anyEntity else { + + continue + } + let actualType = anyEntity.type if (actualType as AnyClass).isSubclass(of: type) { entityTypesByName[entityDescription.name!] = actualType @@ -160,9 +164,9 @@ public final class DataStack: Equatable { } /** - Returns the `NSEntityDescription` for the specified `ManagedObject` subclass. + Returns the `NSEntityDescription` for the specified `CoreStoreObject` subclass. */ - public func entityDescription(for type: ManagedObject.Type) -> NSEntityDescription? { + public func entityDescription(for type: CoreStoreObject.Type) -> NSEntityDescription? { return self.entityDescription(for: EntityIdentifier(type)) } diff --git a/Sources/Setup/Dynamic Models/ManagedObject.swift b/Sources/Setup/Dynamic Models/CoreStoreObject.swift similarity index 93% rename from Sources/Setup/Dynamic Models/ManagedObject.swift rename to Sources/Setup/Dynamic Models/CoreStoreObject.swift index 246d478..6a2a74d 100644 --- a/Sources/Setup/Dynamic Models/ManagedObject.swift +++ b/Sources/Setup/Dynamic Models/CoreStoreObject.swift @@ -1,5 +1,5 @@ // -// ManagedObject.swift +// CoreStoreObject.swift // CoreStore // // Copyright © 2017 John Rommel Estropia @@ -27,9 +27,9 @@ import CoreData import Foundation -// MARK: - ManagedObject +// MARK: - CoreStoreObject -open class ManagedObject: ManagedObjectProtocol, Hashable { +open class CoreStoreObject: DynamicObject, Hashable { public required init(_ object: NSManagedObject) { @@ -47,7 +47,7 @@ open class ManagedObject: ManagedObjectProtocol, Hashable { // MARK: Equatable - public static func == (lhs: ManagedObject, rhs: ManagedObject) -> Bool { + public static func == (lhs: CoreStoreObject, rhs: CoreStoreObject) -> Bool { guard lhs.isMeta == rhs.isMeta else { diff --git a/Sources/Setup/Dynamic Models/ObjectModel.swift b/Sources/Setup/Dynamic Models/DynamicModel.swift similarity index 91% rename from Sources/Setup/Dynamic Models/ObjectModel.swift rename to Sources/Setup/Dynamic Models/DynamicModel.swift index ad94134..3ede3c0 100644 --- a/Sources/Setup/Dynamic Models/ObjectModel.swift +++ b/Sources/Setup/Dynamic Models/DynamicModel.swift @@ -1,5 +1,5 @@ // -// ObjectModel.swift +// DynamicModel.swift // CoreStore // // Copyright © 2017 John Rommel Estropia @@ -27,9 +27,9 @@ import CoreGraphics import Foundation -// MARK: - ObjectModel +// MARK: - DynamicModel -public final class ObjectModel { +public final class DynamicModel { public convenience init(version: String, entities: [EntityProtocol]) { @@ -74,7 +74,7 @@ public final class ObjectModel { self.entityName = entity.entityName } - internal init(type: ManagedObject.Type, entityName: String) { + internal init(type: CoreStoreObject.Type, entityName: String) { self.type = type self.entityName = entityName @@ -99,7 +99,7 @@ public final class ObjectModel { // MARK: EntityProtocol - internal let type: ManagedObject.Type + internal let type: CoreStoreObject.Type internal let entityName: EntityName } @@ -116,12 +116,12 @@ public final class ObjectModel { let entityDescription = ModelCache.entityDescription( for: entity, - initializer: ObjectModel.firstPassCreateEntityDescription + initializer: DynamicModel.firstPassCreateEntityDescription ) entityDescriptionsByEntity[entity] = entityDescription } - ObjectModel.secondPassConnectRelationshipAttributes(for: entityDescriptionsByEntity) - ObjectModel.thirdPassConnectInheritanceTree(for: entityDescriptionsByEntity) + DynamicModel.secondPassConnectRelationshipAttributes(for: entityDescriptionsByEntity) + DynamicModel.thirdPassConnectInheritanceTree(for: entityDescriptionsByEntity) return entityDescriptionsByEntity } model.entities = entityDescriptionsByEntity.values.sorted(by: { $0.name! < $1.name! }) @@ -147,7 +147,7 @@ public final class ObjectModel { entityDescription.name = entity.entityName entityDescription.managedObjectClassName = NSStringFromClass(NSManagedObject.self) - func createProperties(for type: ManagedObject.Type) -> [NSPropertyDescription] { + func createProperties(for type: CoreStoreObject.Type) -> [NSPropertyDescription] { var propertyDescriptions: [NSPropertyDescription] = [] for child in Mirror(reflecting: type.meta).children { @@ -161,9 +161,8 @@ public final class ObjectModel { description.isOptional = attribute.isOptional description.isIndexed = attribute.isIndexed description.defaultValue = attribute.defaultValue - description.isTransient = false + description.isTransient = attribute.isTransient // TODO: versionHash, renamingIdentifier, etc - // TODO: Separate attributes for Value, Transient, Relationship propertyDescriptions.append(description) case let relationship as RelationshipProtocol: @@ -174,7 +173,6 @@ public final class ObjectModel { description.isOrdered = relationship.isOrdered description.deleteRule = relationship.deleteRule // TODO: versionHash, renamingIdentifier, etc - // TODO: Separate attributes for Value, Transient, Relationship propertyDescriptions.append(description) default: @@ -195,7 +193,7 @@ public final class ObjectModel { relationshipsByNameByEntity[entity] = entityDescription.relationshipsByName } - func findEntity(for type: ManagedObject.Type) -> AnyEntity { + func findEntity(for type: CoreStoreObject.Type) -> AnyEntity { var matchedEntities: Set = [] for (entity, _) in entityDescriptionsByEntity where entity.type == type { @@ -209,7 +207,7 @@ public final class ObjectModel { if matchedEntities.isEmpty { CoreStore.abort( - "No \(cs_typeName("Entity<\(type)>")) instance found in the \(cs_typeName(ObjectModel.self))." + "No \(cs_typeName("Entity<\(type)>")) instance found in the \(cs_typeName(DynamicModel.self))." ) } else { @@ -244,7 +242,7 @@ public final class ObjectModel { let description = relationshipsByName[relationship.keyPath]! description.destinationEntity = entityDescriptionsByEntity[destinationEntity]! - if let destinationKeyPath = destinationKeyPath { + if let destinationKeyPath = destinationKeyPath() { let inverseRelationshipDescription = findInverseRelationshipMatching( destinationEntity: destinationEntity, @@ -284,8 +282,8 @@ public final class ObjectModel { func connectBaseEntity(mirror: Mirror, entityDescription: NSEntityDescription) { guard let superclassMirror = mirror.superclassMirror, - let superType = superclassMirror.subjectType as? ManagedObject.Type, - superType != ManagedObject.self else { + let superType = superclassMirror.subjectType as? CoreStoreObject.Type, + superType != CoreStoreObject.self else { return } @@ -325,7 +323,7 @@ fileprivate enum ModelCache { return self.barrierQueue.cs_barrierSync(closure) } - fileprivate static func entityDescription(for entity: ObjectModel.AnyEntity, initializer: (ObjectModel.AnyEntity) -> NSEntityDescription) -> NSEntityDescription { + fileprivate static func entityDescription(for entity: DynamicModel.AnyEntity, initializer: (DynamicModel.AnyEntity) -> NSEntityDescription) -> NSEntityDescription { if let cachedEntityDescription = self.entityDescriptionsByEntity[entity] { @@ -341,5 +339,5 @@ fileprivate enum ModelCache { private static let barrierQueue = DispatchQueue.concurrent("com.coreStore.modelCacheBarrierQueue") - private static var entityDescriptionsByEntity: [ObjectModel.AnyEntity: NSEntityDescription] = [:] + private static var entityDescriptionsByEntity: [DynamicModel.AnyEntity: NSEntityDescription] = [:] } diff --git a/Sources/Setup/Dynamic Models/ManagedObjectProtocol.swift b/Sources/Setup/Dynamic Models/DynamicObject.swift similarity index 74% rename from Sources/Setup/Dynamic Models/ManagedObjectProtocol.swift rename to Sources/Setup/Dynamic Models/DynamicObject.swift index f933f07..8baa366 100644 --- a/Sources/Setup/Dynamic Models/ManagedObjectProtocol.swift +++ b/Sources/Setup/Dynamic Models/DynamicObject.swift @@ -1,5 +1,5 @@ // -// ManagedObjectProtocol.swift +// DynamicObject.swift // CoreStore // // Copyright © 2017 John Rommel Estropia @@ -26,25 +26,27 @@ import Foundation -// MARK: - ManagedObjectProtocol +// MARK: - DynamicObject -public protocol ManagedObjectProtocol: class { +public protocol DynamicObject: class { static func cs_forceCreate(entityDescription: NSEntityDescription, into context: NSManagedObjectContext, assignTo store: NSPersistentStore) -> Self - static func cs_from(object: NSManagedObject) -> Self + static func cs_fromRaw(object: NSManagedObject) -> Self + + func cs_toRaw() -> NSManagedObject } -public extension ManagedObjectProtocol where Self: ManagedObject { +public extension DynamicObject where Self: CoreStoreObject { @inline(__always) - public static func keyPath(_ attribute: (Self) -> AttributeContainer.Required) -> String { + public static func keyPath(_ attribute: (Self) -> ValueContainer.Required) -> String { return attribute(self.meta).keyPath } @inline(__always) - public static func keyPath(_ attribute: (Self) -> AttributeContainer.Optional) -> String { + public static func keyPath(_ attribute: (Self) -> ValueContainer.Optional) -> String { return attribute(self.meta).keyPath } @@ -67,19 +69,9 @@ public extension ManagedObjectProtocol where Self: ManagedObject { // MARK: - NSManagedObject -extension NSManagedObject: ManagedObjectProtocol { +extension NSManagedObject: DynamicObject { - // MARK: ManagedObjectProtocol - - public class func cs_from(object: NSManagedObject) -> Self { - - @inline(__always) - func forceCast(_ value: Any) -> T { - - return value as! T - } - return forceCast(object) - } + // MARK: DynamicObject public class func cs_forceCreate(entityDescription: NSEntityDescription, into context: NSManagedObjectContext, assignTo store: NSPersistentStore) -> Self { @@ -90,19 +82,29 @@ extension NSManagedObject: ManagedObjectProtocol { } return object } + + public class func cs_fromRaw(object: NSManagedObject) -> Self { + + @inline(__always) + func forceCast(_ value: Any) -> T { + + return value as! T + } + return forceCast(object) + } + + public func cs_toRaw() -> NSManagedObject { + + return self + } } -// MARK: - ManagedObject +// MARK: - CoreStoreObject -extension ManagedObject { +extension CoreStoreObject { - // MARK: ManagedObjectProtocol - - public class func cs_from(object: NSManagedObject) -> Self { - - return self.init(object) - } + // MARK: DynamicObject public class func cs_forceCreate(entityDescription: NSEntityDescription, into context: NSManagedObjectContext, assignTo store: NSPersistentStore) -> Self { @@ -114,4 +116,14 @@ extension ManagedObject { } return self.init(object) } + + public class func cs_fromRaw(object: NSManagedObject) -> Self { + + return self.init(object) + } + + public func cs_toRaw() -> NSManagedObject { + + return self.rawObject! + } } diff --git a/Sources/Setup/Dynamic Models/Entity.swift b/Sources/Setup/Dynamic Models/Entity.swift index 9219a1b..7ec9882 100644 --- a/Sources/Setup/Dynamic Models/Entity.swift +++ b/Sources/Setup/Dynamic Models/Entity.swift @@ -32,14 +32,14 @@ import ObjectiveC public protocol EntityProtocol { - var type: ManagedObject.Type { get } + var type: CoreStoreObject.Type { get } var entityName: EntityName { get } } // MARK: Entity -public struct Entity: EntityProtocol { +public struct Entity: EntityProtocol { public init(_ entityName: String) { @@ -49,7 +49,7 @@ public struct Entity: EntityProtocol { // MARK: EntityProtocol - public let type: ManagedObject.Type + public let type: CoreStoreObject.Type public let entityName: EntityName } @@ -78,24 +78,24 @@ internal struct EntityIdentifier: Hashable { self.interfacedClassName = String(reflecting: type) } - internal init(_ type: ManagedObject.Type) { + internal init(_ type: CoreStoreObject.Type) { self.category = .coreStore self.interfacedClassName = String(reflecting: type) } - internal init(_ type: ManagedObjectProtocol.Type) { + internal init(_ type: DynamicObject.Type) { switch type { case let type as NSManagedObject.Type: self.init(type) - case let type as ManagedObject.Type: + case let type as CoreStoreObject.Type: self.init(type) default: - CoreStore.abort("\(cs_typeName(ManagedObjectProtocol.self)) is not meant to be implemented by external types.") + CoreStore.abort("\(cs_typeName(DynamicObject.self)) is not meant to be implemented by external types.") } } @@ -138,7 +138,7 @@ internal struct EntityIdentifier: Hashable { internal extension NSEntityDescription { @nonobjc - internal var anyEntity: ObjectModel.AnyEntity? { + internal var anyEntity: DynamicModel.AnyEntity? { get { @@ -148,8 +148,8 @@ internal extension NSEntityDescription { return nil } - return ObjectModel.AnyEntity( - type: NSClassFromString(typeName) as! ManagedObject.Type, + return DynamicModel.AnyEntity( + type: NSClassFromString(typeName) as! CoreStoreObject.Type, entityName: entityName ) } diff --git a/Sources/Setup/Dynamic Models/Relationship.swift b/Sources/Setup/Dynamic Models/Relationship.swift index ea7d593..8f2b146 100644 --- a/Sources/Setup/Dynamic Models/Relationship.swift +++ b/Sources/Setup/Dynamic Models/Relationship.swift @@ -27,9 +27,14 @@ import CoreData import Foundation -// MARK: - ManagedObjectProtocol +// MARK: Operators -public extension ManagedObjectProtocol where Self: ManagedObject { +infix operator .= : AssignmentPrecedence + + +// MARK: - DynamicObject + +public extension DynamicObject where Self: CoreStoreObject { public typealias Relationship = RelationshipContainer } @@ -37,11 +42,11 @@ public extension ManagedObjectProtocol where Self: ManagedObject { // MARK: - RelationshipContainer -public enum RelationshipContainer { +public enum RelationshipContainer { // MARK: - ToOne - public final class ToOne: RelationshipProtocol { + public final class ToOne: RelationshipProtocol { // MARK: - @@ -49,65 +54,83 @@ public enum RelationshipContainer { relationship.value = value } - - public static postfix func * (_ relationship: RelationshipContainer.ToOne) -> D? { + + public static func .= (_ relationship: RelationshipContainer.ToOne, _ relationship2: RelationshipContainer.ToOne) { - return relationship.value + relationship.value = relationship2.value } - public init(_ keyPath: String, deleteRule: DeleteRule = .nullify) { + public convenience init(_ keyPath: KeyPath, deleteRule: DeleteRule = .nullify) { - self.keyPath = keyPath - self.deleteRule = deleteRule.nativeValue - self.inverse = (D.self, nil) + self.init(keyPath: keyPath, inverseKeyPath: { nil }, deleteRule: deleteRule) } - public init(_ keyPath: String, inverse: (D) -> RelationshipContainer.ToOne, deleteRule: DeleteRule = .nullify) { + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToOne, deleteRule: DeleteRule = .nullify) { - self.keyPath = keyPath - self.deleteRule = deleteRule.nativeValue + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToManyOrdered, deleteRule: DeleteRule = .nullify) { - let inverseRelationship = inverse(D.meta) - self.inverse = (D.self, inverseRelationship.keyPath) + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToManyUnordered, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) } public var value: D? { get { - let object = self.accessRawObject() - let key = self.keyPath - return object.value(forKey: key) - .flatMap({ D.cs_from(object: $0 as! NSManagedObject) }) + return self.accessRawObject() + .getValue( + forKvcKey: self.keyPath, + didGetValue: { $0.flatMap({ D.cs_fromRaw(object: $0 as! NSManagedObject) }) } + ) } set { - let object = self.accessRawObject() - let key = self.keyPath - object.setValue(newValue?.rawObject, forKey: key) + self.accessRawObject() + .setValue( + newValue, + forKvcKey: self.keyPath, + willSetValue: { $0?.rawObject } + ) } } // MARK: RelationshipProtocol - public let keyPath: String + public let keyPath: KeyPath internal let isToMany = false internal let isOrdered = false internal let deleteRule: NSDeleteRule - internal let inverse: (type: ManagedObject.Type, keyPath: String?) + internal let inverse: (type: CoreStoreObject.Type, keyPath: () -> KeyPath?) internal var accessRawObject: () -> NSManagedObject = { - fatalError("\(O.self) relationship values should not be accessed") + CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.") + } + + + // MARK: Private + + private init(keyPath: KeyPath, inverseKeyPath: @escaping () -> KeyPath?, deleteRule: DeleteRule) { + + self.keyPath = keyPath + self.deleteRule = deleteRule.nativeValue + self.inverse = (D.self, inverseKeyPath) } } // MARK: - ToManyOrdered - public final class ToManyOrdered: RelationshipProtocol { + public final class ToManyOrdered: RelationshipProtocol { // MARK: - @@ -116,52 +139,194 @@ public enum RelationshipContainer { relationship.value = value } - public static postfix func * (_ relationship: RelationshipContainer.ToManyOrdered) -> [D] { + public static func .= (_ relationship: RelationshipContainer.ToManyOrdered, _ value: C) where C.Iterator.Element == D { - return relationship.value + relationship.value = Array(value) } - public init(_ keyPath: String, deleteRule: DeleteRule = .nullify) { + public static func .= (_ relationship: RelationshipContainer.ToManyOrdered, _ relationship2: RelationshipContainer.ToManyOrdered) { - self.keyPath = keyPath - self.deleteRule = deleteRule.nativeValue - self.inverse = (D.self, nil) + relationship.value = relationship2.value } + public convenience init(_ keyPath: KeyPath, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { nil }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToOne, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToManyOrdered, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToManyUnordered, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + // TODO: add subscripts, indexed operations for more performant single updates + public var value: [D] { get { - let object = self.accessRawObject() - let key = self.keyPath - guard let orderedSet = object.value(forKey: key) as! NSOrderedSet? else { - - return [] - } - return orderedSet.array as! [D] + return self.accessRawObject() + .getValue( + forKvcKey: self.keyPath, + didGetValue: { + + guard let orderedSet = $0 as! NSOrderedSet? else { + + return [] + } + return orderedSet.map({ D.cs_fromRaw(object: $0 as! NSManagedObject) }) + } + ) } set { - let object = self.accessRawObject() - let key = self.keyPath - object.setValue(NSOrderedSet(array: newValue), forKey: key) + self.accessRawObject() + .setValue( + newValue, + forKvcKey: self.keyPath, + willSetValue: { NSOrderedSet(array: $0.map({ $0.rawObject! })) } + ) } } // MARK: RelationshipProtocol - public let keyPath: String + public let keyPath: KeyPath internal let isToMany = true internal let isOptional = true internal let isOrdered = true internal let deleteRule: NSDeleteRule - internal let inverse: (type: ManagedObject.Type, keyPath: String?) + internal let inverse: (type: CoreStoreObject.Type, keyPath: () -> KeyPath?) internal var accessRawObject: () -> NSManagedObject = { - fatalError("\(O.self) relationship values should not be accessed") + CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.") + } + + + // MARK: Private + + private init(keyPath: String, inverseKeyPath: @escaping () -> String?, deleteRule: DeleteRule) { + + self.keyPath = keyPath + self.deleteRule = deleteRule.nativeValue + self.inverse = (D.self, inverseKeyPath) + } + } + + + // MARK: - ToManyUnordered + + public final class ToManyUnordered: RelationshipProtocol { + + // MARK: - + + public static func .= (_ relationship: RelationshipContainer.ToManyUnordered, _ value: Set) { + + relationship.value = value + } + + public static func .= (_ relationship: RelationshipContainer.ToManyUnordered, _ value: C) where C.Iterator.Element == D { + + relationship.value = Set(value) + } + + public static func .= (_ relationship: RelationshipContainer.ToManyUnordered, _ relationship2: RelationshipContainer.ToManyUnordered) { + + relationship.value = relationship2.value + } + + public static func .= (_ relationship: RelationshipContainer.ToManyUnordered, _ relationship2: RelationshipContainer.ToManyOrdered) { + + relationship.value = Set(relationship2.value) + } + + public convenience init(_ keyPath: KeyPath, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { nil }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToOne, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToManyOrdered, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + public convenience init(_ keyPath: KeyPath, inverse: @escaping (D) -> RelationshipContainer.ToManyUnordered, deleteRule: DeleteRule = .nullify) { + + self.init(keyPath: keyPath, inverseKeyPath: { inverse(D.meta).keyPath }, deleteRule: deleteRule) + } + + // TODO: add subscripts, indexed operations for more performant single updates + + public var value: Set { + + get { + + return self.accessRawObject() + .getValue( + forKvcKey: self.keyPath, + didGetValue: { + + guard let set = $0 as! NSSet? else { + + return [] + } + return Set(set.map({ D.cs_fromRaw(object: $0 as! NSManagedObject) })) + } + ) + } + set { + + self.accessRawObject() + .setValue( + newValue, + forKvcKey: self.keyPath, + willSetValue: { NSSet(array: $0.map({ $0.rawObject! })) } + ) + } + } + + + // MARK: RelationshipProtocol + + public let keyPath: KeyPath + + internal let isToMany = true + internal let isOptional = true + internal let isOrdered = true + internal let deleteRule: NSDeleteRule + internal let inverse: (type: CoreStoreObject.Type, keyPath: () -> KeyPath?) + + internal var accessRawObject: () -> NSManagedObject = { + + CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.") + } + + + // MARK: Private + + private init(keyPath: KeyPath, inverseKeyPath: @escaping () -> KeyPath?, deleteRule: DeleteRule) { + + self.keyPath = keyPath + self.deleteRule = deleteRule.nativeValue + self.inverse = (D.self, inverseKeyPath) } } @@ -191,10 +356,10 @@ public enum RelationshipContainer { internal protocol RelationshipProtocol: class { - var keyPath: String { get } + var keyPath: KeyPath { get } var isToMany: Bool { get } var isOrdered: Bool { get } var deleteRule: NSDeleteRule { get } - var inverse: (type: ManagedObject.Type, keyPath: String?) { get } + var inverse: (type: CoreStoreObject.Type, keyPath: () -> KeyPath?) { get } var accessRawObject: () -> NSManagedObject { get set } } diff --git a/Sources/Setup/Dynamic Models/Attribute.swift b/Sources/Setup/Dynamic Models/Value.swift similarity index 54% rename from Sources/Setup/Dynamic Models/Attribute.swift rename to Sources/Setup/Dynamic Models/Value.swift index 3ebdea1..7e20a43 100644 --- a/Sources/Setup/Dynamic Models/Attribute.swift +++ b/Sources/Setup/Dynamic Models/Value.swift @@ -1,5 +1,5 @@ // -// Attribute.swift +// Value.swift // CoreStore // // Copyright © 2017 John Rommel Estropia @@ -30,56 +30,60 @@ import Foundation // MARK: Operators infix operator .= : AssignmentPrecedence -postfix operator * -// MARK: - ManagedObjectProtocol +// MARK: - DynamicObject -public extension ManagedObjectProtocol where Self: ManagedObject { +public extension DynamicObject where Self: CoreStoreObject { - public typealias Attribute = AttributeContainer + public typealias Value = ValueContainer } -// MARK: - AttributeContainer +// MARK: - ValueContainer -public enum AttributeContainer { +public enum ValueContainer { // MARK: - Required public final class Required: AttributeProtocol { - public static func .= (_ attribute: AttributeContainer.Required, _ value: V) { + public static func .= (_ attribute: ValueContainer.Required, _ value: V) { attribute.value = value } - public static postfix func * (_ attribute: AttributeContainer.Required) -> V { + public static func .= (_ attribute: ValueContainer.Required, _ attribute2: ValueContainer.Required) { - return attribute.value + attribute.value = attribute2.value } - public init(_ keyPath: String, `default`: V = V.cs_emptyValue(), isIndexed: Bool = false) { + public init(_ keyPath: KeyPath, `default`: V = V.cs_emptyValue(), isIndexed: Bool = false, isTransient: Bool = false) { self.keyPath = keyPath - self.defaultValue = `default`.cs_toImportableNativeType() self.isIndexed = isIndexed + self.isTransient = isTransient + self.defaultValue = `default`.cs_toImportableNativeType() } public var value: V { get { - let object = self.accessRawObject() - let key = self.keyPath - let value = object.value(forKey: key)! as! V.ImportableNativeType - return V.cs_fromImportableNativeType(value)! + return self.accessRawObject() + .getValue( + forKvcKey: self.keyPath, + didGetValue: { V.cs_fromImportableNativeType($0 as! V.ImportableNativeType)! } + ) } set { - let object = self.accessRawObject() - let key = self.keyPath - object.setValue(newValue.cs_toImportableNativeType(), forKey: key) + self.accessRawObject() + .setValue( + newValue, + forKvcKey: self.keyPath, + willSetValue: { $0.cs_toImportableNativeType() } + ) } } @@ -91,15 +95,16 @@ public enum AttributeContainer { return V.cs_rawAttributeType } - public let keyPath: String + public let keyPath: KeyPath internal let isOptional = false internal let isIndexed: Bool + internal let isTransient: Bool internal let defaultValue: Any? internal var accessRawObject: () -> NSManagedObject = { - fatalError("\(O.self) attribute values should not be accessed") + CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.") } } @@ -108,19 +113,25 @@ public enum AttributeContainer { public final class Optional: AttributeProtocol { - public static func .= (_ attribute: AttributeContainer.Optional, _ value: V?) { + public static func .= (_ attribute: ValueContainer.Optional, _ value: V?) { attribute.value = value } - public static postfix func * (_ attribute: AttributeContainer.Optional) -> V? { + public static func .= (_ attribute: ValueContainer.Optional, _ attribute2: ValueContainer.Optional) { - return attribute.value + attribute.value = attribute2.value } - public init(_ keyPath: String, `default`: V? = nil) { + public static func .= (_ attribute: ValueContainer.Optional, _ attribute2: ValueContainer.Required) { + + attribute.value = attribute2.value + } + + public init(_ keyPath: KeyPath, `default`: V? = nil, isTransient: Bool = false) { self.keyPath = keyPath + self.isTransient = isTransient self.defaultValue = `default`?.cs_toImportableNativeType() } @@ -128,19 +139,20 @@ public enum AttributeContainer { get { - let object = self.accessRawObject() - let key = self.keyPath - guard let value = object.value(forKey: key) as! V.ImportableNativeType? else { - - return nil - } - return V.cs_fromImportableNativeType(value) + return self.accessRawObject() + .getValue( + forKvcKey: self.keyPath, + didGetValue: { ($0 as! V.ImportableNativeType?).flatMap(V.cs_fromImportableNativeType) } + ) } set { - let object = self.accessRawObject() - let key = self.keyPath - object.setValue(newValue?.cs_toImportableNativeType(), forKey: key) + self.accessRawObject() + .setValue( + newValue, + forKvcKey: self.keyPath, + willSetValue: { $0?.cs_toImportableNativeType() } + ) } } @@ -152,14 +164,15 @@ public enum AttributeContainer { return V.cs_rawAttributeType } - public let keyPath: String + public let keyPath: KeyPath internal let isOptional = true internal let isIndexed = false + internal let isTransient: Bool internal let defaultValue: Any? internal var accessRawObject: () -> NSManagedObject = { - fatalError("\(O.self) attribute values should not be accessed") + CoreStore.abort("Attempted to access values from a \(cs_typeName(O.self)) meta object. Meta objects are only used for querying keyPaths and infering types.") } } } @@ -171,9 +184,10 @@ internal protocol AttributeProtocol: class { static var attributeType: NSAttributeType { get } - var keyPath: String { get } + var keyPath: KeyPath { get } var isOptional: Bool { get } var isIndexed: Bool { get } + var isTransient: Bool { get } var defaultValue: Any? { get } var accessRawObject: () -> NSManagedObject { get set } } diff --git a/Sources/Transactions/AsynchronousDataTransaction.swift b/Sources/Transactions/AsynchronousDataTransaction.swift index b08c691..d8a21c7 100644 --- a/Sources/Transactions/AsynchronousDataTransaction.swift +++ b/Sources/Transactions/AsynchronousDataTransaction.swift @@ -83,12 +83,12 @@ public final class AsynchronousDataTransaction: BaseDataTransaction { // MARK: BaseDataTransaction /** - Creates a new `NSManagedObject` or `ManagedObject` with the specified entity type. + Creates a new `NSManagedObject` or `CoreStoreObject` with the specified entity type. - - parameter into: the `Into` clause indicating the destination `NSManagedObject` or `ManagedObject` entity type and the destination configuration - - returns: a new `NSManagedObject` or `ManagedObject` instance of the specified entity type. + - parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration + - returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type. */ - public override func create(_ into: Into) -> T { + public override func create(_ into: Into) -> T { CoreStore.assert( !self.isCommitted, @@ -136,7 +136,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction { - parameter object: the `NSManagedObject` type to be deleted */ - public override func delete(_ object: NSManagedObject?) { + public override func delete(_ object: T?) { CoreStore.assert( !self.isCommitted, @@ -153,7 +153,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction { - parameter object2: another `NSManagedObject` type to be deleted - parameter objects: other `NSManagedObject`s type to be deleted */ - public override func delete(_ object1: NSManagedObject?, _ object2: NSManagedObject?, _ objects: NSManagedObject?...) { + public override func delete(_ object1: T?, _ object2: T?, _ objects: T?...) { CoreStore.assert( !self.isCommitted, diff --git a/Sources/Transactions/BaseDataTransaction.swift b/Sources/Transactions/BaseDataTransaction.swift index 0578419..baefdf6 100644 --- a/Sources/Transactions/BaseDataTransaction.swift +++ b/Sources/Transactions/BaseDataTransaction.swift @@ -45,12 +45,12 @@ public /*abstract*/ class BaseDataTransaction { } /** - Creates a new `NSManagedObject` or `ManagedObject` with the specified entity type. + Creates a new `NSManagedObject` or `CoreStoreObject` with the specified entity type. - - parameter into: the `Into` clause indicating the destination `NSManagedObject` or `ManagedObject` entity type and the destination configuration - - returns: a new `NSManagedObject` or `ManagedObject` instance of the specified entity type. + - parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration + - returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type. */ - public func create(_ into: Into) -> T { + public func create(_ into: Into) -> T { let entityClass = into.entityClass CoreStore.assert( @@ -121,7 +121,7 @@ public /*abstract*/ class BaseDataTransaction { - parameter object: the `NSManagedObject` type to be edited - returns: an editable proxy for the specified `NSManagedObject`. */ - public func edit(_ object: T?) -> T? { + public func edit(_ object: T?) -> T? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -141,7 +141,7 @@ public /*abstract*/ class BaseDataTransaction { - parameter objectID: the `NSManagedObjectID` for the object to be edited - returns: an editable proxy for the specified `NSManagedObject`. */ - public func edit(_ into: Into, _ objectID: NSManagedObjectID) -> T? { + public func edit(_ into: Into, _ objectID: NSManagedObjectID) -> T? { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -152,7 +152,7 @@ public /*abstract*/ class BaseDataTransaction { || (into.configuration ?? DataStack.defaultConfigurationName) == objectID.persistentStore?.configurationName, "Attempted to update an entity of type \(cs_typeName(into.entityClass)) but the specified persistent store do not match the `NSManagedObjectID`." ) - return self.fetchExisting(objectID) as? T + return self.fetchExisting(objectID) } /** @@ -160,7 +160,7 @@ public /*abstract*/ class BaseDataTransaction { - parameter object: the `NSManagedObject` to be deleted */ - public func delete(_ object: NSManagedObject?) { + public func delete(_ object: T?) { CoreStore.assert( self.isRunningInAllowedQueue(), @@ -169,7 +169,7 @@ public /*abstract*/ class BaseDataTransaction { let context = self.context object .flatMap(context.fetchExisting) - .flatMap(context.delete) + .flatMap({ context.delete($0.cs_toRaw()) }) } /** @@ -179,7 +179,7 @@ public /*abstract*/ class BaseDataTransaction { - parameter object2: another `NSManagedObject` to be deleted - parameter objects: other `NSManagedObject`s to be deleted */ - public func delete(_ object1: NSManagedObject?, _ object2: NSManagedObject?, _ objects: NSManagedObject?...) { + public func delete(_ object1: T?, _ object2: T?, _ objects: T?...) { self.delete(([object1, object2] + objects).flatMap { $0 }) } @@ -189,15 +189,14 @@ public /*abstract*/ class BaseDataTransaction { - parameter objects: the `NSManagedObject`s to be deleted */ - public func delete(_ objects: S) where S.Iterator.Element: NSManagedObject { + public func delete(_ objects: S) where S.Iterator.Element: DynamicObject { CoreStore.assert( self.isRunningInAllowedQueue(), "Attempted to delete entities outside their designated queue." ) - let context = self.context - objects.forEach { context.fetchExisting($0).flatMap(context.delete) } + objects.forEach { context.fetchExisting($0).flatMap({ context.delete($0.cs_toRaw()) }) } } /** @@ -209,7 +208,6 @@ public /*abstract*/ class BaseDataTransaction { self.isRunningInAllowedQueue(), "Attempted to refresh entities outside their designated queue." ) - self.context.refreshAndMergeAllObjects() } @@ -231,7 +229,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access inserted objects from an already committed \(cs_typeName(self))." ) - return self.context.insertedObjects } @@ -251,7 +248,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access inserted objects from an already committed \(cs_typeName(self))." ) - return Set(self.context.insertedObjects.flatMap { $0 as? T }) } @@ -270,7 +266,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))." ) - return Set(self.context.insertedObjects.map { $0.objectID }) } @@ -290,7 +285,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))." ) - return Set(self.context.insertedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID }) } @@ -309,7 +303,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access updated objects from an already committed \(cs_typeName(self))." ) - return self.context.updatedObjects } @@ -329,7 +322,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access updated objects from an already committed \(cs_typeName(self))." ) - return Set(self.context.updatedObjects.filter { $0.isKind(of: entity) }.map { $0 as! T }) } @@ -348,7 +340,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access updated object IDs from an already committed \(cs_typeName(self))." ) - return Set(self.context.updatedObjects.map { $0.objectID }) } @@ -368,7 +359,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access updated object IDs from an already committed \(cs_typeName(self))." ) - return Set(self.context.updatedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID }) } @@ -387,7 +377,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access deleted objects from an already committed \(cs_typeName(self))." ) - return self.context.deletedObjects } @@ -407,7 +396,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access deleted objects from an already committed \(cs_typeName(self))." ) - return Set(self.context.deletedObjects.filter { $0.isKind(of: entity) }.map { $0 as! T }) } @@ -427,7 +415,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access deleted object IDs from an already committed \(cs_typeName(self))." ) - return Set(self.context.deletedObjects.map { $0.objectID }) } @@ -447,7 +434,6 @@ public /*abstract*/ class BaseDataTransaction { !self.isCommitted, "Attempted to access deleted object IDs from an already committed \(cs_typeName(self))." ) - return Set(self.context.deletedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID }) } diff --git a/Sources/Transactions/Into.swift b/Sources/Transactions/Into.swift index 1c922eb..ec070d6 100644 --- a/Sources/Transactions/Into.swift +++ b/Sources/Transactions/Into.swift @@ -39,10 +39,10 @@ import CoreData let person = transaction.create(Into("Configuration1")) ``` */ -public struct Into: Hashable { +public struct Into: Hashable { /** - The associated `NSManagedObject` or `ManagedObject` entity class + The associated `NSManagedObject` or `CoreStoreObject` entity class */ public let entityClass: T.Type @@ -103,7 +103,7 @@ public struct Into: Hashable { // MARK: Equatable - public static func == (lhs: Into, rhs: Into) -> Bool { + public static func == (lhs: Into, rhs: Into) -> Bool { return lhs.entityClass == rhs.entityClass && lhs.configuration == rhs.configuration diff --git a/Sources/Transactions/SynchronousDataTransaction.swift b/Sources/Transactions/SynchronousDataTransaction.swift index 552391e..81d4bce 100644 --- a/Sources/Transactions/SynchronousDataTransaction.swift +++ b/Sources/Transactions/SynchronousDataTransaction.swift @@ -50,12 +50,12 @@ public final class SynchronousDataTransaction: BaseDataTransaction { // MARK: BaseDataTransaction /** - Creates a new `NSManagedObject` or `ManagedObject` with the specified entity type. + Creates a new `NSManagedObject` or `CoreStoreObject` with the specified entity type. - - parameter into: the `Into` clause indicating the destination `NSManagedObject` or `ManagedObject` entity type and the destination configuration - - returns: a new `NSManagedObject` or `ManagedObject` instance of the specified entity type. + - parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration + - returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type. */ - public override func create(_ into: Into) -> T { + public override func create(_ into: Into) -> T { CoreStore.assert( !self.isCommitted, @@ -103,7 +103,7 @@ public final class SynchronousDataTransaction: BaseDataTransaction { - parameter object: the `NSManagedObject` type to be deleted */ - public override func delete(_ object: NSManagedObject?) { + public override func delete(_ object: T?) { CoreStore.assert( !self.isCommitted, @@ -120,7 +120,7 @@ public final class SynchronousDataTransaction: BaseDataTransaction { - parameter object2: another `NSManagedObject` to be deleted - parameter objects: other `NSManagedObject`s to be deleted */ - public override func delete(_ object1: NSManagedObject?, _ object2: NSManagedObject?, _ objects: NSManagedObject?...) { + public override func delete(_ object1: T?, _ object2: T?, _ objects: T?...) { CoreStore.assert( !self.isCommitted, @@ -135,7 +135,7 @@ public final class SynchronousDataTransaction: BaseDataTransaction { - parameter objects: the `NSManagedObject`s to be deleted */ - public override func delete(_ objects: S) where S.Iterator.Element: NSManagedObject { + public override func delete(_ objects: S) where S.Iterator.Element: DynamicObject { CoreStore.assert( !self.isCommitted,