SwiftUI and Combine utilities appledocs. Bump up to 8.0 and iOS 11.0/macOS 10.13

This commit is contained in:
John Estropia
2021-03-01 09:14:41 +09:00
parent d13b0cfabb
commit 1f97225efa
12 changed files with 669 additions and 150 deletions

View File

@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "CoreStore"
s.version = "7.3.1"
s.swift_version = "5.3"
s.version = "8.0.0"
s.swift_version = "5.4"
s.license = "MIT"
s.homepage = "https://github.com/JohnEstropia/CoreStore"
s.documentation_url = "https://JohnEstropia.github.io/CoreStore"
@@ -9,10 +9,10 @@ Pod::Spec.new do |s|
s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" }
s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s }
s.ios.deployment_target = "10.0"
s.osx.deployment_target = "10.12"
s.watchos.deployment_target = "3.0"
s.tvos.deployment_target = "10.0"
s.ios.deployment_target = "11.0"
s.osx.deployment_target = "10.13"
s.watchos.deployment_target = "4.0"
s.tvos.deployment_target = "11.0"
s.source_files = "Sources", "Sources/**/*.{swift,h,m}"
s.public_header_files = "Sources/**/*.h"

View File

@@ -633,6 +633,14 @@
B58D0C641EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
B58D0C651EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
B58D0C661EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
B5944EF625E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EF525E269F9001D1D81 /* ObjectPublisher+Reactive.swift */; };
B5944EF725E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EF525E269F9001D1D81 /* ObjectPublisher+Reactive.swift */; };
B5944EF825E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EF525E269F9001D1D81 /* ObjectPublisher+Reactive.swift */; };
B5944EF925E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EF525E269F9001D1D81 /* ObjectPublisher+Reactive.swift */; };
B5944EFB25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EFA25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift */; };
B5944EFC25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EFA25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift */; };
B5944EFD25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EFA25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift */; };
B5944EFE25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5944EFA25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift */; };
B596BBB21DD5A014001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
B596BBB31DD5A014001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
B596BBB41DD5A016001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
@@ -677,6 +685,14 @@
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
B5B866DB25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DA25E9012F00335476 /* ListPublisher+Reactive.swift */; };
B5B866DC25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DA25E9012F00335476 /* ListPublisher+Reactive.swift */; };
B5B866DD25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DA25E9012F00335476 /* ListPublisher+Reactive.swift */; };
B5B866DE25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DA25E9012F00335476 /* ListPublisher+Reactive.swift */; };
B5B866E025E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DF25E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift */; };
B5B866E125E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DF25E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift */; };
B5B866E225E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DF25E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift */; };
B5B866E325E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B866DF25E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift */; };
B5BF7FAD234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5BF7FAC234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift */; };
B5BF7FAE234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5BF7FAC234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift */; };
B5BF7FAF234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5BF7FAC234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift */; };
@@ -725,14 +741,6 @@
B5C795C425DD651F00BDACC1 /* DataStack+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795C225DD651F00BDACC1 /* DataStack+Reactive.swift */; };
B5C795C525DD651F00BDACC1 /* DataStack+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795C225DD651F00BDACC1 /* DataStack+Reactive.swift */; };
B5C795C625DD651F00BDACC1 /* DataStack+Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795C225DD651F00BDACC1 /* DataStack+Reactive.swift */; };
B5C795C825DD692600BDACC1 /* PublisherConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795C725DD692600BDACC1 /* PublisherConvertible.swift */; };
B5C795C925DD692600BDACC1 /* PublisherConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795C725DD692600BDACC1 /* PublisherConvertible.swift */; };
B5C795CA25DD692600BDACC1 /* PublisherConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795C725DD692600BDACC1 /* PublisherConvertible.swift */; };
B5C795CB25DD692600BDACC1 /* PublisherConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795C725DD692600BDACC1 /* PublisherConvertible.swift */; };
B5C795CD25DD6C7600BDACC1 /* PublisherProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795CC25DD6C7600BDACC1 /* PublisherProvider.swift */; };
B5C795CE25DD6C7600BDACC1 /* PublisherProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795CC25DD6C7600BDACC1 /* PublisherProvider.swift */; };
B5C795CF25DD6C7600BDACC1 /* PublisherProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795CC25DD6C7600BDACC1 /* PublisherProvider.swift */; };
B5C795D025DD6C7600BDACC1 /* PublisherProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795CC25DD6C7600BDACC1 /* PublisherProvider.swift */; };
B5C795D225E0DD1B00BDACC1 /* ListSnapshot.SectionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795D125E0DD1B00BDACC1 /* ListSnapshot.SectionInfo.swift */; };
B5C795D325E0DD1B00BDACC1 /* ListSnapshot.SectionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795D125E0DD1B00BDACC1 /* ListSnapshot.SectionInfo.swift */; };
B5C795D425E0DD1B00BDACC1 /* ListSnapshot.SectionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C795D125E0DD1B00BDACC1 /* ListSnapshot.SectionInfo.swift */; };
@@ -1128,6 +1136,8 @@
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelationshipProtocol.swift; sourceTree = "<group>"; };
B5831B791F34ACBA00A9F647 /* Transformable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transformable.swift; sourceTree = "<group>"; };
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+DynamicModel.swift"; sourceTree = "<group>"; };
B5944EF525E269F9001D1D81 /* ObjectPublisher+Reactive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ObjectPublisher+Reactive.swift"; sourceTree = "<group>"; };
B5944EFA25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListPublisher.SnapshotPublisher.swift; sourceTree = "<group>"; };
B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvenienceTests.swift; sourceTree = "<group>"; };
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchableSource.swift; sourceTree = "<group>"; };
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryableSource.swift; sourceTree = "<group>"; };
@@ -1145,6 +1155,8 @@
B5AA37FC235C3D1A00FFD4B9 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS6.0.sdk/System/Library/Frameworks/SwiftUI.framework; sourceTree = DEVELOPER_DIR; };
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreBridge.swift; sourceTree = "<group>"; };
B5B866DA25E9012F00335476 /* ListPublisher+Reactive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ListPublisher+Reactive.swift"; sourceTree = "<group>"; };
B5B866DF25E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectPublisher.SnapshotPublisher.swift; sourceTree = "<group>"; };
B5BF7FAC234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Internals.DiffableDataSourceSnapshot.swift; sourceTree = "<group>"; };
B5BF7FB1234C97910070E741 /* DiffableDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiffableDataSource.swift; sourceTree = "<group>"; };
B5BF7FB6234C97CE0070E741 /* DiffableDataSource.TableViewAdapter-UIKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DiffableDataSource.TableViewAdapter-UIKit.swift"; sourceTree = "<group>"; };
@@ -1157,8 +1169,6 @@
B5C7959825D7D8B300BDACC1 /* ListReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListReader.swift; sourceTree = "<group>"; };
B5C795A025D7EB2200BDACC1 /* ForEach+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ForEach+SwiftUI.swift"; sourceTree = "<group>"; };
B5C795C225DD651F00BDACC1 /* DataStack+Reactive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataStack+Reactive.swift"; sourceTree = "<group>"; };
B5C795C725DD692600BDACC1 /* PublisherConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublisherConvertible.swift; sourceTree = "<group>"; };
B5C795CC25DD6C7600BDACC1 /* PublisherProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublisherProvider.swift; sourceTree = "<group>"; };
B5C795D125E0DD1B00BDACC1 /* ListSnapshot.SectionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListSnapshot.SectionInfo.swift; sourceTree = "<group>"; };
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = "<group>"; };
B5C976E61C6E3A5900B1AF90 /* Internals.CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Internals.CoreStoreFetchedResultsController.swift; sourceTree = "<group>"; };
@@ -1756,9 +1766,11 @@
B5C795BE25D933C200BDACC1 /* Reactive Programming */ = {
isa = PBXGroup;
children = (
B5C795C725DD692600BDACC1 /* PublisherConvertible.swift */,
B5C795CC25DD6C7600BDACC1 /* PublisherProvider.swift */,
B5C795C225DD651F00BDACC1 /* DataStack+Reactive.swift */,
B5B866DA25E9012F00335476 /* ListPublisher+Reactive.swift */,
B5944EF525E269F9001D1D81 /* ObjectPublisher+Reactive.swift */,
B5944EFA25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift */,
B5B866DF25E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift */,
);
name = "Reactive Programming";
sourceTree = "<group>";
@@ -1953,6 +1965,7 @@
B50564CC2350699700482308 /* Protocols */,
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
B5DE522A230BD7CC00A22534 /* Internals.swift */,
B50C3F0223D1B01C00B29880 /* Internals.AnyFieldCoder.swift */,
B5C976E61C6E3A5900B1AF90 /* Internals.CoreStoreFetchedResultsController.swift */,
B5474D142227C08700B21FEC /* Internals.CoreStoreFetchRequest.swift */,
@@ -1969,7 +1982,6 @@
B5E84F2B1AFF849C0064E85B /* Internals.NotificationObserver.swift */,
B5277676234F265F0056BE9F /* Internals.SharedNotificationObserver.swift */,
B50E17602351FA66004F033C /* Internals.Closure.swift */,
B5DE522A230BD7CC00A22534 /* Internals.swift */,
B5E84F2D1AFF849C0064E85B /* Internals.WeakObject.swift */,
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
@@ -2328,7 +2340,6 @@
B55BB4D4235012AE00C33E34 /* ObjectRepresentation.swift in Sources */,
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B5C795CD25DD6C7600BDACC1 /* PublisherProvider.swift in Sources */,
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */,
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
@@ -2364,6 +2375,7 @@
B5E1B59D1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
B509C7F41E54511B0061C547 /* ImportableAttributeType.swift in Sources */,
B5B866E025E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */,
B5E84F0E1AFF847B0064E85B /* Tweak.swift in Sources */,
B5E1B5931CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
B5277677234F265F0056BE9F /* Internals.SharedNotificationObserver.swift in Sources */,
@@ -2382,6 +2394,7 @@
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */,
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
B5B866DB25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */,
B51260931E9B28F100402229 /* Internals.EntityIdentifier.swift in Sources */,
B56E4ECA23CD9B4800E1708C /* Field.swift in Sources */,
B5DAFB482203D9F8003FCCD0 /* Where.Expression.swift in Sources */,
@@ -2391,6 +2404,7 @@
B509D7BA23C846E300F42824 /* Value.Required.swift in Sources */,
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B5944EF625E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */,
B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */,
B53FBA181CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
@@ -2408,6 +2422,7 @@
B5A1DAC81F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
B5ECDC111CA816E500C7F112 /* CSTweak.swift in Sources */,
B509D7D323C84E1900F42824 /* Transformable.Required.swift in Sources */,
B5944EFB25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */,
B56923C41EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
B5E84F411AFF8CCD0064E85B /* TypeErasedClauses.swift in Sources */,
B5E84F0D1AFF847B0064E85B /* BaseDataTransaction+Querying.swift in Sources */,
@@ -2496,7 +2511,6 @@
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B56923EC1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */,
B5C795C825DD692600BDACC1 /* PublisherConvertible.swift in Sources */,
B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */,
B53FBA041CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
B57E6FAC23D30A5B000FD031 /* FieldRelationshipProtocol.swift in Sources */,
@@ -2579,7 +2593,6 @@
B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */,
B55BB4D5235012AE00C33E34 /* ObjectRepresentation.swift in Sources */,
B5ECDC071CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B5C795CE25DD6C7600BDACC1 /* PublisherProvider.swift in Sources */,
B5E1B59A1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
B5277678234F265F0056BE9F /* Internals.SharedNotificationObserver.swift in Sources */,
@@ -2614,6 +2627,7 @@
B55BB4DA23503B9600C33E34 /* EnvironmentValues+DataSources.swift in Sources */,
B5E1B5951CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
B509D7CA23C8491C00F42824 /* Relationship.ToManyOrdered.swift in Sources */,
B5B866E125E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */,
18166887232B9ED60097C275 /* String+KeyPaths.swift in Sources */,
B5ECDC2B1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
B56923F11EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
@@ -2632,6 +2646,7 @@
B5F8496D234898240029D57B /* ListSnapshot.swift in Sources */,
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B5DBE2D31C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B5B866DC25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */,
82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */,
B514EF1223A8DB1D0093DBA4 /* DiffableDataSource.BaseAdapter.swift in Sources */,
B53FBA1A1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
@@ -2641,6 +2656,7 @@
B53D9E5A23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */,
82BA18BC1C4BBD4A00A0916E /* OrderBy.swift in Sources */,
82BA18B01C4BBD3100A0916E /* NSManagedObject+Transaction.swift in Sources */,
B5944EF725E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */,
B50132312346B76E00FC238B /* Internals.FetchedDiffableDataSourceSnapshotDelegate.swift in Sources */,
82BA18D41C4BBD7100A0916E /* NSManagedObjectContext+Querying.swift in Sources */,
82BA18D51C4BBD7100A0916E /* NSManagedObjectContext+Setup.swift in Sources */,
@@ -2658,6 +2674,7 @@
B5DE5231230BDA1300A22534 /* CoreStoreDefaults.swift in Sources */,
B56E4ED523CDB54A00E1708C /* FieldProtocol.swift in Sources */,
B52F74461E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
B5944EFC25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */,
82BA18C61C4BBD5900A0916E /* DataStack+Migration.swift in Sources */,
B59851491C90289D00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
B596BBB71DD5BC67001DCDD9 /* FetchableSource.swift in Sources */,
@@ -2745,7 +2762,6 @@
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */,
B53FBA061CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
82BA18BE1C4BBD4A00A0916E /* Tweak.swift in Sources */,
B5C795C925DD692600BDACC1 /* PublisherConvertible.swift in Sources */,
B509D7C523C848DA00F42824 /* Relationship.ToOne.swift in Sources */,
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
B57E6FAD23D30A5B000FD031 /* FieldRelationshipProtocol.swift in Sources */,
@@ -2828,7 +2844,6 @@
B55514ED1EED8BF900BAB888 /* From+Querying.swift in Sources */,
B5BF7FC4234D7B2E0070E741 /* ObjectPublisher.swift in Sources */,
B596BBBE1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
B5C795D025DD6C7600BDACC1 /* PublisherProvider.swift in Sources */,
B546F9601C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
B55BB4D7235012AE00C33E34 /* ObjectRepresentation.swift in Sources */,
B5ECDC0F1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
@@ -2864,6 +2879,7 @@
B50EE14523473C97009B8C47 /* CoreStoreObject+DataSources.swift in Sources */,
B509D7CC23C8491C00F42824 /* Relationship.ToManyOrdered.swift in Sources */,
B55BB4D823503B9500C33E34 /* EnvironmentValues+DataSources.swift in Sources */,
B5B866E325E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */,
18166889232B9ED80097C275 /* String+KeyPaths.swift in Sources */,
B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */,
B56923F31EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
@@ -2882,6 +2898,7 @@
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5F8496F234898240029D57B /* ListSnapshot.swift in Sources */,
B5831F452212700500D8604C /* Where.Expression.swift in Sources */,
B5B866DE25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */,
B514EF1423A8DB1E0093DBA4 /* DiffableDataSource.BaseAdapter.swift in Sources */,
B51260961E9B28F100402229 /* Internals.EntityIdentifier.swift in Sources */,
B5ECDBE31CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
@@ -2891,6 +2908,7 @@
B52DD1C71BE1F94600949AFE /* NSManagedObjectContext+Querying.swift in Sources */,
B52DD1C81BE1F94600949AFE /* NSManagedObjectContext+Setup.swift in Sources */,
B53D9E5C23513712000F48FB /* DiffableDataSourceSnapshotProtocol.swift in Sources */,
B5944EF925E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */,
B52DD1C31BE1F94600949AFE /* Internals.NotificationObserver.swift in Sources */,
B52DD1A81BE1F93200949AFE /* DataStack+Querying.swift in Sources */,
B50132332346B76E00FC238B /* Internals.FetchedDiffableDataSourceSnapshotDelegate.swift in Sources */,
@@ -2908,6 +2926,7 @@
B5D8CA792346EAEF0055D7D1 /* DataStack+DataSources.swift in Sources */,
B56E4ED723CDB54A00E1708C /* FieldProtocol.swift in Sources */,
B56923C71EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
B5944EFE25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */,
B5DE5233230BDA1300A22534 /* CoreStoreDefaults.swift in Sources */,
B52DD1A51BE1F92F00949AFE /* ImportableUniqueObject.swift in Sources */,
B5E222271CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
@@ -2995,7 +3014,6 @@
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
B56923EF1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
B53FBA081CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
B5C795CB25DD692600BDACC1 /* PublisherConvertible.swift in Sources */,
B509D7C723C848DA00F42824 /* Relationship.ToOne.swift in Sources */,
B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
B57E6FAF23D30A5B000FD031 /* FieldRelationshipProtocol.swift in Sources */,
@@ -3079,7 +3097,6 @@
B5ECDC081CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B55BB4D6235012AE00C33E34 /* ObjectRepresentation.swift in Sources */,
B5E1B59B1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
B5C795CF25DD6C7600BDACC1 /* PublisherProvider.swift in Sources */,
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
B5277679234F265F0056BE9F /* Internals.SharedNotificationObserver.swift in Sources */,
@@ -3114,6 +3131,7 @@
B509D7CB23C8491C00F42824 /* Relationship.ToManyOrdered.swift in Sources */,
18166888232B9ED70097C275 /* String+KeyPaths.swift in Sources */,
B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */,
B5B866E225E9048000335476 /* ObjectPublisher.SnapshotPublisher.swift in Sources */,
B56923F21EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
B56321811BD65216006C9394 /* DataStack.swift in Sources */,
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
@@ -3132,6 +3150,7 @@
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B514EF1323A8DB1D0093DBA4 /* DiffableDataSource.BaseAdapter.swift in Sources */,
B5B866DD25E9012F00335476 /* ListPublisher+Reactive.swift in Sources */,
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */,
B53FBA1B1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5519A5B1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
@@ -3141,6 +3160,7 @@
B56321AB1BD6521C006C9394 /* Internals.FetchedResultsControllerDelegate.swift in Sources */,
B563219C1BD65216006C9394 /* SectionBy.swift in Sources */,
B50132322346B76E00FC238B /* Internals.FetchedDiffableDataSourceSnapshotDelegate.swift in Sources */,
B5944EF825E269F9001D1D81 /* ObjectPublisher+Reactive.swift in Sources */,
B56321B21BD6521C006C9394 /* NSManagedObjectContext+Querying.swift in Sources */,
B5FE4DA41C8481E100FA6A91 /* StorageInterface.swift in Sources */,
B56321B31BD6521C006C9394 /* NSManagedObjectContext+Setup.swift in Sources */,
@@ -3158,6 +3178,7 @@
B56E4ED623CDB54A00E1708C /* FieldProtocol.swift in Sources */,
B5DE5232230BDA1300A22534 /* CoreStoreDefaults.swift in Sources */,
B598514A1C90289E00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
B5944EFD25E8E8DA001D1D81 /* ListPublisher.SnapshotPublisher.swift in Sources */,
B52F74471E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
B5FEC1901C9166E700532541 /* NSPersistentStore+Setup.swift in Sources */,
B56321A11BD65216006C9394 /* ListMonitor.swift in Sources */,
@@ -3246,7 +3267,6 @@
B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */,
B53FBA071CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
B56321841BD65216006C9394 /* DefaultLogger.swift in Sources */,
B5C795CA25DD692600BDACC1 /* PublisherConvertible.swift in Sources */,
B509D7C623C848DA00F42824 /* Relationship.ToOne.swift in Sources */,
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
B57E6FAE23D30A5B000FD031 /* FieldRelationshipProtocol.swift in Sources */,
@@ -3339,8 +3359,8 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = Sources/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "-D DEBUG";
@@ -3406,8 +3426,8 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = Sources/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore;
PRODUCT_NAME = CoreStore;
@@ -3528,6 +3548,7 @@
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 11.0;
};
name = Debug;
};
@@ -3554,6 +3575,7 @@
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 11.0;
};
name = Release;
};
@@ -3714,6 +3736,7 @@
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Debug;
};
@@ -3742,6 +3765,7 @@
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Release;
};

