diff --git a/.swiftpm/xcode/package.xcworkspace/xcuserdata/JohnEstropia.xcuserdatad/UserInterfaceState.xcuserstate b/.swiftpm/xcode/package.xcworkspace/xcuserdata/JohnEstropia.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 78e6720..0000000 Binary files a/.swiftpm/xcode/package.xcworkspace/xcuserdata/JohnEstropia.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 7a4a8d6..322dab3 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -97,6 +97,10 @@ B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; }; B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; }; B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */; }; + B50564D32350CC3100482308 /* PropertyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50564D22350CC3100482308 /* PropertyProtocol.swift */; }; + B50564D42350CC3100482308 /* PropertyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50564D22350CC3100482308 /* PropertyProtocol.swift */; }; + B50564D52350CC3100482308 /* PropertyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50564D22350CC3100482308 /* PropertyProtocol.swift */; }; + B50564D62350CC3100482308 /* PropertyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50564D22350CC3100482308 /* PropertyProtocol.swift */; }; B509C7F41E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; }; B509C7F51E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; }; B509C7F61E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; }; @@ -280,6 +284,10 @@ B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; }; B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; }; B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; }; + B53D9E5923513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53D9E5823513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift */; }; + B53D9E5A23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53D9E5823513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift */; }; + B53D9E5B23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53D9E5823513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift */; }; + B53D9E5C23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53D9E5823513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift */; }; B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; }; B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; }; B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; }; @@ -376,6 +384,14 @@ B559CD4B1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = B559CD481CAA8C6D00E4D58B /* CSStorageInterface.swift */; }; B559CD4C1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = B559CD481CAA8C6D00E4D58B /* CSStorageInterface.swift */; }; B559CD4D1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = B559CD481CAA8C6D00E4D58B /* CSStorageInterface.swift */; }; + B55BB4D4235012AE00C33E34 /* ObjectRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55BB4D3235012AE00C33E34 /* ObjectRepresentation.swift */; }; + B55BB4D5235012AE00C33E34 /* ObjectRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55BB4D3235012AE00C33E34 /* ObjectRepresentation.swift */; }; + B55BB4D6235012AE00C33E34 /* ObjectRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55BB4D3235012AE00C33E34 /* ObjectRepresentation.swift */; }; + B55BB4D7235012AE00C33E34 /* ObjectRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55BB4D3235012AE00C33E34 /* ObjectRepresentation.swift */; }; + B55BB4D823503B9500C33E34 /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; + B55BB4D923503B9600C33E34 /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; + B55BB4DA23503B9600C33E34 /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; + B55BB4DB23503B9700C33E34 /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56007101B3F6BD500A9A8F9 /* Into.swift */; }; B56007141B3F6C2800A9A8F9 /* SectionBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56007131B3F6C2800A9A8F9 /* SectionBy.swift */; }; B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56007151B4018AB00A9A8F9 /* MigrationChain.swift */; }; @@ -790,10 +806,6 @@ B5F8496D234898240029D57B /* ListSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8496B234898240029D57B /* ListSnapshot.swift */; }; B5F8496E234898240029D57B /* ListSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8496B234898240029D57B /* ListSnapshot.swift */; }; B5F8496F234898240029D57B /* ListSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F8496B234898240029D57B /* ListSnapshot.swift */; }; - B5F849712348A6690029D57B /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; - B5F849722348A6690029D57B /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; - B5F849732348A6690029D57B /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; - B5F849742348A6690029D57B /* EnvironmentKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F849702348A6690029D57B /* EnvironmentKeys.swift */; }; B5FAD6A91B50A4B400714891 /* Progress+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6A81B50A4B300714891 /* Progress+Convenience.swift */; }; B5FAD6AC1B51285300714891 /* Internals.MigrationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6AB1B51285300714891 /* Internals.MigrationManager.swift */; }; B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6AD1B518DCB00714891 /* CoreStore+Migration.swift */; }; @@ -864,6 +876,7 @@ B501FDE61CA8D20500BE22EF /* CSListObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSListObserver.swift; sourceTree = ""; }; 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 = ""; }; + B50564D22350CC3100482308 /* PropertyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyProtocol.swift; sourceTree = ""; }; B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportableAttributeType.swift; sourceTree = ""; }; B50EE14123473C92009B8C47 /* CoreStoreObject+DataSources.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+DataSources.swift"; sourceTree = ""; }; B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Convenience.swift"; sourceTree = ""; }; @@ -903,6 +916,7 @@ B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = ""; }; B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = ""; }; B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PartialObject.swift; sourceTree = ""; }; + B53D9E5823513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiffableDataSourceSnapshotProtocol.swift; sourceTree = ""; }; B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = ""; }; B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = ""; }; B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = ""; }; @@ -931,6 +945,7 @@ B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreStoreBridge.h; sourceTree = ""; }; B559CD421CAA8B6300E4D58B /* CSSetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSetupResult.swift; sourceTree = ""; }; B559CD481CAA8C6D00E4D58B /* CSStorageInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSStorageInterface.swift; sourceTree = ""; }; + B55BB4D3235012AE00C33E34 /* ObjectRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectRepresentation.swift; sourceTree = ""; }; B56007101B3F6BD500A9A8F9 /* Into.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Into.swift; sourceTree = ""; }; B56007131B3F6C2800A9A8F9 /* SectionBy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionBy.swift; sourceTree = ""; }; B56007151B4018AB00A9A8F9 /* MigrationChain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationChain.swift; sourceTree = ""; }; @@ -1294,6 +1309,17 @@ name = Observing; sourceTree = ""; }; + B50564CC2350699700482308 /* Protocols */ = { + isa = PBXGroup; + children = ( + B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */, + B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */, + B50564D22350CC3100482308 /* PropertyProtocol.swift */, + B53D9E5823513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift */, + ); + name = Protocols; + sourceTree = ""; + }; B51B5C2922D43854009FA3BA /* KeyPaths */ = { isa = PBXGroup; children = ( @@ -1485,7 +1511,7 @@ B56964D11B22FF700075EE4A /* Migrating */, B5E5FA4C22D15D3C00330931 /* DataSources */, B5E84F261AFF84920064E85B /* Convenience */, - B5E84F291AFF849C0064E85B /* Internal */, + B5E84F291AFF849C0064E85B /* Internals */, ); name = Swift; sourceTree = ""; @@ -1550,6 +1576,7 @@ B5BF7FC0234D7B2E0070E741 /* LiveObject.swift */, B5F8496B234898240029D57B /* ListSnapshot.swift */, B5BF7FC5234D7E460070E741 /* ObjectSnapshot.swift */, + B55BB4D3235012AE00C33E34 /* ObjectRepresentation.swift */, B50EE14123473C92009B8C47 /* CoreStoreObject+DataSources.swift */, B5D8CA752346E7590055D7D1 /* DataStack+DataSources.swift */, B5F335572348D75D00FD649F /* LiveResult.swift */, @@ -1677,10 +1704,10 @@ name = Convenience; sourceTree = ""; }; - B5E84F291AFF849C0064E85B /* Internal */ = { + B5E84F291AFF849C0064E85B /* Internals */ = { isa = PBXGroup; children = ( - B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */, + B50564CC2350699700482308 /* Protocols */, B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */, B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */, B5C976E61C6E3A5900B1AF90 /* Internals.CoreStoreFetchedResultsController.swift */, @@ -1708,9 +1735,8 @@ B56923C81EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift */, B5FEC18D1C9166E200532541 /* NSPersistentStore+Setup.swift */, B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */, - B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */, ); - name = Internal; + name = Internals; sourceTree = ""; }; B5ECDBEA1CA6BEAC00C7F112 /* Protocol Clauses */ = { @@ -2033,6 +2059,7 @@ buildActionMask = 2147483647; files = ( B5DE5230230BDA1300A22534 /* Shared.swift in Sources */, + B55BB4DB23503B9700C33E34 /* EnvironmentKeys.swift in Sources */, B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */, B5ECDBF91CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */, B5CA2B081F7E5ACA004B1936 /* WhereClauseType.swift in Sources */, @@ -2047,6 +2074,7 @@ B56923FA1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */, B55514EA1EED8BF900BAB888 /* From+Querying.swift in Sources */, B596BBBB1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, + B55BB4D4235012AE00C33E34 /* ObjectRepresentation.swift in Sources */, B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */, B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */, B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */, @@ -2072,13 +2100,13 @@ B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */, B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */, B51B5C2D22D43E38009FA3BA /* KeyPath+KeyPaths.swift in Sources */, + B50564D32350CC3100482308 /* PropertyProtocol.swift in Sources */, B5D8CA762346E7590055D7D1 /* DataStack+DataSources.swift in Sources */, B5BF7FC1234D7B2E0070E741 /* LiveObject.swift in Sources */, B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */, B50132302346B76E00FC238B /* Internals.FetchedDiffableDataSourceSnapshotDelegate.swift in Sources */, B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */, B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */, - B5F849712348A6690029D57B /* EnvironmentKeys.swift in Sources */, B5E1B59D1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */, B5ECDC231CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */, B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, @@ -2187,6 +2215,7 @@ B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */, B5E8A72021C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */, + B53D9E5923513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */, B5474D152227C08700B21FEC /* Internals.CoreStoreFetchRequest.swift in Sources */, B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */, B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */, @@ -2267,6 +2296,7 @@ B5BF7FC2234D7B2E0070E741 /* LiveObject.swift in Sources */, B596BBBC1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */, + B55BB4D5235012AE00C33E34 /* ObjectRepresentation.swift in Sources */, B5ECDC071CA8138100C7F112 /* CSOrderBy.swift in Sources */, B5E1B59A1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */, B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, @@ -2287,6 +2317,7 @@ B5BF7FCC234D80910070E741 /* Internals.LazyNonmutating.swift in Sources */, B5E294DE2349F8E7003E5956 /* SnapshotResult.swift in Sources */, B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */, + B50564D42350CC3100482308 /* PropertyProtocol.swift in Sources */, B53FBA141CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */, B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */, B5BF7FB3234C97910070E741 /* DiffableDataSource.swift in Sources */, @@ -2298,6 +2329,7 @@ B509C7F51E54511B0061C547 /* ImportableAttributeType.swift in Sources */, 82BA18B31C4BBD3900A0916E /* ImportableUniqueObject.swift in Sources */, B50EE14323473C96009B8C47 /* CoreStoreObject+DataSources.swift in Sources */, + B55BB4DA23503B9600C33E34 /* EnvironmentKeys.swift in Sources */, B5E1B5951CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, 18166887232B9ED60097C275 /* String+KeyPaths.swift in Sources */, B5ECDC2B1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, @@ -2322,6 +2354,7 @@ B5519A5A1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */, B5ECDBE11CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */, 82BA18C11C4BBD5300A0916E /* CoreStore+Observing.swift in Sources */, + B53D9E5A23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */, 82BA18BC1C4BBD4A00A0916E /* OrderBy.swift in Sources */, 82BA18B01C4BBD3100A0916E /* NSManagedObject+Transaction.swift in Sources */, B50132312346B76E00FC238B /* Internals.FetchedDiffableDataSourceSnapshotDelegate.swift in Sources */, @@ -2375,7 +2408,6 @@ B5D33A021E96012400C880DE /* Relationship.swift in Sources */, B559CD4B1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */, B56923CA1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */, - B5F849722348A6690029D57B /* EnvironmentKeys.swift in Sources */, B56923E51EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */, B58D0C641EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */, B533C4DC1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */, @@ -2483,6 +2515,7 @@ B5BF7FC4234D7B2E0070E741 /* LiveObject.swift in Sources */, B596BBBE1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, B546F9601C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */, + B55BB4D7235012AE00C33E34 /* ObjectRepresentation.swift in Sources */, B5ECDC0F1CA8161B00C7F112 /* CSGroupBy.swift in Sources */, B5ECDC211CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */, B52DD1C21BE1F94600949AFE /* Internals.MigrationManager.swift in Sources */, @@ -2503,6 +2536,7 @@ B5BF7FCE234D80910070E741 /* Internals.LazyNonmutating.swift in Sources */, B5E294E02349F8E7003E5956 /* SnapshotResult.swift in Sources */, B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */, + B50564D62350CC3100482308 /* PropertyProtocol.swift in Sources */, B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */, B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */, B5BF7FB5234C97910070E741 /* DiffableDataSource.swift in Sources */, @@ -2514,6 +2548,7 @@ B509C7F71E54511B0061C547 /* ImportableAttributeType.swift in Sources */, B5220E1F1D130810009BC71E /* CSListObserver.swift in Sources */, B50EE14523473C97009B8C47 /* CoreStoreObject+DataSources.swift in Sources */, + B55BB4D823503B9500C33E34 /* EnvironmentKeys.swift in Sources */, B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */, 18166889232B9ED80097C275 /* String+KeyPaths.swift in Sources */, B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */, @@ -2538,6 +2573,7 @@ B5FE4DAF1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */, B52DD1C71BE1F94600949AFE /* NSManagedObjectContext+Querying.swift in Sources */, B52DD1C81BE1F94600949AFE /* NSManagedObjectContext+Setup.swift in Sources */, + B53D9E5C23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */, B52DD1C31BE1F94600949AFE /* Internals.NotificationObserver.swift in Sources */, B52DD1A81BE1F93200949AFE /* DataStack+Querying.swift in Sources */, B50132332346B76E00FC238B /* Internals.FetchedDiffableDataSourceSnapshotDelegate.swift in Sources */, @@ -2591,7 +2627,6 @@ B56923CC1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */, B56923E71EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */, B58D0C661EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */, - B5F849742348A6690029D57B /* EnvironmentKeys.swift in Sources */, B533C4DE1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */, B5220E141D130614009BC71E /* DataStack+Observing.swift in Sources */, B52DD1A21BE1F92C00949AFE /* CoreStore+Transaction.swift in Sources */, @@ -2699,6 +2734,7 @@ B5BF7FC3234D7B2E0070E741 /* LiveObject.swift in Sources */, B596BBBD1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */, B5ECDC081CA8138100C7F112 /* CSOrderBy.swift in Sources */, + B55BB4D6235012AE00C33E34 /* ObjectRepresentation.swift in Sources */, B5E1B59B1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */, B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */, @@ -2719,6 +2755,7 @@ B5BF7FCD234D80910070E741 /* Internals.LazyNonmutating.swift in Sources */, B5E294DF2349F8E7003E5956 /* SnapshotResult.swift in Sources */, B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */, + B50564D52350CC3100482308 /* PropertyProtocol.swift in Sources */, B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */, B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */, B5BF7FB4234C97910070E741 /* DiffableDataSource.swift in Sources */, @@ -2730,6 +2767,7 @@ B509C7F61E54511B0061C547 /* ImportableAttributeType.swift in Sources */, B5E1B5961CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, B50EE14423473C97009B8C47 /* CoreStoreObject+DataSources.swift in Sources */, + B55BB4D923503B9600C33E34 /* EnvironmentKeys.swift in Sources */, B5ECDC2C1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, 18166888232B9ED70097C275 /* String+KeyPaths.swift in Sources */, B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */, @@ -2754,6 +2792,7 @@ B5519A5B1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */, B5ECDBE21CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */, B56321971BD65216006C9394 /* Select.swift in Sources */, + B53D9E5B23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */, B56321AB1BD6521C006C9394 /* Internals.FetchedResultsControllerDelegate.swift in Sources */, B563219C1BD65216006C9394 /* SectionBy.swift in Sources */, B50132322346B76E00FC238B /* Internals.FetchedDiffableDataSourceSnapshotDelegate.swift in Sources */, @@ -2807,7 +2846,6 @@ B5215CA61FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */, B5D33A031E96012400C880DE /* Relationship.swift in Sources */, B559CD4C1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */, - B5F849732348A6690029D57B /* EnvironmentKeys.swift in Sources */, B56923CB1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */, B56923E61EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */, B58D0C651EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */, diff --git a/CoreStore.xcodeproj/xcshareddata/xcschemes/CoreStore iOS.xcscheme b/CoreStore.xcodeproj/xcshareddata/xcschemes/CoreStore iOS.xcscheme index 9a36c7d..fdef8e3 100644 --- a/CoreStore.xcodeproj/xcshareddata/xcschemes/CoreStore iOS.xcscheme +++ b/CoreStore.xcodeproj/xcshareddata/xcschemes/CoreStore iOS.xcscheme @@ -41,18 +41,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - - - + + + + + + - - ()) - palette.setInitialValues(in: transaction) - }, - completion: { _ in } - ) - }, - label: { - Image(systemName: "plus") - } - ) + for palette in try transaction.fetchAll(From()) { + + palette.hue .= Palette.randomHue() + palette.colorName .= nil + } + }, + completion: { _ in } + ) + }, + label: { + Image(systemName: "goforward") + } + ) + .frame(width: 30) + Button( + action: { + + self.dataStack.perform( + asynchronous: { transaction in + + let palette = transaction.create(Into()) + palette.setInitialValues(in: transaction) + }, + completion: { _ in } + ) + }, + label: { + Image(systemName: "plus") + } + ) + .frame(width: 30) + } ) .alert( isPresented: $needsShowAlert, diff --git a/CoreStoreTests/DynamicModelTests.swift b/CoreStoreTests/DynamicModelTests.swift index 2283795..1147710 100644 --- a/CoreStoreTests/DynamicModelTests.swift +++ b/CoreStoreTests/DynamicModelTests.swift @@ -164,24 +164,72 @@ class DynamicModelTests: BaseTestDataTestCase { animal.color .= .yellow XCTAssertEqual(animal.color.value, Color.yellow) + + for property in Animal.metaProperties(includeSuperclasses: true) { + + switch property.keyPath { + + case String(keyPath: \Animal.species): + XCTAssertTrue(property is ValueContainer.Required) + + case String(keyPath: \Animal.master): + XCTAssertTrue(property is RelationshipContainer.ToOne) + + case String(keyPath: \Animal.color): + XCTAssertTrue(property is TransformableContainer.Optional) + + default: + XCTFail("Unknown KeyPath: \"\(property.keyPath)\"") + } + } let dog = transaction.create(Into()) XCTAssertEqual(dog.species.value, "Swift") XCTAssertEqual(dog.nickname.value, nil) XCTAssertEqual(dog.age.value, 1) - #if swift(>=5.1) + for property in Dog.metaProperties(includeSuperclasses: true) { - let dogKeyPathBuilder = Dog.keyPathBuilder() - XCTAssertEqual(dogKeyPathBuilder.species.keyPathString, "SELF.species") - XCTAssertEqual(dogKeyPathBuilder.master.title.keyPathString, "SELF.master.title") - let a = dogKeyPathBuilder.master - let b = dogKeyPathBuilder.master.spouse - let c = dogKeyPathBuilder.master.spouse.pets - let d = dogKeyPathBuilder.master.spouse.pets.color - XCTAssertEqual(dogKeyPathBuilder.master.spouse.pets.color.keyPathString, "SELF.master.spouse.pets.color") + switch property.keyPath { - #endif + case String(keyPath: \Dog.species): + XCTAssertTrue(property is ValueContainer.Required) + + case String(keyPath: \Dog.master): + XCTAssertTrue(property is RelationshipContainer.ToOne) + + case String(keyPath: \Dog.color): + XCTAssertTrue(property is TransformableContainer.Optional) + + case String(keyPath: \Dog.nickname): + XCTAssertTrue(property is ValueContainer.Optional) + + case String(keyPath: \Dog.age): + XCTAssertTrue(property is ValueContainer.Required) + + case String(keyPath: \Dog.friends): + XCTAssertTrue(property is RelationshipContainer.ToManyOrdered) + + case String(keyPath: \Dog.friendedBy): + XCTAssertTrue(property is RelationshipContainer.ToManyUnordered) + + default: + XCTFail("Unknown KeyPath: \"\(property.keyPath)\"") + } + } + +// #if swift(>=5.1) +// +// let dogKeyPathBuilder = Dog.keyPathBuilder() +// XCTAssertEqual(dogKeyPathBuilder.species.keyPathString, "SELF.species") +// XCTAssertEqual(dogKeyPathBuilder.master.title.keyPathString, "SELF.master.title") +// let a = dogKeyPathBuilder.master +// let b = dogKeyPathBuilder.master.spouse +// let c = dogKeyPathBuilder.master.spouse.pets +// let d = dogKeyPathBuilder.master.spouse.pets.color +// XCTAssertEqual(dogKeyPathBuilder.master.spouse.pets.color.keyPathString, "SELF.master.spouse.pets.color") +// +// #endif let didSetObserver = dog.species.observe(options: [.new, .old]) { (object, change) in @@ -244,22 +292,22 @@ class DynamicModelTests: BaseTestDataTestCase { XCTAssertEqual(person.name.value, "John") XCTAssertEqual(person.displayName.value, "Mr. John") // Custom getter - let personSnapshot1 = person.createSnapshot() - XCTAssertEqual(person.name.value, personSnapshot1.name) - XCTAssertEqual(person.title.value, personSnapshot1.title) - XCTAssertEqual(person.displayName.value, personSnapshot1.displayName) +// let personSnapshot1 = person.createSnapshot() +// XCTAssertEqual(person.name.value, personSnapshot1.name) +// XCTAssertEqual(person.title.value, personSnapshot1.title) +// XCTAssertEqual(person.displayName.value, personSnapshot1.displayName) person.title .= "Sir" XCTAssertEqual(person.displayName.value, "Sir John") - XCTAssertEqual(personSnapshot1.name, "John") - XCTAssertEqual(personSnapshot1.title, "Mr.") - XCTAssertEqual(personSnapshot1.displayName, "Mr. John") +// XCTAssertEqual(personSnapshot1.name, "John") +// XCTAssertEqual(personSnapshot1.title, "Mr.") +// XCTAssertEqual(personSnapshot1.displayName, "Mr. John") - let personSnapshot2 = person.createSnapshot() - XCTAssertEqual(person.name.value, personSnapshot2.name) - XCTAssertEqual(person.title.value, personSnapshot2.title) - XCTAssertEqual(person.displayName.value, personSnapshot2.displayName) +// let personSnapshot2 = person.createSnapshot() +// XCTAssertEqual(person.name.value, personSnapshot2.name) +// XCTAssertEqual(person.title.value, personSnapshot2.title) +// XCTAssertEqual(person.displayName.value, personSnapshot2.displayName) person.pets.value.insert(dog) XCTAssertEqual(person.pets.count, 1) diff --git a/CoreStoreTests/LiveListTests.swift b/CoreStoreTests/LiveListTests.swift index e9ad339..0d8184c 100644 --- a/CoreStoreTests/LiveListTests.swift +++ b/CoreStoreTests/LiveListTests.swift @@ -33,7 +33,7 @@ import CoreStore // MARK: - LiveListTests -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) class LiveListTests: BaseTestDataTestCase { @objc diff --git a/Sources/AttributeProtocol.swift b/Sources/AttributeProtocol.swift index 0890817..37aa359 100644 --- a/Sources/AttributeProtocol.swift +++ b/Sources/AttributeProtocol.swift @@ -29,11 +29,10 @@ import CoreData // MARK: - AttributeProtocol -internal protocol AttributeProtocol: AnyObject { +internal protocol AttributeProtocol: PropertyProtocol { static var attributeType: NSAttributeType { get } - var keyPath: KeyPathString { get } var isOptional: Bool { get } var isTransient: Bool { get } var allowsExternalBinaryDataStorage: Bool { get } diff --git a/Sources/CoreStoreObject+DataSources.swift b/Sources/CoreStoreObject+DataSources.swift index 4080be2..3147b2c 100644 --- a/Sources/CoreStoreObject+DataSources.swift +++ b/Sources/CoreStoreObject+DataSources.swift @@ -13,7 +13,7 @@ import Combine // MARK: - LiveList: ObservableObject -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) extension CoreStoreObject: ObservableObject { // MARK: ObservableObject diff --git a/Sources/CoreStoreObject.swift b/Sources/CoreStoreObject.swift index 34b5de7..43d73f3 100644 --- a/Sources/CoreStoreObject.swift +++ b/Sources/CoreStoreObject.swift @@ -116,6 +116,27 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable { internal let rawObject: CoreStoreManagedObject? internal let isMeta: Bool + + internal class func metaProperties(includeSuperclasses: Bool) -> [PropertyProtocol] { + + func keyPaths(_ allKeyPaths: inout [PropertyProtocol], for dynamicType: CoreStoreObject.Type) { + + allKeyPaths.append(contentsOf: dynamicType.meta.propertyProtocolsByName()) + guard + includeSuperclasses, + case let superType as CoreStoreObject.Type = (dynamicType as AnyClass).superclass(), + superType != CoreStoreObject.self + else { + + return + } + keyPaths(&allKeyPaths, for: superType) + } + + var allKeyPaths: [PropertyProtocol] = [] + keyPaths(&allKeyPaths, for: self) + return allKeyPaths + } // MARK: Private @@ -144,6 +165,22 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable { } } } + + private func propertyProtocolsByName() -> [PropertyProtocol] { + + Internals.assert(self.isMeta, "'propertyProtocolsByName()' accessed from non-meta instance of \(Internals.typeName(self))") + + let cacheKey = ObjectIdentifier(Self.self) + if let properties = Static.propertiesCache[cacheKey] { + + return properties + } + let values: [PropertyProtocol] = Mirror(reflecting: self) + .children + .compactMap({ $0.value as? PropertyProtocol }) + Static.propertiesCache[cacheKey] = values + return values + } } @@ -187,4 +224,5 @@ fileprivate enum Static { // MARK: FilePrivate fileprivate static var metaCache: [ObjectIdentifier: Any] = [:] + fileprivate static var propertiesCache: [ObjectIdentifier: [PropertyProtocol]] = [:] } diff --git a/Sources/CoreStoreSchema.swift b/Sources/CoreStoreSchema.swift index e2def5d..91905e5 100644 --- a/Sources/CoreStoreSchema.swift +++ b/Sources/CoreStoreSchema.swift @@ -283,9 +283,9 @@ public final class CoreStoreSchema: DynamicSchema { func createProperties(for type: CoreStoreObject.Type) -> [NSPropertyDescription] { var propertyDescriptions: [NSPropertyDescription] = [] - for child in Mirror(reflecting: type.meta).children { + for property in type.metaProperties(includeSuperclasses: false) { - switch child.value { + switch property { case let attribute as AttributeProtocol: Internals.assert( @@ -378,9 +378,10 @@ public final class CoreStoreSchema: DynamicSchema { for (entity, entityDescription) in entityDescriptionsByEntity { let relationshipsByName = relationshipsByNameByEntity[entity]! - for child in Mirror(reflecting: (entity.type as! CoreStoreObject.Type).meta).children { + let entityType = entity.type as! CoreStoreObject.Type + for property in entityType.metaProperties(includeSuperclasses: false) { - switch child.value { + switch property { case let relationship as RelationshipProtocol: let (destinationType, destinationKeyPath) = relationship.inverse diff --git a/Sources/DataStack+DataSources.swift b/Sources/DataStack+DataSources.swift index 3b0c24d..34ce792 100644 --- a/Sources/DataStack+DataSources.swift +++ b/Sources/DataStack+DataSources.swift @@ -31,7 +31,7 @@ import CoreData // MARK: - DataStack -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) extension DataStack { public func liveList(_ from: From, _ fetchClauses: FetchClause...) -> LiveList { diff --git a/Sources/DiffableDataSource.TableView.swift b/Sources/DiffableDataSource.TableView.swift index 2ff6cd9..9be4987 100644 --- a/Sources/DiffableDataSource.TableView.swift +++ b/Sources/DiffableDataSource.TableView.swift @@ -48,7 +48,7 @@ import CoreData // self.tableView = tableView // self.cellProvider = cellProvider // -// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) { +// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) { // // self.rawDataSource = UITableViewDiffableDataSource( // tableView: tableView, @@ -71,7 +71,7 @@ import CoreData // public func apply(_ snapshot: ListSnapshot, animatingDifferences: Bool = true) { // // let dataSource = UITableViewDiffableDataSource. -// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) { +// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) { // // self.rawDataSource! as! UITableViewDiffableDataSource // @@ -95,7 +95,7 @@ import CoreData // private let cellProvider: (UITableView, IndexPath, ObjectType) -> UITableViewCell? // private let rawDataSource: Any? // -// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) // private var diffableDataSource: UITableViewDiffableDataSource { // // return self.rawDataSource! as! UITableViewDiffableDataSource diff --git a/Sources/DiffableDataSourceSnapshotProtocol.swift b/Sources/DiffableDataSourceSnapshotProtocol.swift new file mode 100644 index 0000000..46872bc --- /dev/null +++ b/Sources/DiffableDataSourceSnapshotProtocol.swift @@ -0,0 +1,34 @@ +// +// DiffableDataSourceSnapshotProtocol.swift +// CoreStore +// +// Copyright © 2018 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation +import CoreData + + +// MARK: - DiffableDataSourceSnapshotProtocol + +internal protocol DiffableDataSourceSnapshotProtocol { + +} diff --git a/Sources/DynamicObject.swift b/Sources/DynamicObject.swift index d5054aa..b0eebc4 100644 --- a/Sources/DynamicObject.swift +++ b/Sources/DynamicObject.swift @@ -74,10 +74,10 @@ extension DynamicObject { // MARK: Internal - internal static func keyPathBuilder() -> DynamicObjectMeta { - - return .init(keyPathString: "SELF") - } +// internal static func keyPathBuilder() -> DynamicObjectMeta { +// +// return .init(keyPathString: "SELF") +// } internal func runtimeType() -> Self.Type { diff --git a/Sources/EnvironmentKeys.swift b/Sources/EnvironmentKeys.swift index 2472e96..882e012 100644 --- a/Sources/EnvironmentKeys.swift +++ b/Sources/EnvironmentKeys.swift @@ -2,8 +2,25 @@ // EnvironmentKeys.swift // CoreStore // -// Created by John Rommel Estropia on 2019/10/05. -// Copyright © 2019 John Rommel Estropia. All rights reserved. +// Copyright © 2018 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. // #if canImport(SwiftUI) @@ -13,7 +30,7 @@ import SwiftUI // MARK: - DataStackEnvironmentKey -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) public struct DataStackEnvironmentKey: EnvironmentKey { // MARK: Public @@ -27,7 +44,7 @@ public struct DataStackEnvironmentKey: EnvironmentKey { // MARK: - EnvironmentValues -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) extension EnvironmentValues { // MARK: Public diff --git a/Sources/Internals.DiffableDataSourceSnapshot.swift b/Sources/Internals.DiffableDataSourceSnapshot.swift index f5afcf9..deb0a74 100644 --- a/Sources/Internals.DiffableDataSourceSnapshot.swift +++ b/Sources/Internals.DiffableDataSourceSnapshot.swift @@ -48,18 +48,14 @@ extension Internals { // MARK: Internal - internal let nextStateTag: UUID - init() { self.structure = .init() - self.nextStateTag = .init() } - init(sections: [NSFetchedResultsSectionInfo], previousStateTag: UUID, nextStateTag: UUID) { + init(sections: [NSFetchedResultsSectionInfo]) { - self.structure = .init(sections: sections, previousStateTag: previousStateTag) - self.nextStateTag = nextStateTag + self.structure = .init(sections: sections) } var numberOfItems: Int { @@ -77,21 +73,11 @@ extension Internals { return self.structure.allSectionIDs } - var allSectionStateIDs: [SectionStateID] { - - return self.structure.allSectionStateIDs - } - var allItemIDs: [NSManagedObjectID] { return self.structure.allItemIDs } - var allItemStateIDs: [ItemStateID] { - - return self.structure.allItemStateIDs - } - func numberOfItems(inSection identifier: String) -> Int { return self.itemIDs(inSection: identifier).count @@ -102,21 +88,11 @@ extension Internals { return self.structure.items(in: identifier) } - func itemStateIDs(inSection identifier: String) -> [ItemStateID] { - - return self.structure.itemStateIDs(in: identifier) - } - func sectionIDs(containingItem identifier: NSManagedObjectID) -> String? { return self.structure.section(containing: identifier) } - func sectionStateIDs(containingItem identifier: NSManagedObjectID) -> SectionStateID? { - - return self.structure.sectionStateID(containing: identifier) - } - func indexOfItemID(_ identifier: NSManagedObjectID) -> Int? { return self.structure.allItemIDs.firstIndex(of: identifier) @@ -127,24 +103,19 @@ extension Internals { return self.structure.allSectionIDs.firstIndex(of: identifier) } - func itemIDs(where stateCondition: @escaping (UUID) -> Bool) -> [NSManagedObjectID] { + mutating func appendItems(_ identifiers: [NSManagedObjectID], toSection sectionIdentifier: String?) { - return self.structure.itemsIDs(where: stateCondition) + self.structure.append(itemIDs: identifiers, to: sectionIdentifier) } - mutating func appendItems(_ identifiers: [NSManagedObjectID], toSection sectionIdentifier: String?, nextStateTag: UUID) { + mutating func insertItems(_ identifiers: [NSManagedObjectID], beforeItem beforeIdentifier: NSManagedObjectID) { - self.structure.append(itemIDs: identifiers, to: sectionIdentifier, nextStateTag: nextStateTag) + self.structure.insert(itemIDs: identifiers, before: beforeIdentifier) } - mutating func insertItems(_ identifiers: [NSManagedObjectID], beforeItem beforeIdentifier: NSManagedObjectID, nextStateTag: UUID) { + mutating func insertItems(_ identifiers: [NSManagedObjectID], afterItem afterIdentifier: NSManagedObjectID) { - self.structure.insert(itemIDs: identifiers, before: beforeIdentifier, nextStateTag: nextStateTag) - } - - mutating func insertItems(_ identifiers: [NSManagedObjectID], afterItem afterIdentifier: NSManagedObjectID, nextStateTag: UUID) { - - self.structure.insert(itemIDs: identifiers, after: afterIdentifier, nextStateTag: nextStateTag) + self.structure.insert(itemIDs: identifiers, after: afterIdentifier) } mutating func deleteItems(_ identifiers: [NSManagedObjectID]) { @@ -172,19 +143,19 @@ extension Internals { self.structure.update(itemIDs: identifiers, nextStateTag: nextStateTag) } - mutating func appendSections(_ identifiers: [String], nextStateTag: UUID) { + mutating func appendSections(_ identifiers: [String]) { - self.structure.append(sectionIDs: identifiers, nextStateTag: nextStateTag) + self.structure.append(sectionIDs: identifiers) } - mutating func insertSections(_ identifiers: [String], beforeSection toIdentifier: String, nextStateTag: UUID) { + mutating func insertSections(_ identifiers: [String], beforeSection toIdentifier: String) { - self.structure.insert(sectionIDs: identifiers, before: toIdentifier, nextStateTag: nextStateTag) + self.structure.insert(sectionIDs: identifiers, before: toIdentifier) } - mutating func insertSections(_ identifiers: [String], afterSection toIdentifier: String, nextStateTag: UUID) { + mutating func insertSections(_ identifiers: [String], afterSection toIdentifier: String) { - self.structure.insert(sectionIDs: identifiers, after: toIdentifier, nextStateTag: nextStateTag) + self.structure.insert(sectionIDs: identifiers, after: toIdentifier) } mutating func deleteSections(_ identifiers: [String]) { @@ -271,7 +242,7 @@ extension Internals { self.sections = [] } - init(sections: [NSFetchedResultsSectionInfo], previousStateTag: UUID) { + init(sections: [NSFetchedResultsSectionInfo]) { self.sections = sections.map { @@ -279,8 +250,7 @@ extension Internals { id: $0.name, items: $0.objects? .compactMap({ ($0 as? NSManagedObject)?.objectID }) - .map({ Item(id: $0, stateTag: previousStateTag) }) ?? [], - stateTag: previousStateTag + .map({ Item(id: $0) }) ?? [] ) } } @@ -290,21 +260,11 @@ extension Internals { return self.sections.map({ $0.id }) } - var allSectionStateIDs: [SectionStateID] { - - return self.sections.map({ $0.stateID }) - } - var allItemIDs: [NSManagedObjectID] { return self.sections.lazy.flatMap({ $0.elements }).map({ $0.id }) } - var allItemStateIDs: [ItemStateID] { - - return self.sections.lazy.flatMap({ $0.elements }).map({ $0.stateID }) - } - func items(in sectionID: String) -> [NSManagedObjectID] { guard let sectionIndex = self.sectionIndex(of: sectionID) else { @@ -314,33 +274,12 @@ extension Internals { return self.sections[sectionIndex].elements.map({ $0.id }) } - func itemsIDs(where stateCondition: @escaping (UUID) -> Bool) -> [NSManagedObjectID] { - - return self.sections.lazy - .flatMap({ $0.elements.filter({ stateCondition($0.stateTag) }) }) - .map({ $0.id }) - } - - func itemStateIDs(in sectionID: String) -> [ItemStateID] { - - guard let sectionIndex = self.sectionIndex(of: sectionID) else { - - Internals.abort("Section \"\(sectionID)\" does not exist") - } - return self.sections[sectionIndex].elements.map({ $0.stateID }) - } - func section(containing itemID: NSManagedObjectID) -> String? { return self.itemPositionMap()[itemID]?.section.id } - func sectionStateID(containing itemID: NSManagedObjectID) -> SectionStateID? { - - return self.itemPositionMap()[itemID]?.section.stateID - } - - mutating func append(itemIDs: [NSManagedObjectID], to sectionID: String?, nextStateTag: UUID) { + mutating func append(itemIDs: [NSManagedObjectID], to sectionID: String?) { let index: Array
.Index if let sectionID = sectionID { @@ -360,22 +299,22 @@ extension Internals { } index = section.index(before: section.endIndex) } - let items = itemIDs.lazy.map({ Item(id: $0, stateTag: nextStateTag) }) + let items = itemIDs.lazy.map({ Item(id: $0) }) self.sections[index].elements.append(contentsOf: items) } - mutating func insert(itemIDs: [NSManagedObjectID], before beforeItemID: NSManagedObjectID, nextStateTag: UUID) { + mutating func insert(itemIDs: [NSManagedObjectID], before beforeItemID: NSManagedObjectID) { guard let itemPosition = self.itemPositionMap()[beforeItemID] else { Internals.abort("Item \(beforeItemID) does not exist") } - let items = itemIDs.lazy.map({ Item(id: $0, stateTag: nextStateTag) }) + let items = itemIDs.lazy.map({ Item(id: $0) }) self.sections[itemPosition.sectionIndex].elements .insert(contentsOf: items, at: itemPosition.itemRelativeIndex) } - mutating func insert(itemIDs: [NSManagedObjectID], after afterItemID: NSManagedObjectID, nextStateTag: UUID) { + mutating func insert(itemIDs: [NSManagedObjectID], after afterItemID: NSManagedObjectID) { guard let itemPosition = self.itemPositionMap()[afterItemID] else { @@ -383,7 +322,7 @@ extension Internals { } let itemIndex = self.sections[itemPosition.sectionIndex].elements .index(after: itemPosition.itemRelativeIndex) - let items = itemIDs.lazy.map({ Item(id: $0, stateTag: nextStateTag) }) + let items = itemIDs.lazy.map({ Item(id: $0) }) self.sections[itemPosition.sectionIndex].elements .insert(contentsOf: items, at: itemIndex) } @@ -459,34 +398,34 @@ extension Internals { continue } self.sections[itemPosition.sectionIndex] - .elements[itemPosition.itemRelativeIndex].stateTag = nextStateTag + .elements[itemPosition.itemRelativeIndex].isReloaded = true } } - mutating func append(sectionIDs: [String], nextStateTag: UUID) { + mutating func append(sectionIDs: [String]) { - let newSections = sectionIDs.lazy.map({ Section(id: $0, stateTag: nextStateTag) }) + let newSections = sectionIDs.lazy.map({ Section(id: $0) }) self.sections.append(contentsOf: newSections) } - mutating func insert(sectionIDs: [String], before beforeSectionID: String, nextStateTag: UUID) { + mutating func insert(sectionIDs: [String], before beforeSectionID: String) { guard let sectionIndex = self.sectionIndex(of: beforeSectionID) else { Internals.abort("Section \"\(beforeSectionID)\" does not exist") } - let newSections = sectionIDs.lazy.map({ Section(id: $0, stateTag: nextStateTag) }) + let newSections = sectionIDs.lazy.map({ Section(id: $0) }) self.sections.insert(contentsOf: newSections, at: sectionIndex) } - mutating func insert(sectionIDs: [String], after afterSectionID: String, nextStateTag: UUID) { + mutating func insert(sectionIDs: [String], after afterSectionID: String) { guard let beforeIndex = self.sectionIndex(of: afterSectionID) else { Internals.abort("Section \"\(afterSectionID)\" does not exist") } let sectionIndex = self.sections.index(after: beforeIndex) - let newSections = sectionIDs.lazy.map({ Section(id: $0, stateTag: nextStateTag) }) + let newSections = sectionIDs.lazy.map({ Section(id: $0) }) self.sections.insert(contentsOf: newSections, at: sectionIndex) } @@ -533,7 +472,7 @@ extension Internals { continue } - self.sections[sectionIndex].stateTag = nextStateTag + self.sections[sectionIndex].isReloaded = true } } @@ -589,22 +528,17 @@ extension Internals { fileprivate struct Item: Identifiable, Equatable { - var stateTag: UUID + var isReloaded: Bool - init(id: NSManagedObjectID, stateTag: UUID) { + init(id: NSManagedObjectID, isReloaded: Bool = false) { self.id = id - self.stateTag = stateTag - } - - var stateID: ItemStateID { - - return .init(id: self.id, stateTag: self.stateTag) + self.isReloaded = isReloaded } func isContentEqual(to source: Item) -> Bool { - return self.id == source.id && self.stateTag == source.stateTag + return !self.isReloaded && self.id == source.id } // MARK: Identifiable @@ -618,27 +552,22 @@ extension Internals { fileprivate struct Section: Identifiable, Equatable { var elements: [Item] = [] - var stateTag: UUID + var isReloaded: Bool - init(id: String, items: [Item] = [], stateTag: UUID) { + init(id: String, items: [Item] = [], isReloaded: Bool = false) { self.id = id self.elements = items - self.stateTag = stateTag + self.isReloaded = isReloaded } init(source: Section, elements: S) where S.Element == Item { - self.init(id: source.id, items: Array(elements), stateTag: source.stateTag) - } - - var stateID: SectionStateID { - - return .init(id: self.id, stateTag: self.stateTag) + self.init(id: source.id, items: Array(elements), isReloaded: source.isReloaded) } func isContentEqual(to source: Section) -> Bool { - return self.id == source.id && self.stateTag == source.stateTag + return !self.isReloaded && self.id == source.id } // MARK: Identifiable diff --git a/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift b/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift index a9185f8..a49e902 100644 --- a/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift +++ b/Sources/Internals.FetchedDiffableDataSourceSnapshotDelegate.swift @@ -77,7 +77,7 @@ extension Internals { // #if canImport(UIKit) || canImport(AppKit) // -// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) { +// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) { // // return // } @@ -96,7 +96,7 @@ extension Internals { // #if canImport(UIKit) || canImport(AppKit) // -// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) // @objc // dynamic func controller(_ controller: NSFetchedResultsController, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) { // @@ -111,48 +111,12 @@ extension Internals { @objc dynamic func controllerDidChangeContent(_ controller: NSFetchedResultsController) { - let nextStateTag: UUID = .init() - var dataSourceSnapshot = Internals.DiffableDataSourceSnapshot( - sections: controller.sections ?? [], - previousStateTag: self.previousStateTag, - nextStateTag: nextStateTag - ) - dataSourceSnapshot.reloadItems(self.reloadedItemIDs, nextStateTag: nextStateTag) - dataSourceSnapshot.reloadSections(self.reloadedSectionIDs, nextStateTag: nextStateTag) - self.handler?.controller( controller, - didChangContentWith: dataSourceSnapshot + didChangContentWith: Internals.DiffableDataSourceSnapshot( + sections: controller.sections ?? [] + ) ) - self.previousStateTag = nextStateTag } - - @objc - dynamic func controller(_ controller: NSFetchedResultsController, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { - - let managedObject = anObject as! NSManagedObject - self.reloadedItemIDs.insert(managedObject.objectID) - } - - @objc - dynamic func controller(_ controller: NSFetchedResultsController, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) { - - self.reloadedSectionIDs.insert(sectionInfo.name) - } - - - // MARK: Private - - private var previousStateTag: UUID = .init() { - - didSet { - - self.reloadedItemIDs = [] - self.reloadedSectionIDs = [] - } - } - - private var reloadedItemIDs: Set = [] - private var reloadedSectionIDs: Set = [] } } diff --git a/Sources/ListSnapshot.swift b/Sources/ListSnapshot.swift index 5509a4b..51b985d 100644 --- a/Sources/ListSnapshot.swift +++ b/Sources/ListSnapshot.swift @@ -128,17 +128,17 @@ public struct ListSnapshot: SnapshotResult, RandomAccessCollec public mutating func appendItems(_ identifiers: [ItemID], toSection sectionIdentifier: SectionID? = nil) { - self.diffableSnapshot.appendItems(identifiers, toSection: sectionIdentifier, nextStateTag: .init()) + self.diffableSnapshot.appendItems(identifiers, toSection: sectionIdentifier) } public mutating func insertItems(_ identifiers: [ItemID], beforeItem beforeIdentifier: ItemID) { - self.diffableSnapshot.insertItems(identifiers, beforeItem: beforeIdentifier, nextStateTag: .init()) + self.diffableSnapshot.insertItems(identifiers, beforeItem: beforeIdentifier) } public mutating func insertItems(_ identifiers: [ItemID], afterItem afterIdentifier: ItemID) { - self.diffableSnapshot.insertItems(identifiers, afterItem: afterIdentifier, nextStateTag: .init()) + self.diffableSnapshot.insertItems(identifiers, afterItem: afterIdentifier) } public mutating func deleteItems(_ identifiers: [ItemID]) { @@ -168,17 +168,17 @@ public struct ListSnapshot: SnapshotResult, RandomAccessCollec public mutating func appendSections(_ identifiers: [SectionID]) { - self.diffableSnapshot.appendSections(identifiers, nextStateTag: .init()) + self.diffableSnapshot.appendSections(identifiers) } public mutating func insertSections(_ identifiers: [SectionID], beforeSection toIdentifier: SectionID) { - self.diffableSnapshot.insertSections(identifiers, beforeSection: toIdentifier, nextStateTag: .init()) + self.diffableSnapshot.insertSections(identifiers, beforeSection: toIdentifier) } public mutating func insertSections(_ identifiers: [SectionID], afterSection toIdentifier: SectionID) { - self.diffableSnapshot.insertSections(identifiers, afterSection: toIdentifier, nextStateTag: .init()) + self.diffableSnapshot.insertSections(identifiers, afterSection: toIdentifier) } public mutating func deleteSections(_ identifiers: [SectionID]) { @@ -263,16 +263,6 @@ public struct ListSnapshot: SnapshotResult, RandomAccessCollec self.diffableSnapshot = diffableSnapshot self.context = context } - - internal var nextStateTag: UUID { - - return self.diffableSnapshot.nextStateTag - } - - internal func itemIDs(where stateCondition: @escaping (UUID) -> Bool) -> [ItemID] { - - return self.diffableSnapshot.itemIDs(where: stateCondition) - } // MARK: Private diff --git a/Sources/LiveList.swift b/Sources/LiveList.swift index 1029a64..da455aa 100644 --- a/Sources/LiveList.swift +++ b/Sources/LiveList.swift @@ -49,10 +49,7 @@ public final class LiveList: Hashable { willSet { - if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) { - - self.willChange() - } + self.willChange() } } @@ -267,7 +264,7 @@ public final class LiveList: Hashable { applyFetchClauses: applyFetchClauses ) - if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) { + if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) { #if canImport(Combine) self.rawObjectWillChange = ObservableObjectPublisher() @@ -318,20 +315,33 @@ extension LiveList: FetchedDiffableDataSourceSnapshotHandler { #if canImport(Combine) import Combine +@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) +extension LiveList: ObservableObject {} + +#endif + // MARK: - LiveList: LiveResult -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) extension LiveList: LiveResult { // MARK: ObservableObject + #if canImport(Combine) + + @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) public var objectWillChange: ObservableObjectPublisher { return self.rawObjectWillChange! as! ObservableObjectPublisher } + #endif + public func willChange() { + guard #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) else { + + return + } #if canImport(Combine) #if canImport(SwiftUI) @@ -340,11 +350,10 @@ extension LiveList: LiveResult { self.objectWillChange.send() } - #else - self.objectWillChange.send() - #endif + self.objectWillChange.send() + #endif } @@ -353,5 +362,3 @@ extension LiveList: LiveResult { // TODO: } } - -#endif diff --git a/Sources/LiveObject.swift b/Sources/LiveObject.swift index f11be0d..2e6c937 100644 --- a/Sources/LiveObject.swift +++ b/Sources/LiveObject.swift @@ -100,7 +100,7 @@ public final class LiveObject: Identifiable, Hashable { self.id = id self.context = context - if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) { + if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) { #if canImport(Combine) self.rawObjectWillChange = ObservableObjectPublisher() @@ -132,10 +132,7 @@ public final class LiveObject: Identifiable, Hashable { return } self.$lazySnapshot.reset({ initializer(id, context) }) - if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) { - - self.willChange() - } + self.willChange() } ) @@ -156,20 +153,33 @@ public final class LiveObject: Identifiable, Hashable { #if canImport(Combine) import Combine +@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) +extension LiveObject: ObservableObject {} + +#endif + // MARK: - LiveObject: LiveResult -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) extension LiveObject: LiveResult { // MARK: ObservableObject + #if canImport(Combine) + + @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) public var objectWillChange: ObservableObjectPublisher { return self.rawObjectWillChange! as! ObservableObjectPublisher } + + #endif public func willChange() { + guard #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) else { + + return + } #if canImport(Combine) #if canImport(SwiftUI) @@ -178,11 +188,10 @@ extension LiveObject: LiveResult { self.objectWillChange.send() } - #else - self.objectWillChange.send() - #endif + self.objectWillChange.send() + #endif } @@ -192,8 +201,6 @@ extension LiveObject: LiveResult { } } -#endif - // MARK: - LiveObject where O: NSManagedObject diff --git a/Sources/LiveQuery.swift b/Sources/LiveQuery.swift index c270229..aefa1ce 100644 --- a/Sources/LiveQuery.swift +++ b/Sources/LiveQuery.swift @@ -31,7 +31,7 @@ // // //#warning("TODO: autoupdating doesn't work yet") -//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) //@propertyWrapper //public struct LiveQuery: DynamicProperty { // @@ -143,7 +143,7 @@ // //#if canImport(UIKit) || canImport(AppKit) // -//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) +//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) //extension LiveQuery { // // public init(liveList: LiveList) where Result == LiveList { diff --git a/Sources/LiveResult.swift b/Sources/LiveResult.swift index e246116..e2c012f 100644 --- a/Sources/LiveResult.swift +++ b/Sources/LiveResult.swift @@ -36,8 +36,7 @@ import AppKit // MARK: - LiveResult -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) -public protocol LiveResult: ObservableObject { +public protocol LiveResult: AnyObject { associatedtype ObjectType associatedtype SnapshotType: SnapshotResult where SnapshotType.ObjectType == Self.ObjectType diff --git a/Sources/ObjectRepresentation.swift b/Sources/ObjectRepresentation.swift new file mode 100644 index 0000000..d68b8e2 --- /dev/null +++ b/Sources/ObjectRepresentation.swift @@ -0,0 +1,9 @@ +// +// ObjectRepresentation.swift +// CoreStore +// +// Created by John Estropia on 2019/10/11. +// Copyright © 2019 John Rommel Estropia. All rights reserved. +// + +import Foundation diff --git a/Sources/PropertyProtocol.swift b/Sources/PropertyProtocol.swift new file mode 100644 index 0000000..1c6292a --- /dev/null +++ b/Sources/PropertyProtocol.swift @@ -0,0 +1,35 @@ +// +// PropertyProtocol.swift +// CoreStore +// +// Copyright © 2018 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation +import CoreData + + +// MARK: - PropertyProtocol + +internal protocol PropertyProtocol: AnyObject { + + var keyPath: KeyPathString { get } +} diff --git a/Sources/Relationship.swift b/Sources/Relationship.swift index 6fe5419..4243db4 100644 --- a/Sources/Relationship.swift +++ b/Sources/Relationship.swift @@ -249,11 +249,15 @@ public enum RelationshipContainer { // MARK: RelationshipKeyPathStringConvertible public typealias ReturnValueType = DestinationValueType? + + + // MARK: PropertyProtocol + + internal let keyPath: KeyPathString // MARK: RelationshipProtocol - - internal let keyPath: KeyPathString + internal let isToMany = false internal let isOrdered = false internal let deleteRule: NSDeleteRule @@ -540,11 +544,15 @@ public enum RelationshipContainer { // MARK: RelationshipKeyPathStringConvertible public typealias ReturnValueType = [DestinationValueType] + + + // MARK: PropertyProtocol + + internal let keyPath: KeyPathString // MARK: RelationshipProtocol - - internal let keyPath: KeyPathString + internal let isToMany = true internal let isOptional = true internal let isOrdered = true @@ -837,11 +845,15 @@ public enum RelationshipContainer { // MARK: RelationshipKeyPathStringConvertible public typealias ReturnValueType = Set + + + // MARK: PropertyProtocol + + internal let keyPath: KeyPathString // MARK: RelationshipProtocol - internal let keyPath: KeyPathString internal let isToMany = true internal let isOptional = true internal let isOrdered = false diff --git a/Sources/RelationshipProtocol.swift b/Sources/RelationshipProtocol.swift index 31e4293..b2269a5 100644 --- a/Sources/RelationshipProtocol.swift +++ b/Sources/RelationshipProtocol.swift @@ -29,9 +29,8 @@ import CoreData // MARK: - RelationshipProtocol -internal protocol RelationshipProtocol: AnyObject { - - var keyPath: KeyPathString { get } +internal protocol RelationshipProtocol: PropertyProtocol { + var isToMany: Bool { get } var isOrdered: Bool { get } var deleteRule: NSDeleteRule { get } diff --git a/Sources/SnapshotResult.swift b/Sources/SnapshotResult.swift index e22bfb6..a58422c 100644 --- a/Sources/SnapshotResult.swift +++ b/Sources/SnapshotResult.swift @@ -36,7 +36,6 @@ import AppKit // MARK: - SnapshotResult -@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) public protocol SnapshotResult { associatedtype ObjectType: DynamicObject diff --git a/Sources/Transformable.swift b/Sources/Transformable.swift index 52ac645..f26ed6c 100644 --- a/Sources/Transformable.swift +++ b/Sources/Transformable.swift @@ -209,6 +209,11 @@ public enum TransformableContainer { public typealias ReturnValueType = DestinationValueType + // MARK: PropertyProtocol + + internal let keyPath: KeyPathString + + // MARK: AttributeProtocol internal static var attributeType: NSAttributeType { @@ -216,7 +221,6 @@ public enum TransformableContainer { return .transformableAttributeType } - internal let keyPath: KeyPathString internal let isOptional = false internal let isTransient: Bool internal let allowsExternalBinaryDataStorage: Bool @@ -427,6 +431,11 @@ public enum TransformableContainer { public typealias ReturnValueType = DestinationValueType? + // MARK: PropertyProtocol + + internal let keyPath: KeyPathString + + // MARK: AttributeProtocol internal static var attributeType: NSAttributeType { @@ -434,7 +443,6 @@ public enum TransformableContainer { return .transformableAttributeType } - internal let keyPath: KeyPathString internal let isOptional = true internal let isTransient: Bool internal let allowsExternalBinaryDataStorage: Bool diff --git a/Sources/Value.swift b/Sources/Value.swift index f4c2d28..fec2e9a 100644 --- a/Sources/Value.swift +++ b/Sources/Value.swift @@ -202,6 +202,11 @@ public enum ValueContainer { // MARK: AttributeKeyPathStringConvertible public typealias ReturnValueType = DestinationValueType + + + // MARK: PropertyProtocol + + internal let keyPath: KeyPathString // MARK: AttributeProtocol @@ -210,8 +215,7 @@ public enum ValueContainer { return V.cs_rawAttributeType } - - internal let keyPath: KeyPathString + internal let isOptional = false internal let isTransient: Bool internal let allowsExternalBinaryDataStorage = false @@ -420,6 +424,11 @@ public enum ValueContainer { // MARK: AttributeKeyPathStringConvertible public typealias ReturnValueType = DestinationValueType? + + + // MARK: PropertyProtocol + + internal let keyPath: KeyPathString // MARK: AttributeProtocol @@ -429,7 +438,6 @@ public enum ValueContainer { return V.cs_rawAttributeType } - internal let keyPath: KeyPathString internal let isOptional = true internal let isTransient: Bool internal let allowsExternalBinaryDataStorage = false