View File

@@ -29,7 +29,7 @@ import PackageDescription
let package = Package(
name: "CoreStore",
platforms: [
.macOS(.v10_12), .iOS(.v10), .tvOS(.v10), .watchOS(.v3)
.macOS(.v10_13), .iOS(.v11), .tvOS(.v11), .watchOS(.v4)
],
products: [
.library(name: "CoreStore", type: .static, targets: ["CoreStore"])

View File

@@ -19,10 +19,10 @@ Unleashing the real power of Core Data with the elegance and safety of Swift
<br />
</p>
* **Swift 5.3:** iOS 10+ / macOS 10.12+ / watchOS 3.0+ / tvOS 10.0+
* Previously supported Swift versions: [Swift 3.2](https://github.com/JohnEstropia/CoreStore/tree/4.2.3), [Swift 4.2](https://github.com/JohnEstropia/CoreStore/tree/6.2.1), [Swift 5.0](https://github.com/JohnEstropia/CoreStore/tree/6.3.2), [Swift 5.1](https://github.com/JohnEstropia/CoreStore/tree/7.0.4)
* **Swift 5.4:** iOS 11+ / macOS 10.13+ / watchOS 4.0+ / tvOS 11.0+
* Previously supported Swift versions: [Swift 3.2](https://github.com/JohnEstropia/CoreStore/tree/4.2.3), [Swift 4.2](https://github.com/JohnEstropia/CoreStore/tree/6.2.1), [Swift 5.0](https://github.com/JohnEstropia/CoreStore/tree/6.3.2), [Swift 5.1](https://github.com/JohnEstropia/CoreStore/tree/7.0.4), [Swift 5.3](https://github.com/JohnEstropia/CoreStore/tree/7.3.1)
Upgrading from CoreStore 6.x (swift 5.0) to 7.x (Swift 5.1)? Check out the [🆕 features](#features) and make sure to read the [Change logs](https://github.com/JohnEstropia/CoreStore/releases).
Upgrading from previous CoreStore versions? Check out the [🆕 features](#features) and make sure to read the [Change logs](https://github.com/JohnEstropia/CoreStore/releases).
CoreStore is now part of the [Swift Source Compatibility projects](https://swift.org/source-compatibility/#current-list-of-projects).
@@ -33,6 +33,7 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
### Features
- **SwiftUI and Combine API utilities.**
- **Backwards-portable DiffableDataSources implementation!** `UITableViews` and `UICollectionViews` now have a new ally: `ListPublisher`s provide diffable snapshots that make reloading animations very easy and very safe. Say goodbye to `UITableViews` and `UICollectionViews` reload errors!
- **💎Tight design around Swifts code elegance and type safety.** CoreStore fully utilizes Swift's community-driven language features.
- **🚦Safer concurrency architecture.** CoreStore makes it hard to fall into common concurrency mistakes. The main `NSManagedObjectContext` is strictly read-only, while all updates are done through serial *transactions*. *(See [Saving and processing transactions](#saving-and-processing-transactions))*

View File

@@ -31,10 +31,47 @@ import Combine
// MARK: - DataStack
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension DataStack: PublisherCompatible {}
extension DataStack {
// MARK: Public
/**
Combine utilities for the `DataStack` are exposed through this namespace
*/
public var reactive: DataStack.ReactiveNamespace {
return .init(self)
}
// MARK: - ReactiveNamespace
/**
Combine utilities for the `DataStack` are exposed through this namespace. Extend this type if you need to add other Combine Publisher utilities for `DataStack`.
*/
public struct ReactiveNamespace {
// MARK: Public
/**
The `DataStack` instance
*/
public let base: DataStack
// MARK: Internal
internal init(_ base: DataStack) {
self.base = base
}
}
}
// MARK: - DataStack.ReactiveNamespace
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension PublisherProvider where Base == DataStack {
extension DataStack.ReactiveNamespace {
// MARK: Public

View File

@@ -0,0 +1,109 @@
//
// ListPublisher+Reactive.swift
// CoreStore
//
// Copyright © 2021 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(Combine)
import Combine
// MARK: - ListPublisher
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ListPublisher {
// MARK: Public
/**
Combine utilities for the `ListPublisher` are exposed through this namespace
*/
public var reactive: ListPublisher.ReactiveNamespace {
return .init(self)
}
// MARK: - ReactiveNamespace
/**
Combine utilities for the `ListPublisher` are exposed through this namespace. Extend this type if you need to add other Combine Publisher utilities for `ListPublisher`.
*/
public struct ReactiveNamespace {
// MARK: Public
/**
The `ListPublisher` instance
*/
public let base: ListPublisher
// MARK: Internal
internal init(_ base: ListPublisher) {
self.base = base
}
}
}
// MARK: - ListPublisher.ReactiveNamespace
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ListPublisher.ReactiveNamespace {
// MARK: Public
/**
Returns a `Publisher` that emits a `ListSnapshot` whenever changes occur in the `ListPublisher`
```
listPublisher.reactive
.snapshot(emitInitialValue: true)
.sink(
receiveCompletion: { result in
// ...
},
receiveValue: { (listSnapshot) in
dataSource.apply(
listSnapshot,
animatingDifferences: true
)
}
)
.store(in: &cancellables)
```
- parameter emitInitialValue: If `true`, the current value is immediately emitted to the first subscriber. If `false`, the event fires only starting the next `ListSnapshot` update.
- returns: A `Publisher` that emits a `ListSnapshot` whenever changes occur in the `ListPublisher`.
*/
public func snapshot(emitInitialValue: Bool = true) -> ListPublisher.SnapshotPublisher {
return .init(
listPublisher: self.base,
emitInitialValue: emitInitialValue
)
}
}
#endif

View File

@@ -0,0 +1,150 @@
//
// ListPublisher.SnapshotPublisher.swift
// CoreStore
//
// Copyright © 2021 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(Combine)
import Combine
import CoreData
// MARK: - ListPublisher
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ListPublisher {
// MARK: - SnapshotPublisher
/**
A `Publisher` that emits a `ListSnapshot` whenever changes occur in the `ListPublisher`.
*/
public struct SnapshotPublisher: Publisher {
// MARK: Internal
internal let listPublisher: ListPublisher<O>
internal let emitInitialValue: Bool
// MARK: Publisher
public typealias Output = ListSnapshot<O>
public typealias Failure = Never
public func receive<S: Subscriber>(subscriber: S) where S.Input == Output, S.Failure == Failure {
subscriber.receive(
subscription: ListSnapshotSubscription(
publisher: self.listPublisher,
emitInitialValue: self.emitInitialValue,
subscriber: subscriber
)
)
}
// MARK: - ListSnapshotSubscriber
fileprivate final class ListSnapshotSubscriber: Subscriber {
// MARK: Subscriber
typealias Failure = Never
func receive(subscription: Subscription) {
subscription.request(.unlimited)
}
func receive(_ input: Output) -> Subscribers.Demand {
return .unlimited
}
func receive(completion: Subscribers.Completion<Failure>) {}
}
// MARK: - ListSnapshotSubscription
fileprivate final class ListSnapshotSubscription<S: Subscriber>: Subscription where S.Input == Output, S.Failure == Never {
// MARK: FilePrivate
init(
publisher: ListPublisher<O>,
emitInitialValue: Bool,
subscriber: S
) {
self.publisher = publisher
self.emitInitialValue = emitInitialValue
self.subscriber = subscriber
}
// MARK: Subscription
func request(_ demand: Subscribers.Demand) {
guard demand > 0 else {
return
}
self.publisher.addObserver(
self,
notifyInitial: self.emitInitialValue,
{ [weak self] (publisher) in
guard
let self = self,
let subscriber = self.subscriber
else {
return
}
_ = subscriber.receive(publisher.snapshot)
}
)
}
// MARK: Cancellable
func cancel() {
self.publisher.removeObserver(self)
self.subscriber = nil
}
// MARK: Private
private let publisher: ListPublisher<O>
private let emitInitialValue: Bool
private var subscriber: S?
}
}
}
#endif

View File

@@ -0,0 +1,161 @@
//
// ObjectPublisher+Reactive.swift
// CoreStore
//
// Copyright © 2021 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(Combine)
import Combine
// MARK: - ObjectPublisher
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ObjectPublisher {
// MARK: Public
/**
Combine utilities for the `ObjectPublisher` are exposed through this namespace
*/
public var reactive: ObjectPublisher.ReactiveNamespace {
return .init(self)
}
// MARK: - ReactiveNamespace
/**
Combine utilities for the `ObjectPublisher` are exposed through this namespace. Extend this type if you need to add other Combine Publisher utilities for `ObjectPublisher`.
*/
@dynamicMemberLookup
public struct ReactiveNamespace {
// MARK: Public
/**
The `ObjectPublisher` instance
*/
public let base: ObjectPublisher
// MARK: Internal
internal init(_ base: ObjectPublisher) {
self.base = base
}
}
}
// MARK: - ObjectPublisher.ReactiveNamespace
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ObjectPublisher.ReactiveNamespace {
// MARK: Public
/**
Returns a `Publisher` that emits an `ObjectSnapshot?` whenever changes occur in the `ObjectPublisher`. The event emits `nil` if the object has been deletd.
```
objectPublisher.reactive
.snapshot(emitInitialValue: true)
.sink(
receiveCompletion: { result in
// ...
},
receiveValue: { (objectSnapshot) in
tableViewCell.setObject(objectSnapshot)
}
)
.store(in: &tableViewCell.cancellables)
```
- parameter emitInitialValue: If `true`, the current value is immediately emitted to the first subscriber. If `false`, the event fires only starting the next `ObjectSnapshot` update.
- returns: A `Publisher` that emits an `ObjectSnapshot?` whenever changes occur in the `ObjectPublisher`. The event emits `nil` if the object has been deletd.
*/
public func snapshot(emitInitialValue: Bool = true) -> ObjectPublisher.SnapshotPublisher {
return .init(
objectPublisher: self.base,
emitInitialValue: emitInitialValue
)
}
}
// MARK: - ObjectPublisher.ReactiveNamespace where O: NSManagedObject
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ObjectPublisher.ReactiveNamespace where O: NSManagedObject {
/**
Returns the value for the property identified by a given key.
*/
public subscript<V: AllowedObjectiveCKeyPathValue>(dynamicMember member: KeyPath<O, V>) -> some Publisher {
return self
.snapshot(emitInitialValue: true)
.map({ $0?[dynamicMember: member] })
}
}
// MARK: - ObjectPublisher.ReactiveNamespace where O: CoreStoreObject
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ObjectPublisher.ReactiveNamespace where O: CoreStoreObject {
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, FieldContainer<OBase>.Stored<V>>) -> some Publisher {
return self
.snapshot(emitInitialValue: true)
.map({ $0?[dynamicMember: member] })
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, FieldContainer<OBase>.Virtual<V>>) -> some Publisher {
return self
.snapshot(emitInitialValue: true)
.map({ $0?[dynamicMember: member] })
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, FieldContainer<OBase>.Coded<V>>) -> some Publisher {
return self
.snapshot(emitInitialValue: true)
.map({ $0?[dynamicMember: member] })
}
}
#endif

View File

@@ -0,0 +1,150 @@
//
// ObjectPublisher.SnapshotPublisher.swift
// CoreStore
//
// Copyright © 2021 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(Combine)
import Combine
import CoreData
// MARK: - ObjectPublisher
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension ObjectPublisher {
// MARK: - SnapshotPublisher
/**
A `Publisher` that emits an `ObjectSnapshot?` whenever changes occur in the `ObjectPublisher`. The event emits `nil` if the object has been deletd.
*/
public struct SnapshotPublisher: Publisher {
// MARK: Internal
internal let objectPublisher: ObjectPublisher<O>
internal let emitInitialValue: Bool
// MARK: Publisher
public typealias Output = ObjectSnapshot<O>?
public typealias Failure = Never
public func receive<S: Subscriber>(subscriber: S) where S.Input == Output, S.Failure == Failure {
subscriber.receive(
subscription: ObjectSnapshotSubscription(
publisher: self.objectPublisher,
emitInitialValue: self.emitInitialValue,
subscriber: subscriber
)
)
}
// MARK: - ObjectSnapshotSubscriber
fileprivate final class ObjectSnapshotSubscriber: Subscriber {
// MARK: Subscriber
typealias Failure = Never
func receive(subscription: Subscription) {
subscription.request(.unlimited)
}
func receive(_ input: Output) -> Subscribers.Demand {
return .unlimited
}
func receive(completion: Subscribers.Completion<Failure>) {}
}
// MARK: - ObjectSnapshotSubscription
fileprivate final class ObjectSnapshotSubscription<S: Subscriber>: Subscription where S.Input == Output, S.Failure == Never {
// MARK: FilePrivate
init(
publisher: ObjectPublisher<O>,
emitInitialValue: Bool,
subscriber: S
) {
self.publisher = publisher
self.emitInitialValue = emitInitialValue
self.subscriber = subscriber
}
// MARK: Subscription
func request(_ demand: Subscribers.Demand) {
guard demand > 0 else {
return
}
self.publisher.addObserver(
self,
notifyInitial: self.emitInitialValue,
{ [weak self] (publisher) in
guard
let self = self,
let subscriber = self.subscriber
else {
return
}
_ = subscriber.receive(publisher.snapshot)
}
)
}
// MARK: Cancellable
func cancel() {
self.publisher.removeObserver(self)
self.subscriber = nil
}
// MARK: Private
private let publisher: ObjectPublisher<O>
private let emitInitialValue: Bool
private var subscriber: S?
}
}
}
#endif

View File

@@ -174,21 +174,6 @@ extension ObjectSnapshot where O: NSManagedObject {
self.values[key] = newValue
}
}
// MARK: Deprecated
@available(*, deprecated, message: "Accessing the property directly now works")
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
return self[dynamicMember: keyPath]
}
@available(*, deprecated, message: "Mutating the property directly now works")
public mutating func setValue<V: AllowedObjectiveCKeyPathValue>(_ value: V!, forKeyPath keyPath: KeyPath<O, V>) {
self[dynamicMember: keyPath] = value
}
}

View File

@@ -1,52 +0,0 @@
//
// PublisherCompatible.swift
// CoreStore
//
// Copyright © 2021 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(Combine)
import Combine
// MARK: - PublisherCompatible
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
public protocol PublisherCompatible {
associatedtype ReactiveBase
var reactive: PublisherProvider<ReactiveBase> { get }
}
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension PublisherCompatible {
// MARK: Public
public var reactive: PublisherProvider<Self> {
return .init(self)
}
}
#endif

View File

@@ -1,46 +0,0 @@
//
// PublisherProvider.swift
// CoreStore
//
// Copyright © 2021 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(Combine)
import Combine
// MARK: - PublisherProvider
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
public struct PublisherProvider<Base> {
// MARK: Public
public let base: Base
public init(_ base: Base) {
self.base = base
}
}
#endif