mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-12 04:10:36 +01:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
367cfea8a7 | ||
|
|
5d3b7e3dab | ||
|
|
fe7e6e7b84 | ||
|
|
b2dba0d6fd | ||
|
|
6f290213fa | ||
|
|
0ab52d2f43 | ||
|
|
bf8a1062e0 | ||
|
|
0e254867b6 | ||
|
|
0376ac6908 | ||
|
|
b3421888a6 | ||
|
|
7b3f4ae0a4 | ||
|
|
b4e12cc922 | ||
|
|
6c282b18af | ||
|
|
ebbde8b7b6 | ||
|
|
a1407e4121 | ||
|
|
99b871b97a | ||
|
|
1cd3c4fcf4 | ||
|
|
e09ac9ee00 | ||
|
|
4b0d134acb | ||
|
|
eeec3979ee | ||
|
|
5b365c642d | ||
|
|
635201868a | ||
|
|
db4426e6b9 | ||
|
|
41902fee2e | ||
|
|
9239370793 | ||
|
|
a4d2f326a5 | ||
|
|
9f54ec26e2 | ||
|
|
9425cb56d7 | ||
|
|
1de56d2776 | ||
|
|
b3261ea930 | ||
|
|
88dd7aef72 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ CoreStore.xcworkspace/xcuserdata
|
||||
DerivedData
|
||||
*.orig
|
||||
build
|
||||
Playground_macOS.playground/playground.xcworkspace/xcuserdata
|
||||
|
||||
11
.travis.yml
11
.travis.yml
@@ -1,5 +1,5 @@
|
||||
language: objective-c
|
||||
osx_image: xcode10
|
||||
osx_image: xcode10.2
|
||||
sudo: false
|
||||
git:
|
||||
submodules: false
|
||||
@@ -22,15 +22,10 @@ env:
|
||||
- DESTINATION="OS=11.0,name=Apple TV 4K (at 1080p)" SCHEME="CoreStore tvOS" SDK=appletvsimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
before_install:
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.26.0/Carthage.pkg"
|
||||
- sudo installer -pkg "Carthage.pkg" -target /
|
||||
- rm "Carthage.pkg"
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document
|
||||
- npm install ios-sim -g
|
||||
- ios-sim start --devicetypeid "com.apple.CoreSimulator.SimDeviceType.iPhone-8, 11.0"
|
||||
before_script:
|
||||
- carthage update --use-submodules
|
||||
script:
|
||||
- set -o pipefail
|
||||
- xcodebuild -version
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "CoreStore"
|
||||
s.version = "6.0.0"
|
||||
s.swift_version = "4.2"
|
||||
s.version = "6.3.1"
|
||||
s.swift_version = "5.0"
|
||||
s.license = "MIT"
|
||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||
s.documentation_url = "https://JohnEstropia.github.io/CoreStore"
|
||||
|
||||
BIN
CoreStore.sketch
BIN
CoreStore.sketch
Binary file not shown.
@@ -27,7 +27,6 @@
|
||||
82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEC1AFF846E0064E85B /* DataStack+Transaction.swift */; };
|
||||
82BA18AF1C4BBD3100A0916E /* CoreStore+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEE1AFF846E0064E85B /* CoreStore+Transaction.swift */; };
|
||||
82BA18B01C4BBD3100A0916E /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
||||
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EF21AFF846E0064E85B /* SaveResult.swift */; };
|
||||
82BA18B21C4BBD3900A0916E /* ImportableObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */; };
|
||||
82BA18B31C4BBD3900A0916E /* ImportableUniqueObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */; };
|
||||
82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */; };
|
||||
@@ -165,14 +164,6 @@
|
||||
B52557881D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
|
||||
B52557891D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
|
||||
B525578A1D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
|
||||
B52661401CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
|
||||
B52661421CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
|
||||
B52661431CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
|
||||
B52661441CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
|
||||
B529C2041CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
|
||||
B529C2061CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
|
||||
B529C2071CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
|
||||
B529C2081CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
|
||||
B52DD17E1BE1F8CD00949AFE /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52DD1741BE1F8CC00949AFE /* CoreStore.framework */; };
|
||||
B52DD1931BE1F8FD00949AFE /* CoreStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F03A53519C5C6DA005002A5 /* CoreStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F291E2619C6D3CF007AF63F /* CoreStore.swift */; };
|
||||
@@ -189,7 +180,6 @@
|
||||
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EED1AFF846E0064E85B /* UnsafeDataTransaction.swift */; };
|
||||
B52DD1A11BE1F92C00949AFE /* DataStack+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEC1AFF846E0064E85B /* DataStack+Transaction.swift */; };
|
||||
B52DD1A21BE1F92C00949AFE /* CoreStore+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEE1AFF846E0064E85B /* CoreStore+Transaction.swift */; };
|
||||
B52DD1A31BE1F92C00949AFE /* SaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EF21AFF846E0064E85B /* SaveResult.swift */; };
|
||||
B52DD1A41BE1F92F00949AFE /* ImportableObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */; };
|
||||
B52DD1A51BE1F92F00949AFE /* ImportableUniqueObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */; };
|
||||
B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */; };
|
||||
@@ -297,6 +287,10 @@
|
||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
|
||||
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
|
||||
B546F9761C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
|
||||
B5474D152227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5474D162227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5474D172227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5474D182227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5489F3F1CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
|
||||
B5489F401CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
|
||||
B5489F411CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
|
||||
@@ -371,7 +365,6 @@
|
||||
B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EED1AFF846E0064E85B /* UnsafeDataTransaction.swift */; };
|
||||
B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEC1AFF846E0064E85B /* DataStack+Transaction.swift */; };
|
||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEE1AFF846E0064E85B /* CoreStore+Transaction.swift */; };
|
||||
B563218E1BD65216006C9394 /* SaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EF21AFF846E0064E85B /* SaveResult.swift */; };
|
||||
B563218F1BD65216006C9394 /* ImportableObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */; };
|
||||
B56321901BD65216006C9394 /* ImportableUniqueObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */; };
|
||||
B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */; };
|
||||
@@ -414,10 +407,6 @@
|
||||
B565079A1D3930D1000596DA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B56507991D3930D1000596DA /* Foundation.framework */; };
|
||||
B565079E1D3930ED000596DA /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B565079D1D3930ED000596DA /* CoreData.framework */; };
|
||||
B56507A01D3930F5000596DA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B565079F1D3930F5000596DA /* Foundation.framework */; };
|
||||
B5677D3D1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5677D3C1CD3B1E400322BFC /* ICloudStoreObserver.swift */; };
|
||||
B5677D3F1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5677D3C1CD3B1E400322BFC /* ICloudStoreObserver.swift */; };
|
||||
B5677D401CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5677D3C1CD3B1E400322BFC /* ICloudStoreObserver.swift */; };
|
||||
B5677D411CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5677D3C1CD3B1E400322BFC /* ICloudStoreObserver.swift */; };
|
||||
B56923C41EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */; };
|
||||
B56923C51EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */; };
|
||||
B56923C61EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */; };
|
||||
@@ -477,6 +466,12 @@
|
||||
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831F4022126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
|
||||
B5831F4122126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
|
||||
B5831F4222126FED00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
|
||||
B5831F432212700400D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
|
||||
B5831F442212700500D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
|
||||
B5831F452212700500D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
|
||||
B58B22F51C93C1BA00521925 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F03A53019C5C6DA005002A5 /* CoreStore.framework */; };
|
||||
B58D0C631EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
|
||||
B58D0C641EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
|
||||
@@ -496,11 +491,10 @@
|
||||
B59851491C90289D00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */; };
|
||||
B598514A1C90289E00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */; };
|
||||
B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */; };
|
||||
B59A51832256C85E00CEF3C5 /* VersionLockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59A51822256C85E00CEF3C5 /* VersionLockTests.swift */; };
|
||||
B59A51842256C85E00CEF3C5 /* VersionLockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59A51822256C85E00CEF3C5 /* VersionLockTests.swift */; };
|
||||
B59A51852256C85E00CEF3C5 /* VersionLockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59A51822256C85E00CEF3C5 /* VersionLockTests.swift */; };
|
||||
B59AFF411C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */; };
|
||||
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
|
||||
B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
|
||||
B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
|
||||
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
|
||||
B5A1DAC81F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
|
||||
B5A1DAC91F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
|
||||
B5A1DACA1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
|
||||
@@ -570,14 +564,12 @@
|
||||
B5D33A041E96012400C880DE /* Relationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D33A001E96012400C880DE /* Relationship.swift */; };
|
||||
B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; };
|
||||
B5D39A0219FD00C9000E91BB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5D39A0119FD00C9000E91BB /* Foundation.framework */; };
|
||||
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; };
|
||||
B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; };
|
||||
B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; };
|
||||
B5D3F6481C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; };
|
||||
B5D7A5B61CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
|
||||
B5D7A5B81CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
|
||||
B5D7A5B91CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
|
||||
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
|
||||
B5DAFB482203D9F8003FCCD0 /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
|
||||
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
|
||||
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
|
||||
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
|
||||
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
|
||||
@@ -634,7 +626,6 @@
|
||||
B5E84EF61AFF846E0064E85B /* DataStack+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEC1AFF846E0064E85B /* DataStack+Transaction.swift */; };
|
||||
B5E84EF71AFF846E0064E85B /* UnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EED1AFF846E0064E85B /* UnsafeDataTransaction.swift */; };
|
||||
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EEE1AFF846E0064E85B /* CoreStore+Transaction.swift */; };
|
||||
B5E84EFB1AFF846E0064E85B /* SaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EF21AFF846E0064E85B /* SaveResult.swift */; };
|
||||
B5E84EFC1AFF846E0064E85B /* SynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EF31AFF846E0064E85B /* SynchronousDataTransaction.swift */; };
|
||||
B5E84F0D1AFF847B0064E85B /* BaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */; };
|
||||
B5E84F0E1AFF847B0064E85B /* Tweak.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F001AFF847B0064E85B /* Tweak.swift */; };
|
||||
@@ -796,8 +787,6 @@
|
||||
B525577F1D029D2500E51965 /* TweakTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TweakTests.swift; sourceTree = "<group>"; };
|
||||
B52557831D02A07400E51965 /* SectionByTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionByTests.swift; sourceTree = "<group>"; };
|
||||
B52557871D02DE8100E51965 /* FetchTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchTests.swift; sourceTree = "<group>"; };
|
||||
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreFetchRequest+CoreStore.swift"; sourceTree = "<group>"; };
|
||||
B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSaveResult.swift; sourceTree = "<group>"; };
|
||||
B52DD1741BE1F8CC00949AFE /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B52DD17D1BE1F8CC00949AFE /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaHistory.swift; sourceTree = "<group>"; };
|
||||
@@ -820,6 +809,7 @@
|
||||
B546F95C1C9A12B800D5AC55 /* CSSQliteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSQliteStore.swift; sourceTree = "<group>"; };
|
||||
B546F9681C9AF26D00D5AC55 /* CSInMemoryStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInMemoryStore.swift; sourceTree = "<group>"; };
|
||||
B546F9721C9C553300D5AC55 /* SetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupResult.swift; sourceTree = "<group>"; };
|
||||
B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchRequest.swift; sourceTree = "<group>"; };
|
||||
B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity1.swift; sourceTree = "<group>"; };
|
||||
B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity2.swift; sourceTree = "<group>"; };
|
||||
B5489F451CF5F017008B4978 /* TransactionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionTests.swift; sourceTree = "<group>"; };
|
||||
@@ -850,7 +840,6 @@
|
||||
B56507991D3930D1000596DA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS3.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B565079D1D3930ED000596DA /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B565079F1D3930F5000596DA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B5677D3C1CD3B1E400322BFC /* ICloudStoreObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStoreObserver.swift; sourceTree = "<group>"; };
|
||||
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSEntityDescription+Migration.swift"; sourceTree = "<group>"; };
|
||||
B56923C81EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectModel+Migration.swift"; sourceTree = "<group>"; };
|
||||
B56923DC1EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomSchemaMappingProvider.swift; sourceTree = "<group>"; };
|
||||
@@ -860,7 +849,7 @@
|
||||
B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDynamicSchema.swift; sourceTree = "<group>"; };
|
||||
B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSXcodeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||
B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||
B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = "<group>"; };
|
||||
B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.swift; sourceTree = "<group>"; };
|
||||
B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestDataTestCase.swift; sourceTree = "<group>"; };
|
||||
B57D27C11D0BC20100539C58 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
|
||||
@@ -872,11 +861,13 @@
|
||||
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>"; };
|
||||
B59A51822256C85E00CEF3C5 /* VersionLockTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionLockTests.swift; sourceTree = "<group>"; };
|
||||
B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSPersistentStoreCoordinator+Setup.swift"; sourceTree = "<group>"; };
|
||||
B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStore.swift; sourceTree = "<group>"; };
|
||||
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyPath+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = "<group>"; };
|
||||
B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = "<group>"; };
|
||||
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_macOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_iOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionLock.swift; sourceTree = "<group>"; };
|
||||
B5A9921E1EA898710091A2E3 /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = "<group>"; };
|
||||
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
|
||||
@@ -899,9 +890,10 @@
|
||||
B5D33A001E96012400C880DE /* Relationship.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Relationship.swift; sourceTree = "<group>"; };
|
||||
B5D372831A39CD6900F583D9 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
|
||||
B5D39A0119FD00C9000E91BB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacySQLiteStore.swift; sourceTree = "<group>"; };
|
||||
B5D7A5B51CA3BF8F005C752B /* CSInto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInto.swift; sourceTree = "<group>"; };
|
||||
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = CoreStore.podspec; sourceTree = SOURCE_ROOT; };
|
||||
B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Where.Expression.swift; sourceTree = "<group>"; };
|
||||
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPathGenericBindings.swift; sourceTree = "<group>"; };
|
||||
B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSCoreStore.swift; sourceTree = "<group>"; };
|
||||
B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDataStack.swift; sourceTree = "<group>"; };
|
||||
B5DBE2DA1C9939E100B5CEFA /* CoreStoreTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreStoreTests-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
@@ -930,7 +922,6 @@
|
||||
B5E84EEC1AFF846E0064E85B /* DataStack+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DataStack+Transaction.swift"; sourceTree = "<group>"; };
|
||||
B5E84EED1AFF846E0064E85B /* UnsafeDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeDataTransaction.swift; sourceTree = "<group>"; };
|
||||
B5E84EEE1AFF846E0064E85B /* CoreStore+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Transaction.swift"; sourceTree = "<group>"; };
|
||||
B5E84EF21AFF846E0064E85B /* SaveResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SaveResult.swift; sourceTree = "<group>"; };
|
||||
B5E84EF31AFF846E0064E85B /* SynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronousDataTransaction.swift; sourceTree = "<group>"; };
|
||||
B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseDataTransaction+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5E84F001AFF847B0064E85B /* Tweak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tweak.swift; sourceTree = "<group>"; };
|
||||
@@ -956,7 +947,6 @@
|
||||
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeErasedClauses.swift; sourceTree = "<group>"; };
|
||||
B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Observing.swift"; sourceTree = "<group>"; };
|
||||
B5E8A72621C3B85000EF006A /* Playground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSBaseDataTransaction+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5ECDBE41CA6BEA300C7F112 /* CSClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSClauseTypes.swift; sourceTree = "<group>"; };
|
||||
B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSFrom.swift; sourceTree = "<group>"; };
|
||||
@@ -1047,7 +1037,8 @@
|
||||
2F03A52619C5C6DA005002A5 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5E8A72621C3B85000EF006A /* Playground.playground */,
|
||||
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */,
|
||||
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */,
|
||||
2F291E3119C6D4D3007AF63F /* Frameworks */,
|
||||
2F03A53219C5C6DA005002A5 /* Sources */,
|
||||
2F03A53C19C5C6DA005002A5 /* CoreStoreTests */,
|
||||
@@ -1123,6 +1114,7 @@
|
||||
B5489F3C1CF5EEBC008B4978 /* TestEntities */,
|
||||
B5489F451CF5F017008B4978 /* TransactionTests.swift */,
|
||||
B525577F1D029D2500E51965 /* TweakTests.swift */,
|
||||
B59A51822256C85E00CEF3C5 /* VersionLockTests.swift */,
|
||||
B52557731D02791400E51965 /* WhereTests.swift */,
|
||||
);
|
||||
path = CoreStoreTests;
|
||||
@@ -1254,7 +1246,6 @@
|
||||
B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */,
|
||||
B5ECDC281CA81CC700C7F112 /* CSDataStack+Transaction.swift */,
|
||||
B5ECDC2E1CA81CDC00C7F112 /* CSCoreStore+Transaction.swift */,
|
||||
B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */,
|
||||
);
|
||||
name = Transactions;
|
||||
sourceTree = "<group>";
|
||||
@@ -1333,6 +1324,7 @@
|
||||
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */,
|
||||
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
|
||||
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */,
|
||||
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */,
|
||||
);
|
||||
name = "KeyPath Utilities";
|
||||
sourceTree = "<group>";
|
||||
@@ -1452,7 +1444,6 @@
|
||||
B5E84EEC1AFF846E0064E85B /* DataStack+Transaction.swift */,
|
||||
B5E84EEE1AFF846E0064E85B /* CoreStore+Transaction.swift */,
|
||||
B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */,
|
||||
B5E84EF21AFF846E0064E85B /* SaveResult.swift */,
|
||||
);
|
||||
name = Transactions;
|
||||
sourceTree = "<group>";
|
||||
@@ -1480,6 +1471,7 @@
|
||||
B5E84F011AFF847B0064E85B /* From.swift */,
|
||||
B5E84F031AFF847B0064E85B /* Select.swift */,
|
||||
B5E84F051AFF847B0064E85B /* Where.swift */,
|
||||
B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */,
|
||||
B5E84F041AFF847B0064E85B /* OrderBy.swift */,
|
||||
B5E84F021AFF847B0064E85B /* GroupBy.swift */,
|
||||
B5E84F001AFF847B0064E85B /* Tweak.swift */,
|
||||
@@ -1530,8 +1522,8 @@
|
||||
children = (
|
||||
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */,
|
||||
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */,
|
||||
B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */,
|
||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
|
||||
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
||||
B51260921E9B28F100402229 /* EntityIdentifier.swift */,
|
||||
@@ -1582,9 +1574,6 @@
|
||||
B5FE4DA11C8481E100FA6A91 /* StorageInterface.swift */,
|
||||
B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */,
|
||||
B5FE4DAB1C85D44E00FA6A91 /* SQLiteStore.swift */,
|
||||
B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */,
|
||||
B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */,
|
||||
B5677D3C1CD3B1E400322BFC /* ICloudStoreObserver.swift */,
|
||||
);
|
||||
name = StorageInterfaces;
|
||||
sourceTree = "<group>";
|
||||
@@ -1764,7 +1753,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0730;
|
||||
LastUpgradeCheck = 0930;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
||||
TargetAttributes = {
|
||||
2F03A52F19C5C6DA005002A5 = {
|
||||
@@ -1801,6 +1790,7 @@
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
@@ -1885,17 +1875,16 @@
|
||||
B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */,
|
||||
B51260891E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||
B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */,
|
||||
B529C2041CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */,
|
||||
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */,
|
||||
B5E84F131AFF847B0064E85B /* Where.swift in Sources */,
|
||||
B5D339D81E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B56923FA1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||
B55514EA1EED8BF900BAB888 /* From+Querying.swift in Sources */,
|
||||
B596BBBB1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */,
|
||||
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
@@ -1926,7 +1915,6 @@
|
||||
B56923F01EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
|
||||
B5E84F121AFF847B0064E85B /* OrderBy.swift in Sources */,
|
||||
B546F9581C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
||||
B5677D3D1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||
B5E84F361AFF85470064E85B /* NSManagedObjectContext+Setup.swift in Sources */,
|
||||
B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */,
|
||||
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
|
||||
@@ -1935,11 +1923,11 @@
|
||||
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
||||
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
||||
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
B5DAFB482203D9F8003FCCD0 /* Where.Expression.swift in Sources */,
|
||||
B5FE4DA21C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||
B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||
B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */,
|
||||
B52661401CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
|
||||
B53FBA181CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B5519A591CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
|
||||
@@ -1976,7 +1964,6 @@
|
||||
B5519A4A1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
||||
B52F742F1E9B50D0005F3DAC /* SchemaHistory.swift in Sources */,
|
||||
B5E84EF51AFF846E0064E85B /* BaseDataTransaction.swift in Sources */,
|
||||
B5E84EFB1AFF846E0064E85B /* SaveResult.swift in Sources */,
|
||||
B5D339EC1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */,
|
||||
B5E84F0F1AFF847B0064E85B /* From.swift in Sources */,
|
||||
B5FAD6A91B50A4B400714891 /* Progress+Convenience.swift in Sources */,
|
||||
@@ -2005,7 +1992,6 @@
|
||||
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B538BA771D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B512607F1E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
|
||||
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B5831B7A1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
@@ -2019,6 +2005,7 @@
|
||||
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72021C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D152227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
@@ -2061,6 +2048,7 @@
|
||||
B5489F461CF5F017008B4978 /* TransactionTests.swift in Sources */,
|
||||
B52557801D029D2500E51965 /* TweakTests.swift in Sources */,
|
||||
B580857A1CDF808C004C2EEB /* SetupTests.swift in Sources */,
|
||||
B59A51832256C85E00CEF3C5 /* VersionLockTests.swift in Sources */,
|
||||
B5489F4C1CF5F743008B4978 /* BaseTestCase.swift in Sources */,
|
||||
B5DBE2DF1C9939E100B5CEFA /* BridgingTests.m in Sources */,
|
||||
B57D27BE1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */,
|
||||
@@ -2082,7 +2070,6 @@
|
||||
82BA18A21C4BBD1D00A0916E /* CoreStoreError.swift in Sources */,
|
||||
B512608A1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||
82BA18B21C4BBD3900A0916E /* ImportableObject.swift in Sources */,
|
||||
B529C2061CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */,
|
||||
82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */,
|
||||
82BA18AB1C4BBD3100A0916E /* AsynchronousDataTransaction.swift in Sources */,
|
||||
B5D339D91E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||
@@ -2112,7 +2099,6 @@
|
||||
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5E1B5AA1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5D339F21E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B5E1B59F1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
||||
B5ECDC251CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
||||
B549F6741E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
||||
@@ -2123,14 +2109,14 @@
|
||||
B56923F11EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
|
||||
82BA18A11C4BBD1D00A0916E /* CoreStore.swift in Sources */,
|
||||
B546F9591C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
||||
B5677D3F1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||
82BA18CF1C4BBD7100A0916E /* Functions.swift in Sources */,
|
||||
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
|
||||
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
|
||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B5831F4022126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */,
|
||||
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B5831F432212700400D8604C /* Where.Expression.swift in Sources */,
|
||||
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||
@@ -2138,7 +2124,6 @@
|
||||
82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */,
|
||||
B53FBA1A1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
82BA18CA1C4BBD5900A0916E /* MigrationResult.swift in Sources */,
|
||||
B52661421CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
|
||||
B5519A5A1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
|
||||
B5ECDBE11CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
|
||||
82BA18C11C4BBD5300A0916E /* CoreStore+Observing.swift in Sources */,
|
||||
@@ -2199,7 +2184,6 @@
|
||||
82BA18CB1C4BBD6400A0916E /* NSManagedObject+Convenience.swift in Sources */,
|
||||
82BA18B51C4BBD3F00A0916E /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
@@ -2216,6 +2200,7 @@
|
||||
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72121C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D162227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CAF1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
@@ -2258,6 +2243,7 @@
|
||||
B52557711D02561A00E51965 /* SelectTests.swift in Sources */,
|
||||
B5489F471CF5F017008B4978 /* TransactionTests.swift in Sources */,
|
||||
B52557811D029D2500E51965 /* TweakTests.swift in Sources */,
|
||||
B59A51842256C85E00CEF3C5 /* VersionLockTests.swift in Sources */,
|
||||
B5489F4D1CF5F743008B4978 /* BaseTestCase.swift in Sources */,
|
||||
82BA18DC1C4BBD9C00A0916E /* Model.xcdatamodeld in Sources */,
|
||||
B57D27BF1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */,
|
||||
@@ -2274,7 +2260,6 @@
|
||||
B5220E1E1D13080D009BC71E /* CSListMonitor.swift in Sources */,
|
||||
B5DBE2D01C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B5CA2B0B1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
|
||||
B5677D411CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||
B56923F81EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||
B52DD1BE1BE1F94300949AFE /* Progress+Convenience.swift in Sources */,
|
||||
B512608C1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||
@@ -2303,7 +2288,6 @@
|
||||
B52DD1AB1BE1F93900949AFE /* From.swift in Sources */,
|
||||
B546F95B1C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
||||
B52DD1A11BE1F92C00949AFE /* DataStack+Transaction.swift in Sources */,
|
||||
B5D3F6481C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B5220E1C1D130801009BC71E /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||
B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */,
|
||||
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
@@ -2325,9 +2309,11 @@
|
||||
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
|
||||
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B5831F4222126FED00D8604C /* KeyPathGenericBindings.swift in Sources */,
|
||||
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
||||
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
B5831F452212700500D8604C /* Where.Expression.swift in Sources */,
|
||||
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
B5ECDBE31CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
|
||||
B5ECDC031CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||
@@ -2336,7 +2322,6 @@
|
||||
B52DD1C71BE1F94600949AFE /* NSManagedObjectContext+Querying.swift in Sources */,
|
||||
B52DD1C81BE1F94600949AFE /* NSManagedObjectContext+Setup.swift in Sources */,
|
||||
B52DD1C31BE1F94600949AFE /* NotificationObserver.swift in Sources */,
|
||||
B52661441CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
|
||||
B52DD1A81BE1F93200949AFE /* DataStack+Querying.swift in Sources */,
|
||||
B5220E221D130818009BC71E /* CSSectionBy.swift in Sources */,
|
||||
B52DD1BC1BE1F94000949AFE /* MigrationResult.swift in Sources */,
|
||||
@@ -2357,7 +2342,6 @@
|
||||
B52DD19C1BE1F92C00949AFE /* Into.swift in Sources */,
|
||||
B5FE4DA51C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||
B596BBB91DD5BC67001DCDD9 /* FetchableSource.swift in Sources */,
|
||||
B529C2081CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */,
|
||||
B5FE4DAA1C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B52DD1AF1BE1F93900949AFE /* GroupBy.swift in Sources */,
|
||||
B52DD1B01BE1F93900949AFE /* Tweak.swift in Sources */,
|
||||
@@ -2368,7 +2352,6 @@
|
||||
B52DD1BA1BE1F94000949AFE /* MigrationChain.swift in Sources */,
|
||||
B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */,
|
||||
B52F74321E9B50D0005F3DAC /* SchemaHistory.swift in Sources */,
|
||||
B52DD1A31BE1F92C00949AFE /* SaveResult.swift in Sources */,
|
||||
B5220E211D130816009BC71E /* CSObjectObserver.swift in Sources */,
|
||||
B5D339EF1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */,
|
||||
B52DD19F1BE1F92C00949AFE /* SynchronousDataTransaction.swift in Sources */,
|
||||
@@ -2378,7 +2361,6 @@
|
||||
B5215CAC1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
|
||||
B53FBA0F1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
||||
B52F744D1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B52DD19A1BE1F92800949AFE /* CoreStore+Logging.swift in Sources */,
|
||||
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B546F96C1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
@@ -2413,6 +2395,7 @@
|
||||
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
|
||||
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72321C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D182227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CB11FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
@@ -2455,6 +2438,7 @@
|
||||
B5489F481CF5F017008B4978 /* TransactionTests.swift in Sources */,
|
||||
B52557821D029D2500E51965 /* TweakTests.swift in Sources */,
|
||||
B5489F4E1CF5F743008B4978 /* BaseTestCase.swift in Sources */,
|
||||
B59A51852256C85E00CEF3C5 /* VersionLockTests.swift in Sources */,
|
||||
B5598BCC1BE2093D0092EFCE /* Model.xcdatamodeld in Sources */,
|
||||
B5220E261D1308C2009BC71E /* ListObserverTests.swift in Sources */,
|
||||
B57D27C01D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */,
|
||||
@@ -2476,7 +2460,6 @@
|
||||
B56321801BD65216006C9394 /* CoreStoreError.swift in Sources */,
|
||||
B512608B1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||
B56321AD1BD6521C006C9394 /* MigrationManager.swift in Sources */,
|
||||
B529C2071CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */,
|
||||
B563219D1BD65216006C9394 /* DataStack+Observing.swift in Sources */,
|
||||
B56321961BD65216006C9394 /* From.swift in Sources */,
|
||||
B5D339DA1E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||
@@ -2504,7 +2487,6 @@
|
||||
B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||
B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B5D339F31E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5E1B5A01CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
||||
B5ECDC261CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
||||
@@ -2516,20 +2498,20 @@
|
||||
B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */,
|
||||
B56923F21EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
|
||||
B546F95A1C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
||||
B5677D401CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||
B56321941BD65216006C9394 /* CoreStore+Querying.swift in Sources */,
|
||||
B56321811BD65216006C9394 /* DataStack.swift in Sources */,
|
||||
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
||||
B5831F4122126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */,
|
||||
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B5831F442212700500D8604C /* Where.Expression.swift in Sources */,
|
||||
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||
B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */,
|
||||
B52661431CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
|
||||
B53FBA1B1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
B5519A5B1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
|
||||
B5ECDBE21CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
|
||||
@@ -2569,7 +2551,6 @@
|
||||
B56321991BD65216006C9394 /* OrderBy.swift in Sources */,
|
||||
B5D339EE1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */,
|
||||
B56321A51BD65216006C9394 /* MigrationChain.swift in Sources */,
|
||||
B563218E1BD65216006C9394 /* SaveResult.swift in Sources */,
|
||||
B5E222261CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||
B56321A21BD65216006C9394 /* ListObserver.swift in Sources */,
|
||||
B5215CAB1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
|
||||
@@ -2593,7 +2574,6 @@
|
||||
B56321851BD65216006C9394 /* CoreStore+Logging.swift in Sources */,
|
||||
B56321921BD65216006C9394 /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
@@ -2610,6 +2590,7 @@
|
||||
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72221C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D172227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CB01FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
@@ -2654,6 +2635,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
@@ -2709,7 +2691,7 @@
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 10.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@@ -2723,6 +2705,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
@@ -2771,7 +2754,7 @@
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 10.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
@@ -2796,7 +2779,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2815,7 +2797,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2836,7 +2817,6 @@
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2852,7 +2832,6 @@
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2873,7 +2852,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -2895,7 +2873,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Release;
|
||||
@@ -2914,7 +2891,6 @@
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -2933,7 +2909,6 @@
|
||||
SDKROOT = appletvos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Release;
|
||||
@@ -2958,7 +2933,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2983,7 +2957,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -3004,7 +2977,6 @@
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -3025,7 +2997,6 @@
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -3047,7 +3018,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -3071,7 +3041,6 @@
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -276,7 +276,7 @@
|
||||
};
|
||||
buildConfigurationList = B54AAD441AF4D26E00848AE0 /* Build configuration list for PBXProject "CoreStoreDemo" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
@@ -416,7 +416,7 @@
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -464,7 +464,7 @@
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
@@ -478,7 +478,6 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -492,7 +491,6 @@
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -18,7 +18,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ class FetchingResultsViewController: UITableViewController {
|
||||
super.viewDidLoad()
|
||||
|
||||
self.tableView.estimatedRowHeight = 60
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension
|
||||
self.tableView.rowHeight = UITableView.automaticDimension
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class QueryingResultsViewController: UITableViewController {
|
||||
super.viewDidLoad()
|
||||
|
||||
self.tableView.estimatedRowHeight = 60
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension
|
||||
self.tableView.rowHeight = UITableView.automaticDimension
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -90,8 +90,9 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Mask + Oval 1 + Oval 1 + Oval 1.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>6.0.0</string>
|
||||
<string>6.3.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -187,7 +187,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
|
||||
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
|
||||
|
||||
switch editingStyle {
|
||||
|
||||
@@ -313,6 +313,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
@IBAction private dynamic func shuffleBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
self.setTable(enabled: false)
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
@@ -322,12 +323,16 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
palette.colorName .= nil
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
completion: { _ in
|
||||
|
||||
self.setTable(enabled: true)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private func setTable(enabled: Bool) {
|
||||
|
||||
|
||||
tableView.isUserInteractionEnabled = enabled
|
||||
UIView.animate(
|
||||
withDuration: 0.2,
|
||||
delay: 0,
|
||||
@@ -337,7 +342,6 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
if let tableView = self.tableView {
|
||||
|
||||
tableView.alpha = enabled ? 1.0 : 0.5
|
||||
tableView.isUserInteractionEnabled = enabled
|
||||
}
|
||||
},
|
||||
completion: nil
|
||||
|
||||
@@ -360,7 +360,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
if let dataStack = dataStack, let model = model {
|
||||
|
||||
self.segmentedControl?.selectedSegmentIndex = self.models
|
||||
.index(
|
||||
.firstIndex(
|
||||
where: { (arg) -> Bool in
|
||||
|
||||
let (_, _, schemaHistory) = arg
|
||||
@@ -386,7 +386,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
}
|
||||
else {
|
||||
|
||||
self.segmentedControl?.selectedSegmentIndex = UISegmentedControlNoSegment
|
||||
self.segmentedControl?.selectedSegmentIndex = UISegmentedControl.noSegment
|
||||
self._listMonitor = nil
|
||||
self._dataStack = nil
|
||||
}
|
||||
|
||||
@@ -30,9 +30,10 @@ import CoreStore
|
||||
|
||||
#if os(macOS)
|
||||
typealias Color = NSColor
|
||||
|
||||
#else
|
||||
|
||||
typealias Color = UIColor
|
||||
|
||||
#endif
|
||||
|
||||
class Animal: CoreStoreObject {
|
||||
@@ -70,8 +71,13 @@ class Person: CoreStoreObject {
|
||||
customGetter: Person.getDisplayName(_:),
|
||||
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
|
||||
)
|
||||
|
||||
let spouse = Relationship.ToOne<Person>("spouse")
|
||||
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
|
||||
private let _spouse = Relationship.ToOne<Person>("_spouseInverse", inverse: { $0.spouse })
|
||||
|
||||
|
||||
private static func setTitle(_ partialObject: PartialObject<Person>, _ newValue: String) {
|
||||
|
||||
@@ -126,7 +132,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
versionLock: [
|
||||
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
||||
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
|
||||
"Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b]
|
||||
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
|
||||
]
|
||||
)
|
||||
)
|
||||
@@ -134,7 +140,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
|
||||
let k1 = String(keyPath: \Animal.species)
|
||||
XCTAssertEqual(k1, "species")
|
||||
|
||||
|
||||
let k2 = String(keyPath: \Dog.species)
|
||||
XCTAssertEqual(k2, "species")
|
||||
|
||||
@@ -272,11 +278,11 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
|
||||
_ = try transaction.fetchAll(
|
||||
From<Dog>()
|
||||
.where(\Animal.species == "Dog" && \.age == 10)
|
||||
.where(\Animal.species == "Dog" && \Dog.age == 10)
|
||||
)
|
||||
_ = try transaction.fetchAll(
|
||||
From<Dog>()
|
||||
.where(\.age == 10 && \Animal.species == "Dog")
|
||||
.where(\Dog.age == 10 && \Animal.species == "Dog")
|
||||
.orderBy(.ascending({ $0.species }))
|
||||
)
|
||||
_ = try transaction.fetchAll(
|
||||
|
||||
@@ -74,31 +74,31 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -113,98 +113,98 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config2")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>()
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config1")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config2")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -219,96 +219,96 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(Set(affectedConfigurations), ["PF_DEFAULT_CONFIGURATION_NAME", "Config1"] as Set)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config2")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>()
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config1")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config2")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -323,94 +323,94 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config2")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>()
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config2"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config1")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config2")
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.safeAffectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config2"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ final class GroupByTests: BaseTestCase {
|
||||
|
||||
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
try From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
groupBy.applyToFetchRequest(request)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>6.0.0</string>
|
||||
<string>6.2.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11759" systemVersion="16C67" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="17G2307" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
|
||||
<entity name="TestEntity1AAA" representedClassName="CoreStoreTests.TestEntity1" syncable="YES">
|
||||
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
|
||||
@@ -9,6 +9,8 @@
|
||||
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<relationship name="testToManyUnordered" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToOne" inverseEntity="TestEntity1AAA" syncable="YES"/>
|
||||
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToManyUnordered" inverseEntity="TestEntity1AAA" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="TestEntity2" representedClassName="CoreStoreTests.TestEntity2" syncable="YES">
|
||||
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
||||
@@ -19,6 +21,8 @@
|
||||
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<relationship name="testToManyOrdered" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TestEntity2" inverseName="testToOne" inverseEntity="TestEntity2" syncable="YES"/>
|
||||
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity2" inverseName="testToManyOrdered" inverseEntity="TestEntity2" syncable="YES"/>
|
||||
</entity>
|
||||
<configuration name="Config1">
|
||||
<memberEntity name="TestEntity1AAA"/>
|
||||
@@ -27,7 +31,7 @@
|
||||
<memberEntity name="TestEntity2"/>
|
||||
</configuration>
|
||||
<elements>
|
||||
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="165"/>
|
||||
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="165"/>
|
||||
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="195"/>
|
||||
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="195"/>
|
||||
</elements>
|
||||
</model>
|
||||
@@ -179,7 +179,7 @@ final class OrderByTests: XCTestCase {
|
||||
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
|
||||
|
||||
let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
orderBy.applyToFetchRequest(request)
|
||||
XCTAssertNotNil(request.sortDescriptors)
|
||||
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)
|
||||
|
||||
@@ -330,7 +330,14 @@ class SetupTests: BaseTestDataTestCase {
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try! stack.addStorageAndWait(sqliteStore)
|
||||
try! stack.addStorageAndWait(
|
||||
SQLiteStore.legacy(
|
||||
fileName: sqliteStore.fileURL.lastPathComponent,
|
||||
configuration: sqliteStore.configuration,
|
||||
migrationMappingProviders: sqliteStore.migrationMappingProviders,
|
||||
localStorageOptions: .recreateStoreOnModelMismatch
|
||||
)
|
||||
)
|
||||
self.prepareTestDataForStack(stack)
|
||||
}
|
||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||
|
||||
@@ -36,4 +36,6 @@ class TestEntity1: NSManagedObject {
|
||||
@NSManaged var testDecimal: NSDecimalNumber?
|
||||
@NSManaged var testData: Data?
|
||||
@NSManaged var testNil: String?
|
||||
@NSManaged var testToOne: TestEntity1?
|
||||
@NSManaged var testToManyUnordered: NSSet?
|
||||
}
|
||||
|
||||
@@ -36,4 +36,6 @@ class TestEntity2: NSManagedObject {
|
||||
@NSManaged var testDecimal: NSDecimalNumber?
|
||||
@NSManaged var testData: Data?
|
||||
@NSManaged var testNil: String?
|
||||
@NSManaged var testToOne: TestEntity2?
|
||||
@NSManaged var testToManyOrdered: NSOrderedSet?
|
||||
}
|
||||
|
||||
@@ -303,8 +303,8 @@ final class TransactionTests: BaseTestCase {
|
||||
do {
|
||||
|
||||
let createExpectation = self.expectation(description: "create")
|
||||
let dataPrepared: Void? = try? stack.perform(
|
||||
synchronous: { (transaction) in
|
||||
try stack.perform(
|
||||
synchronous: { (transaction) -> Void in
|
||||
|
||||
let object = transaction.create(Into<TestEntity1>())
|
||||
object.testEntityID = NSNumber(value: 1)
|
||||
@@ -313,10 +313,7 @@ final class TransactionTests: BaseTestCase {
|
||||
object.testDate = testDate
|
||||
}
|
||||
)
|
||||
if dataPrepared != nil {
|
||||
|
||||
createExpectation.fulfill()
|
||||
}
|
||||
createExpectation.fulfill()
|
||||
self.checkExpectationsImmediately()
|
||||
}
|
||||
do {
|
||||
|
||||
@@ -43,7 +43,7 @@ final class TweakTests: XCTestCase {
|
||||
$0.fetchLimit = 200
|
||||
$0.predicate = predicate
|
||||
}
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
tweak.applyToFetchRequest(request)
|
||||
XCTAssertEqual(request.fetchOffset, 100)
|
||||
XCTAssertEqual(request.fetchLimit, 200)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// SaveResult.swift
|
||||
// VersionLockTests.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2018 John Rommel Estropia
|
||||
@@ -23,36 +23,33 @@
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import XCTest
|
||||
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - SaveResult
|
||||
//MARK: - VersionLockTests
|
||||
|
||||
@available(*, deprecated, message: "Use the new DataStack.perform(asynchronous:...) and DataStack.perform(synchronous:...) family of APIs")
|
||||
public enum SaveResult: Hashable {
|
||||
|
||||
case success(hasChanges: Bool)
|
||||
case failure(CoreStoreError)
|
||||
|
||||
public var boolValue: Bool {
|
||||
final class VersionLockTests: XCTestCase {
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatVersionLocksProduceCorrectHashes() {
|
||||
|
||||
switch self {
|
||||
|
||||
case .success: return true
|
||||
case .failure: return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal init(hasChanges: Bool) {
|
||||
|
||||
self = .success(hasChanges: hasChanges)
|
||||
}
|
||||
|
||||
internal init(_ error: CoreStoreError) {
|
||||
|
||||
self = .failure(error)
|
||||
let versionLock: VersionLock = [
|
||||
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
||||
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
|
||||
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
|
||||
]
|
||||
XCTAssertEqual(
|
||||
versionLock.description,
|
||||
"""
|
||||
[
|
||||
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
||||
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
|
||||
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
|
||||
]
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,275 @@ final class WhereTests: XCTestCase {
|
||||
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
|
||||
|
||||
XCTAssertEqual(String(keyPath: \TestEntity1.testEntityID), "testEntityID")
|
||||
XCTAssertEqual(String(keyPath: \Animal.color), "color")
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatExpressions_HaveCorrectKeyPaths() {
|
||||
|
||||
do {
|
||||
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity1.testToOne.testEntityID),
|
||||
(\TestEntity1.testToOne ~ \.testEntityID).description,
|
||||
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered).description,
|
||||
String(keyPath: \TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).description,
|
||||
String(keyPath: \TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered)
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"master.pets",
|
||||
(\Animal.master ~ \.pets).description,
|
||||
String(keyPath: \Animal.master ~ \.pets)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).description,
|
||||
String(keyPath: \Animal.master ~ \.pets ~ \.species)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"master.pets.master",
|
||||
(\Animal.master ~ \.pets ~ \.master).description,
|
||||
String(keyPath: \Animal.master ~ \.pets ~ \.master)
|
||||
)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity1.testToOne.testToManyUnordered) + ".@count",
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).count())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered) + ".@count",
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"master.pets.@count",
|
||||
(\Animal.master ~ \.pets).count().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).count())
|
||||
)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ANY " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).any())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ANY " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ANY master.pets",
|
||||
(\Animal.master ~ \.pets).any().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).any())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ANY master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).any().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets ~ \.species).any())
|
||||
)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ALL " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).all())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ALL " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ALL master.pets",
|
||||
(\Animal.master ~ \.pets).all().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).all())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ALL master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).all().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets ~ \.species).all())
|
||||
)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"NONE " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).none())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"NONE " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"NONE master.pets",
|
||||
(\Animal.master ~ \.pets).none().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).none())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"NONE master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).none().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets ~ \.species).none())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatWhereClauses_CanBeCreatedFromExpressionsCorrectly() {
|
||||
|
||||
do {
|
||||
|
||||
let dummy = "dummy"
|
||||
do {
|
||||
|
||||
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testString) == dummy
|
||||
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testString)) == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause: Where<Animal> = (\.master ~ \.name) == dummy
|
||||
let predicate = NSPredicate(format: "master.name == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<Animal>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let dummy = "dummy"
|
||||
do {
|
||||
|
||||
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToOne ~ \.testString) == dummy
|
||||
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToOne.testString)) == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause: Where<Animal> = (\.master ~ \.spouse ~ \.name) == dummy
|
||||
let predicate = NSPredicate(format: "master.spouse.name == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<Animal>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let count = 3
|
||||
do {
|
||||
|
||||
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered).count() == count
|
||||
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToManyUnordered)).@count == %d", count)
|
||||
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause: Where<Animal> = (\.master ~ \.pets).count() == count
|
||||
let predicate = NSPredicate(format: "master.pets.@count == %d", count)
|
||||
XCTAssertEqual(whereClause, Where<Animal>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let dummy = "dummy"
|
||||
do {
|
||||
|
||||
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).any() == dummy
|
||||
let predicate = NSPredicate(format: "ANY \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).any() == dummy
|
||||
let predicate = NSPredicate(format: "ANY master.pets.species == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<Animal>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let dummy = "dummy"
|
||||
do {
|
||||
|
||||
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).all() == dummy
|
||||
let predicate = NSPredicate(format: "ALL \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).all() == dummy
|
||||
let predicate = NSPredicate(format: "ALL master.pets.species == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<Animal>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
||||
let dummy = "dummy"
|
||||
do {
|
||||
|
||||
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).none() == dummy
|
||||
let predicate = NSPredicate(format: "NONE \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).none() == dummy
|
||||
let predicate = NSPredicate(format: "NONE master.pets.species == %@", dummy)
|
||||
XCTAssertEqual(whereClause, Where<Animal>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
@@ -314,7 +583,7 @@ final class WhereTests: XCTestCase {
|
||||
dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() {
|
||||
|
||||
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
|
||||
let request = CoreStoreFetchRequest()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
whereClause.applyToFetchRequest(request)
|
||||
XCTAssertNotNil(request.predicate)
|
||||
XCTAssertEqual(request.predicate, whereClause.predicate)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// swift-tools-version:4.2
|
||||
//
|
||||
// Package.swift
|
||||
// CoreStore
|
||||
@@ -25,21 +26,18 @@
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let targets: [Target]
|
||||
#if os(iOS)
|
||||
targets = [Target(name: "CoreStore iOS")]
|
||||
#elseif os(macOS)
|
||||
targets = [Target(name: "CoreStore OSX")]
|
||||
#elseif os(watchOS)
|
||||
targets = [Target(name: "CoreStore watchOS")]
|
||||
#elseif os(tvOS)
|
||||
targets = [Target(name: "CoreStore tvOS")]
|
||||
#else
|
||||
targets = []
|
||||
#endif
|
||||
|
||||
let package = Package(
|
||||
name: "CoreStore",
|
||||
targets: targets,
|
||||
exclude: ["Carthage", "CoreStoreDemo", "Sources/libA/images"]
|
||||
products: [
|
||||
.library(name: "CoreStore", type: .static, targets: ["CoreStore"])
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "CoreStore",
|
||||
dependencies: [],
|
||||
path: "Sources",
|
||||
exclude: ["CoreStoreBridge.h", "CoreStoreBridge.m"]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import UIKit
|
||||
import CoreStore
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<UIColor>("color", initial: .orange)
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
}
|
||||
/// =======================
|
||||
|
||||
/// Stack setup ===========
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "V1",
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
]
|
||||
)
|
||||
)
|
||||
try dataStack.addStorageAndWait(SQLiteStore(fileName: "data.sqlite"))
|
||||
/// =======================
|
||||
|
||||
/// Transactions ==========
|
||||
dataStack.perform(synchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
})
|
||||
/// =======================
|
||||
|
||||
/// Accessing Objects =====
|
||||
let bird = dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
bird.species.value
|
||||
bird.color.value
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
owner.name.value
|
||||
owner.pets.count
|
||||
print(owner)
|
||||
/// =======================
|
||||
79
Playground_iOS.playground/Contents.swift
Normal file
79
Playground_iOS.playground/Contents.swift
Normal file
@@ -0,0 +1,79 @@
|
||||
import UIKit
|
||||
import CoreStore
|
||||
import PlaygroundSupport
|
||||
|
||||
PlaygroundPage.current.needsIndefiniteExecution = true
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<UIColor>("color", initial: .orange)
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
}
|
||||
/// =======================
|
||||
|
||||
/// Stack setup ===========
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "V1",
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
]
|
||||
)
|
||||
)
|
||||
dataStack.addStorage(
|
||||
SQLiteStore(fileName: "data.sqlite"),
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Transactions ==========
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
},
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Accessing Objects =====
|
||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
print(bird.species.value)
|
||||
print(bird.color.value as Any)
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
print(owner.name.value as Any)
|
||||
print(owner.pets.count)
|
||||
print(owner)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
77
Playground_macOS.playground/Contents.swift
Normal file
77
Playground_macOS.playground/Contents.swift
Normal file
@@ -0,0 +1,77 @@
|
||||
import AppKit
|
||||
import CoreStore
|
||||
import PlaygroundSupport
|
||||
|
||||
PlaygroundPage.current.needsIndefiniteExecution = true
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<NSColor>("color", initial: .orange)
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
}
|
||||
/// =======================
|
||||
|
||||
/// Stack setup ===========
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "V1",
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
]
|
||||
)
|
||||
)
|
||||
dataStack.addStorage(
|
||||
SQLiteStore(fileName: "data.sqlite"),
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Transactions ==========
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
},
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Accessing Objects =====
|
||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
print(bird.species.value)
|
||||
print(bird.color.value as Any)
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
print(owner.name.value as Any)
|
||||
print(owner.pets.count)
|
||||
print(owner)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
4
Playground_macOS.playground/contents.xcplayground
Normal file
4
Playground_macOS.playground/contents.xcplayground
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
7
Playground_macOS.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
Playground_macOS.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
192
README.md
192
README.md
@@ -6,22 +6,23 @@ Unleashing the real power of Core Data with the elegance and safety of Swift
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://travis-ci.org/JohnEstropia/CoreStore"><img alt="Build Status" src="https://img.shields.io/travis/JohnEstropia/CoreStore/master.svg?style=flat" /></a>
|
||||
<a href="https://github.com/JohnEstropia/CoreStore/commits"><img alt="Last Commit" src="https://img.shields.io/github/last-commit/johnestropia/corestore.svg?style=flat" /></a>
|
||||
<a href="http://cocoadocs.org/docsets/CoreStore"><img alt="Platform" src="https://img.shields.io/cocoapods/p/CoreStore.svg?style=flat" /></a>
|
||||
<a href="https://raw.githubusercontent.com/JohnEstropia/CoreStore/master/LICENSE"><img alt="License" src="https://img.shields.io/cocoapods/l/CoreStore.svg?style=flat" /></a>
|
||||
<br /><br />Dependency managers<br />
|
||||
<a href="https://cocoapods.org/pods/CoreStore"><img alt="Cocoapods compatible" src="https://img.shields.io/cocoapods/v/CoreStore.svg?style=flat&label=Cocoapods" /></a>
|
||||
<a href="https://github.com/Carthage/Carthage"><img alt="Carthage compatible" src="https://img.shields.io/badge/Carthage-compatible-16a085.svg?style=flat" /></a>
|
||||
<a href="https://swiftpkgs.ng.bluemix.net/package/JohnEstropia/CoreStore"><img alt="Swift Package Manager compatible" src="https://img.shields.io/badge/Swift_Package_Manager-compatible-orange.svg?style=flat" /></a>
|
||||
<a href="https://swift.org/source-compatibility/#current-list-of-projects"><img alt="Swift Package Manager compatible" src="https://img.shields.io/badge/Swift_Package_Manager-compatible-orange.svg?style=flat" /></a>
|
||||
<br /><br />Contact<br />
|
||||
<a href="http://swift-corestore-slack.herokuapp.com/"><img alt="Join us on Slack!" src="http://swift-corestore-slack.herokuapp.com/badge.svg" /></a>
|
||||
<a href="https://twitter.com/JohnEstropia"><img alt="Reach me on Twitter!" src="https://img.shields.io/badge/twitter-%40JohnEstropia-3498db.svg" /></a>
|
||||
<br />
|
||||
</p>
|
||||
|
||||
* **Swift 4.2:** iOS 9+ / macOS 10.10+ / watchOS 2.0+ / tvOS 9.0+
|
||||
* Other Swift versions: [Swift 3.2(version 4.2.3)](https://github.com/JohnEstropia/CoreStore/tree/4.2.3)
|
||||
* **Swift 5.0:** 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)
|
||||
|
||||
Upgrading from CoreStore 4.2 (Swift 3.2) to 5.x (Swift 4.x)? Check out the [new features](#features) and make sure to read the [Change logs](https://github.com/JohnEstropia/CoreStore/releases).
|
||||
Upgrading from CoreStore 5.x (min iOS 9) to 6.x (min iOS 10)? Check out the [new 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).
|
||||
|
||||
@@ -58,7 +59,6 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
|
||||
- [Setting up](#setting-up)
|
||||
- [In-memory store](#in-memory-store)
|
||||
- [Local store](#local-store)
|
||||
- [iCloud store](#icloud-store)
|
||||
- [Migrations](#migrations)
|
||||
- [Declaring model versions](#declaring-model-versions)
|
||||
- [Starting migrations](#starting-migrations)
|
||||
@@ -86,6 +86,7 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
|
||||
- [`GroupBy` clause](#groupby-clause)
|
||||
- [Logging and error reporting](#logging-and-error-reporting)
|
||||
- [Observing changes and notifications](#observing-changes-and-notifications)
|
||||
- [Observe a single property](#observe-a-single-property)
|
||||
- [Observe a single object](#observe-a-single-object)
|
||||
- [Observe a list of objects](#observe-a-list-of-objects)
|
||||
- [Objective-C support](#objective-c-support)
|
||||
@@ -139,12 +140,12 @@ CoreStore.perform(
|
||||
|
||||
Fetching objects (simple):
|
||||
```swift
|
||||
let people = CoreStore.fetchAll(From<MyPersonEntity>())
|
||||
let people = try CoreStore.fetchAll(From<MyPersonEntity>())
|
||||
```
|
||||
|
||||
Fetching objects (complex):
|
||||
```swift
|
||||
let people = CoreStore.fetchAll(
|
||||
let people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 30),
|
||||
.orderBy(.ascending(\.name), .descending(.\age)),
|
||||
@@ -154,7 +155,7 @@ let people = CoreStore.fetchAll(
|
||||
|
||||
Querying values:
|
||||
```swift
|
||||
let maxAge = CoreStore.queryValue(
|
||||
let maxAge = try CoreStore.queryValue(
|
||||
From<MyPersonEntity>()
|
||||
.select(Int.self, .maximum(\.age))
|
||||
)
|
||||
@@ -311,66 +312,6 @@ public protocol LocalStorage: StorageInterface {
|
||||
```
|
||||
If you have custom `NSIncrementalStore` or `NSAtomicStore` subclasses, you can implement this protocol and use it similarly to `SQLiteStore`.
|
||||
|
||||
### iCloud Store
|
||||
> ⚠️**Important:** The iCloud Store is being deprecated. Please use with caution. If you have any concerns please do send me a message on [Twitter](https://twitter.com/JohnEstropia) or on the [CoreStore Slack Team](http://swift-corestore-slack.herokuapp.com/)
|
||||
|
||||
As a counterpart to `LocalStorage`, the `CloudStorage` protocol abstracts stores managed in the cloud. CoreStore currently provides the concrete class `ICloudStore`. Unlike `InMemoryStore` and `SQLiteStore` though, the `ICloudStore`'s initializer may return `nil` if the iCloud container could not be located or if iCloud is not available on the device:
|
||||
```swift
|
||||
guard let storage = ICloudStore(
|
||||
ubiquitousContentName: "MyAppCloudData", // the name of the store in iCloud
|
||||
ubiquitousContentTransactionLogsSubdirectory: "logs/config1", // optional. Subdirectory path for the transaction logs
|
||||
ubiquitousContainerID: "iCloud.com.mycompany.myapp.containername", // optional. The container if your app has multiple ubiquity container identifiers in its entitlements
|
||||
ubiquitousPeerToken: "9614d658014f4151a95d8048fb717cf0", // optional. A per-application salt to allow multiple apps on the same device to share a Core Data store integrated with iCloud
|
||||
configuration: "Config1", // optional. Use entities from the "Config1" configuration in the .xcdatamodeld file
|
||||
cloudStorageOptions: .recreateLocalStoreOnModelMismatch // optional. Provides settings that tells the DataStack how to setup the persistent store
|
||||
) else {
|
||||
// The iCloud container could not be located or if iCloud is not available on the device.
|
||||
// Handle appropriately
|
||||
return
|
||||
}
|
||||
CoreStore.addStorage(,
|
||||
storage,
|
||||
completion: { result in
|
||||
switch result {
|
||||
case .success(let storage): // ...
|
||||
case .failure(let error): // ...
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
If your app is using iCloud stores, you may want to be notified of particular iCloud events. The `ICloudStoreObserver` functions are all optional, so you may implement only the ones your app is interested in:
|
||||
```swift
|
||||
public protocol ICloudStoreObserver: class {
|
||||
func iCloudStoreWillFinishUbiquitousStoreInitialImport(storage storage: ICloudStore, dataStack: DataStack)
|
||||
func iCloudStoreDidFinishUbiquitousStoreInitialImport(storage storage: ICloudStore, dataStack: DataStack)
|
||||
func iCloudStoreWillAddAccount(storage storage: ICloudStore, dataStack: DataStack)
|
||||
func iCloudStoreDidAddAccount(storage storage: ICloudStore, dataStack: DataStack)
|
||||
func iCloudStoreWillRemoveAccount(storage storage: ICloudStore, dataStack: DataStack)
|
||||
func iCloudStoreDidRemoveAccount(storage storage: ICloudStore, dataStack: DataStack)
|
||||
func iCloudStoreWillRemoveContent(storage storage: ICloudStore, dataStack: DataStack)
|
||||
func iCloudStoreDidRemoveContent(storage storage: ICloudStore, dataStack: DataStack)
|
||||
}
|
||||
```
|
||||
To register your `ICloudStoreObserver`, call `addObserver(_:)` on the `ICloudStore` instance:
|
||||
|
||||
```swift
|
||||
guard let storage = ICloudStore(/* ... */) else {
|
||||
return
|
||||
}
|
||||
storage.addObserver(self) // assuming self implements ICloudStoreObserver
|
||||
CoreStore.addStorage(,
|
||||
storage,
|
||||
completion: { result in
|
||||
switch result {
|
||||
case .success(let storage): // ... You may also call storage.addObserver(_:) here
|
||||
case .failure(let error): // ...
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
The `ICloudStore` only keeps weak references of the registered observers. You may call `removeObserver(_:)` for precise deregistration, but `ICloudStore` automatically removes deallocated observers.
|
||||
|
||||
|
||||
## Migrations
|
||||
|
||||
@@ -851,7 +792,7 @@ To update an existing object, fetch the object's instance from the transaction:
|
||||
```swift
|
||||
CoreStore.perform(
|
||||
asynchronous: { (transaction) -> Void in
|
||||
let person = transaction.fetchOne(
|
||||
let person = try transaction.fetchOne(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.name == "Jane Smith")
|
||||
)
|
||||
@@ -913,8 +854,8 @@ let jane: MyPersonEntity = // ...
|
||||
|
||||
CoreStore.perform(
|
||||
asynchronous: { (transaction) -> Void in
|
||||
transaction.delete(john, jane)
|
||||
// transaction.delete([john, jane]) is also allowed
|
||||
try transaction.delete(john, jane)
|
||||
// try transaction.delete([john, jane]) is also allowed
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
@@ -923,7 +864,7 @@ If you do not have references yet to the objects to be deleted, transactions hav
|
||||
```swift
|
||||
CoreStore.perform(
|
||||
asynchronous: { (transaction) -> Void in
|
||||
transaction.deleteAll(
|
||||
try transaction.deleteAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 30)
|
||||
)
|
||||
@@ -971,7 +912,7 @@ var peopleIDs: [NSManagedObjectID] = // ...
|
||||
|
||||
CoreStore.perform(
|
||||
asynchronous: { (transaction) -> Void in
|
||||
let jane = transaction.fetchOne(
|
||||
let jane = try transaction.fetchOne(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.name == "Jane Smith")
|
||||
)
|
||||
@@ -1184,17 +1125,17 @@ Before we dive in, be aware that CoreStore distinguishes between *fetching* and
|
||||
#### `From` clause
|
||||
The search conditions for fetches and queries are specified using *clauses*. All fetches and queries require a `From` clause that indicates the target entity type:
|
||||
```swift
|
||||
let people = CoreStore.fetchAll(From<MyPersonEntity>())
|
||||
let people = try CoreStore.fetchAll(From<MyPersonEntity>())
|
||||
```
|
||||
`people` in the example above will be of type `[MyPersonEntity]`. The `From<MyPersonEntity>()` clause indicates a fetch to all persistent stores that `MyPersonEntity` belong to.
|
||||
|
||||
If the entity exists in multiple configurations and you need to only search from a particular configuration, indicate in the `From` clause the configuration name for the destination persistent store:
|
||||
```swift
|
||||
let people = CoreStore.fetchAll(From<MyPersonEntity>("Config1")) // ignore objects in persistent stores other than the "Config1" configuration
|
||||
let people = try CoreStore.fetchAll(From<MyPersonEntity>("Config1")) // ignore objects in persistent stores other than the "Config1" configuration
|
||||
```
|
||||
or if the persistent store is the auto-generated "Default" configuration, specify `nil`:
|
||||
```swift
|
||||
let person = CoreStore.fetchAll(From<MyPersonEntity>(nil))
|
||||
let person = try CoreStore.fetchAll(From<MyPersonEntity>(nil))
|
||||
```
|
||||
Now we know how to use a `From` clause, let's move on to fetching and querying.
|
||||
|
||||
@@ -1214,11 +1155,11 @@ Each method's purpose is straightforward, but we need to understand how to set t
|
||||
|
||||
The `Where` clause is CoreStore's `NSPredicate` wrapper. It specifies the search filter to use when fetching (or querying). It implements all initializers that `NSPredicate` does (except for `-predicateWithBlock:`, which Core Data does not support):
|
||||
```swift
|
||||
var people = CoreStore.fetchAll(
|
||||
var people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>(),
|
||||
Where<MyPersonEntity>("%K > %d", "age", 30) // string format initializer
|
||||
)
|
||||
people = CoreStore.fetchAll(
|
||||
people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>(),
|
||||
Where<MyPersonEntity>(true) // boolean initializer
|
||||
)
|
||||
@@ -1233,14 +1174,14 @@ var people = CoreStore.fetchAll(
|
||||
```
|
||||
⭐️Starting CoreStore 5.0, `Where` clauses became more type-safe and are now generic types. To avoid verbose repetition of the generic object type, fetch methods now support **Fetch Chain builders**. We can also use Swift's Smart KeyPaths as the `Where` clause expression:
|
||||
```swift
|
||||
var people = CoreStore.fetchAll(
|
||||
var people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 30) // Type-safe!
|
||||
)
|
||||
```
|
||||
`Where` clauses also implement the `&&`, `||`, and `!` logic operators, so you can provide logical conditions without writing too much `AND`, `OR`, and `NOT` strings:
|
||||
```swift
|
||||
var people = CoreStore.fetchAll(
|
||||
var people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 30 && \.gender == "M")
|
||||
)
|
||||
@@ -1251,7 +1192,7 @@ If you do not provide a `Where` clause, all objects that belong to the specified
|
||||
|
||||
The `OrderBy` clause is CoreStore's `NSSortDescriptor` wrapper. Use it to specify attribute keys in which to sort the fetch (or query) results with.
|
||||
```swift
|
||||
var mostValuablePeople = CoreStore.fetchAll(
|
||||
var mostValuablePeople = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>(),
|
||||
OrderBy<MyPersonEntity>(.descending("rating"), .ascending("surname"))
|
||||
)
|
||||
@@ -1259,7 +1200,7 @@ var mostValuablePeople = CoreStore.fetchAll(
|
||||
As seen above, `OrderBy` accepts a list of `SortKey` enumeration values, which can be either `.ascending` or `.descending`.
|
||||
⭐️As with `Where` clauses, CoreStore 5.0 turned `OrderBy` clauses into generic types. To avoid verbose repetition of the generic object type, fetch methods now support **Fetch Chain builders**. We can also use Swift's Smart KeyPaths as the `OrderBy` clause expression:
|
||||
```swift
|
||||
var people = CoreStore.fetchAll(
|
||||
var people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.orderBy(.descending(\.rating), .ascending(\.surname)) // Type-safe!
|
||||
)
|
||||
@@ -1271,7 +1212,7 @@ var orderBy = OrderBy<MyPersonEntity>(.descending(\.rating))
|
||||
if sortFromYoungest {
|
||||
orderBy += OrderBy(.ascending(\.age))
|
||||
}
|
||||
var mostValuablePeople = CoreStore.fetchAll(
|
||||
var mostValuablePeople = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>(),
|
||||
orderBy
|
||||
)
|
||||
@@ -1281,7 +1222,7 @@ var mostValuablePeople = CoreStore.fetchAll(
|
||||
|
||||
The `Tweak` clause lets you, uh, *tweak* the fetch (or query). `Tweak` exposes the `NSFetchRequest` in a closure where you can make changes to its properties:
|
||||
```swift
|
||||
var people = CoreStore.fetchAll(
|
||||
var people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>(),
|
||||
Where<MyPersonEntity>("age > %d", 30),
|
||||
OrderBy<MyPersonEntity>(.ascending("surname")),
|
||||
@@ -1294,7 +1235,7 @@ var people = CoreStore.fetchAll(
|
||||
```
|
||||
`Tweak` also supports **Fetch Chain builders**:
|
||||
```swift
|
||||
var people = CoreStore.fetchAll(
|
||||
var people = try CoreStore.fetchAll(
|
||||
From<MyPersonEntity>(),
|
||||
.where(\.age > 30)
|
||||
.orderBy(.ascending(\.surname))
|
||||
@@ -1325,7 +1266,7 @@ Setting up the `From`, `Where`, `OrderBy`, and `Tweak` clauses is similar to how
|
||||
|
||||
The `Select<T>` clause specifies the target attribute/aggregate key, as well as the expected return type:
|
||||
```swift
|
||||
let johnsAge = CoreStore.queryValue(
|
||||
let johnsAge = try CoreStore.queryValue(
|
||||
From<MyPersonEntity>(),
|
||||
Select<Int>("age"),
|
||||
Where("name == %@", "John Smith")
|
||||
@@ -1335,14 +1276,14 @@ The example above queries the "age" property for the first object that matches t
|
||||
|
||||
For `queryAttributes(...)`, only `NSDictionary` is valid for `Select`, thus you are allowed to omit the generic type:
|
||||
```swift
|
||||
let allAges = CoreStore.queryAttributes(
|
||||
let allAges = try CoreStore.queryAttributes(
|
||||
From<MyPersonEntity>(),
|
||||
Select("age")
|
||||
)
|
||||
```
|
||||
⭐️Starting CoreStore 5.0, query methods now support **Query Chain builders**. We can also use Swift's Smart KeyPaths to use in the expressions:
|
||||
```swift
|
||||
let johnsAge = CoreStore.queryValue(
|
||||
let johnsAge = try CoreStore.queryValue(
|
||||
From<MyPersonEntity>()
|
||||
.select(\.age) // binds the result to Int
|
||||
.where(\.name == "John Smith")
|
||||
@@ -1357,7 +1298,7 @@ If you only need a value for a particular attribute, you can just specify the ke
|
||||
- `.sum(...)`
|
||||
|
||||
```swift
|
||||
let oldestAge = CoreStore.queryValue(
|
||||
let oldestAge = try CoreStore.queryValue(
|
||||
From<MyPersonEntity>(),
|
||||
Select<Int>(.maximum("age"))
|
||||
)
|
||||
@@ -1365,7 +1306,7 @@ let oldestAge = CoreStore.queryValue(
|
||||
|
||||
For `queryAttributes(...)` which returns an array of dictionaries, you can specify multiple attributes/aggregates to `Select`:
|
||||
```swift
|
||||
let personJSON = CoreStore.queryAttributes(
|
||||
let personJSON = try CoreStore.queryAttributes(
|
||||
From<MyPersonEntity>(),
|
||||
Select("name", "age")
|
||||
)
|
||||
@@ -1385,7 +1326,7 @@ let personJSON = CoreStore.queryAttributes(
|
||||
```
|
||||
You can also include an aggregate as well:
|
||||
```swift
|
||||
let personJSON = CoreStore.queryAttributes(
|
||||
let personJSON = try CoreStore.queryAttributes(
|
||||
From<MyPersonEntity>(),
|
||||
Select("name", .count("friends"))
|
||||
)
|
||||
@@ -1405,7 +1346,7 @@ which returns:
|
||||
```
|
||||
The `"count(friends)"` key name was automatically used by CoreStore, but you can specify your own key alias if you need:
|
||||
```swift
|
||||
let personJSON = CoreStore.queryAttributes(
|
||||
let personJSON = try CoreStore.queryAttributes(
|
||||
From<MyPersonEntity>(),
|
||||
Select("name", .count("friends", as: "friendsCount"))
|
||||
)
|
||||
@@ -1428,7 +1369,7 @@ which now returns:
|
||||
|
||||
The `GroupBy` clause lets you group results by a specified attribute/aggregate. This is useful only for `queryAttributes(...)` since `queryValue(...)` just returns the first value.
|
||||
```swift
|
||||
let personJSON = CoreStore.queryAttributes(
|
||||
let personJSON = try CoreStore.queryAttributes(
|
||||
From<MyPersonEntity>(),
|
||||
Select("age", .count("age", as: "count")),
|
||||
GroupBy("age")
|
||||
@@ -1436,7 +1377,7 @@ let personJSON = CoreStore.queryAttributes(
|
||||
```
|
||||
⭐️Starting CoreStore 5.0, `GroupBy` clauses are now also generic types and now support **Query Chain builders**. We can also use Swift's Smart KeyPaths to use in the expressions:
|
||||
```swift
|
||||
let personJSON = CoreStore.queryAttributes(
|
||||
let personJSON = try CoreStore.queryAttributes(
|
||||
From<MyPersonEntity>()
|
||||
.select(.attribute(\.age), .count(\.age, as: "count"))
|
||||
.groupBy(\.age)
|
||||
@@ -1491,16 +1432,35 @@ A couple of examples, `ListMonitor`:
|
||||
These are all implemented with `CustomDebugStringConvertible.debugDescription`, so they work with lldb's `po` command as well.
|
||||
|
||||
## Observing changes and notifications
|
||||
> (unavailable on macOS versions below 10.12)
|
||||
|
||||
CoreStore provides type-safe wrappers for observing managed objects:
|
||||
|
||||
- `ObjectMonitor`: use to monitor changes to a single `NSManagedObject` or `CoreStoreObject` instance (instead of Key-Value Observing)
|
||||
- `ListMonitor`: use to monitor changes to a list of `NSManagedObject` or `CoreStoreObject` instances (instead of `NSFetchedResultsController`)
|
||||
|
||||
### Observe a single property
|
||||
To get notifications for single property changes in an object, there are two methods depending on the object's base class.
|
||||
|
||||
- For `NSManagedObject` subclasses: Use the standard KVO method:
|
||||
```swift
|
||||
let observer = person.observe(\.age, options: [.new]) { (person, change)
|
||||
print("Happy \(change.newValue)th birthday!")
|
||||
}
|
||||
```
|
||||
|
||||
- For `CoreStoreObject` subclasses: Call the `observe(...)` method directly on the property. You'll notice that the API itself is a bit similar to the KVO method:
|
||||
```swift
|
||||
let observer = person.age.observe(options: [.new]) { (person, change)
|
||||
print("Happy \(change.newValue)th birthday!")
|
||||
}
|
||||
```
|
||||
|
||||
For both methods, you will need to keep a reference to the returned `observer` for the duration of the observation.
|
||||
|
||||
|
||||
### Observe a single object
|
||||
|
||||
To observe an object, implement the `ObjectObserver` protocol and specify the `EntityType`:
|
||||
To observe an object itself as a whole, implement the `ObjectObserver` protocol and specify the `EntityType`:
|
||||
```swift
|
||||
class MyViewController: UIViewController, ObjectObserver {
|
||||
func objectMonitor(monitor: ObjectMonitor<MyPersonEntity>, willUpdateObject object: MyPersonEntity) {
|
||||
@@ -1654,14 +1614,13 @@ CoreStore.perform(
|
||||
<td><pre lang=objc>
|
||||
[CSCoreStore beginAsynchronous:^(CSAsynchronousDataTransaction *transaction) {
|
||||
// ...
|
||||
[transaction commitWithCompletion:^(CSSaveResult *result) {
|
||||
if (result.isSuccess) {
|
||||
NSLog(@"Done");
|
||||
}
|
||||
else if (result.isFailure) {
|
||||
NSLog(@"error: %@", result.error);
|
||||
}
|
||||
}];
|
||||
[transaction
|
||||
commitWithSuccess:^{
|
||||
NSLog(@"Done");
|
||||
}
|
||||
failure: ^(CSError *error) {
|
||||
NSLog(@"error: %@", result.error);
|
||||
}];
|
||||
}];
|
||||
</pre></td>
|
||||
</tr>
|
||||
@@ -1796,7 +1755,7 @@ let keyPath: String = Dog.keyPath { $0.nickname }
|
||||
```
|
||||
as well as `Where` and `OrderBy` clauses
|
||||
```swift
|
||||
let puppies = CoreStore.fetchAll(
|
||||
let puppies = try CoreStore.fetchAll(
|
||||
From<Dog>()
|
||||
.where(\.age < 1)
|
||||
.orderBy(.ascending(\.age))
|
||||
@@ -1841,8 +1800,9 @@ Once the version lock is set, any changes in the properties or to the model will
|
||||
|
||||
# Installation
|
||||
- Requires:
|
||||
- iOS 8 SDK and above
|
||||
- Swift 4 (Xcode 9+)
|
||||
- iOS 10 SDK and above
|
||||
- Swift 5.0 (Xcode 10+)
|
||||
- For previous 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)
|
||||
- Dependencies:
|
||||
- *None*
|
||||
- Other notes:
|
||||
@@ -1851,7 +1811,7 @@ Once the version lock is set, any changes in the properties or to the model will
|
||||
### Install with CocoaPods
|
||||
In your `Podfile`, add
|
||||
```
|
||||
pod 'CoreStore', '~> 5.0'
|
||||
pod 'CoreStore', '~> 6.3'
|
||||
```
|
||||
and run
|
||||
```
|
||||
@@ -1862,7 +1822,7 @@ This installs CoreStore as a framework. Declare `import CoreStore` in your swift
|
||||
### Install with Carthage
|
||||
In your `Cartfile`, add
|
||||
```
|
||||
github "JohnEstropia/CoreStore" >= 5.0.0
|
||||
github "JohnEstropia/CoreStore" >= 6.3.0
|
||||
```
|
||||
and run
|
||||
```
|
||||
@@ -1870,18 +1830,20 @@ carthage update
|
||||
```
|
||||
This installs CoreStore as a framework. Declare `import CoreStore` in your swift file to use the library.
|
||||
|
||||
#### Install with Swift Package Manager:
|
||||
```swift
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "6.3.0"))
|
||||
]
|
||||
```
|
||||
Declare `import CoreStore` in your swift file to use the library.
|
||||
|
||||
### Install as Git Submodule
|
||||
```
|
||||
git submodule add https://github.com/JohnEstropia/CoreStore.git <destination directory>
|
||||
```
|
||||
Drag and drop **CoreStore.xcodeproj** to your project.
|
||||
|
||||
#### To install as a framework:
|
||||
Drag and drop **CoreStore.xcodeproj** to your project.
|
||||
|
||||
#### To include directly in your app module:
|
||||
Add all *.swift* files to your project.
|
||||
|
||||
|
||||
### Objective-C support
|
||||
|
||||
|
||||
@@ -50,45 +50,11 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
// MARK: - Result
|
||||
|
||||
/**
|
||||
The `Result` contains the success or failure information for a completed transaction
|
||||
The `Result` contains the success or failure information for a completed transaction.
|
||||
`Result<T>.success` indicates that the transaction succeeded, either because the save succeeded or because there were no changes to save. The associated `userInfo` is the value returned from the transaction closure.
|
||||
`Result<T>.failure` indicates that the transaction either failed or was cancelled. The associated object for this value is a `CoreStoreError` enum value.
|
||||
*/
|
||||
public enum Result<T> {
|
||||
|
||||
/**
|
||||
`Result<T>.success` indicates that the transaction succeeded, either because the save succeeded or because there were no changes to save. The associated `userInfo` is the value returned from the transaction closure.
|
||||
*/
|
||||
case success(userInfo: T)
|
||||
|
||||
/**
|
||||
`Result<T>.failure` indicates that the transaction either failed or was cancelled. The associated object for this value is a `CoreStoreError` enum value.
|
||||
*/
|
||||
case failure(error: CoreStoreError)
|
||||
|
||||
/**
|
||||
Returns `true` if the result indicates `.success`, `false` if the result is `.failure`.
|
||||
*/
|
||||
public var boolValue: Bool {
|
||||
|
||||
switch self {
|
||||
|
||||
case .success: return true
|
||||
case .failure: return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal init(userInfo: T) {
|
||||
|
||||
self = .success(userInfo: userInfo)
|
||||
}
|
||||
|
||||
internal init(error: CoreStoreError) {
|
||||
|
||||
self = .failure(error: error)
|
||||
}
|
||||
}
|
||||
public typealias Result<UserInfoType> = Swift.Result<UserInfoType, CoreStoreError>
|
||||
|
||||
// MARK: -
|
||||
|
||||
@@ -212,67 +178,4 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
group.wait()
|
||||
self.context.reset()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new auto-commiting methods `DataStack.perform(asynchronous:completion:)` or `DataStack.perform(asynchronous:success:failure:)`. Please read the documentation on the behavior of the new methods.")
|
||||
public func commit(_ completion: @escaping (_ result: SaveResult) -> Void = { _ in }) {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to commit a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to commit a \(cs_typeName(self)) more than once."
|
||||
)
|
||||
self.autoCommit { (hasChanges, error) in
|
||||
|
||||
if let error = error {
|
||||
|
||||
completion(SaveResult(error))
|
||||
}
|
||||
else {
|
||||
|
||||
completion(SaveResult(hasChanges: hasChanges))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Secondary tasks spawned from AsynchronousDataTransactions and SynchronousDataTransactions are no longer supported. ")
|
||||
@discardableResult
|
||||
public func beginSynchronous(_ closure: @escaping (_ transaction: SynchronousDataTransaction) -> Void) -> SaveResult? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to begin a child transaction from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to begin a child transaction from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
let childTransaction = SynchronousDataTransaction(
|
||||
mainContext: self.context,
|
||||
queue: self.childTransactionQueue
|
||||
)
|
||||
childTransaction.transactionQueue.cs_sync {
|
||||
|
||||
closure(childTransaction)
|
||||
|
||||
if !childTransaction.isCommitted && childTransaction.hasChanges {
|
||||
|
||||
CoreStore.log(
|
||||
.warning,
|
||||
message: "The closure for the \(cs_typeName(childTransaction)) completed without being committed. All changes made within the transaction were discarded."
|
||||
)
|
||||
}
|
||||
}
|
||||
switch childTransaction.result {
|
||||
|
||||
case .none: return nil
|
||||
case .some(let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
|
||||
case .some(_, let error?): return SaveResult(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - BaseDataTransaction
|
||||
|
||||
public extension BaseDataTransaction {
|
||||
extension BaseDataTransaction {
|
||||
|
||||
/**
|
||||
Creates an `ImportableObject` by importing from the specified import source.
|
||||
|
||||
@@ -561,13 +561,4 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
|
||||
return self.context
|
||||
}
|
||||
|
||||
|
||||
// MARK: Obsoleted
|
||||
|
||||
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
|
||||
public func internalContext() -> NSManagedObjectContext {
|
||||
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,49 +442,4 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
|
||||
self.context.reset()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use insertedObjects(_:) and pass the specific entity type")
|
||||
public func insertedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to access inserted objects from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return self.context.insertedObjects
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use updatedObjects(_:) and pass the specific entity type")
|
||||
public func updatedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to access updated objects from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return self.context.updatedObjects
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use deletedObjects(_:) and pass the specific entity type")
|
||||
public func deletedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to access deleted objects from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return self.context.deletedObjects
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,41 +156,6 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction, CoreSto
|
||||
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new -[CSAsynchronousDataTransaction commitWithSuccess:failure:] method.")
|
||||
@objc
|
||||
public func commitWithCompletion(_ completion: ((_ result: CSSaveResult) -> Void)?) {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to commit a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.bridgeToSwift.isCommitted,
|
||||
"Attempted to commit a \(cs_typeName(self)) more than once."
|
||||
)
|
||||
self.bridgeToSwift.commit { (result) in
|
||||
|
||||
completion?(result.bridgeToObjectiveC)
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Secondary tasks spawned from CSAsynchronousDataTransactions and CSSynchronousDataTransactions are no longer supported. ")
|
||||
@objc
|
||||
@discardableResult
|
||||
public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
||||
|
||||
return bridge {
|
||||
|
||||
self.bridgeToSwift.beginSynchronous { (transaction) in
|
||||
|
||||
closure(transaction.bridgeToObjectiveC)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CSBaseDataTransaction
|
||||
|
||||
public extension CSBaseDataTransaction {
|
||||
extension CSBaseDataTransaction {
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
|
||||
|
||||
@@ -251,28 +251,4 @@ public class CSBaseDataTransaction: NSObject {
|
||||
self.swiftTransaction = swiftValue
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use -[insertedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func insertedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.swiftTransaction.insertedObjects()
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use -[updatedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func updatedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.swiftTransaction.updatedObjects()
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use -[deletedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func deletedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.swiftTransaction.deletedObjects()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CSCoreStore
|
||||
|
||||
public extension CSCoreStore {
|
||||
extension CSCoreStore {
|
||||
|
||||
/**
|
||||
Asynchronously adds a `CSInMemoryStore` to the `defaultStack`. Migrations are also initiated by default.
|
||||
|
||||
@@ -30,7 +30,7 @@ import CoreData
|
||||
// MARK: - CSCoreStore
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
public extension CSCoreStore {
|
||||
extension CSCoreStore {
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, creates an `CSObjectMonitor` for the specified `NSManagedObject`. Multiple `CSObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CSCoreStore
|
||||
|
||||
public extension CSCoreStore {
|
||||
extension CSCoreStore {
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CSCoreStore
|
||||
|
||||
public extension CSCoreStore {
|
||||
extension CSCoreStore {
|
||||
|
||||
/**
|
||||
Returns the `defaultStack`'s model version. The version string is the same as the name of the version-specific .xcdatamodeld file.
|
||||
@@ -125,21 +125,4 @@ public extension CSCoreStore {
|
||||
|
||||
return self.defaultStack.addSQLiteStorageAndWait(storage, error: error)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new +entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public static var entityClassesByName: [EntityName: NSManagedObject.Type] {
|
||||
|
||||
return CoreStore.entityTypesByName
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new +entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public static func entityClassWithName(_ name: EntityName) -> NSManagedObject.Type? {
|
||||
|
||||
return CoreStore.entityTypesByName[name]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import Foundation
|
||||
|
||||
// MARK: - CSCoreStore
|
||||
|
||||
public extension CSCoreStore {
|
||||
extension CSCoreStore {
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
@@ -45,7 +45,7 @@ public extension CSCoreStore {
|
||||
Using the `defaultStack`, begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
|
||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- returns: a `CSSaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
||||
- returns: `YES` if the commit succeeded, `NO` if the commit failed. If `NO`, the `error` argument will hold error information.
|
||||
*/
|
||||
@objc
|
||||
public static func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void, error: NSErrorPointer) -> Bool {
|
||||
@@ -91,15 +91,4 @@ public extension CSCoreStore {
|
||||
|
||||
CoreStore.refreshAndMergeAllObjects()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new +[CSCoreStore beginSynchronous:error:] API that reports failure using an error instance.")
|
||||
@objc
|
||||
@discardableResult
|
||||
public static func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
||||
|
||||
return self.defaultStack.beginSynchronous(closure)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CSDataStack
|
||||
|
||||
public extension CSDataStack {
|
||||
extension CSDataStack {
|
||||
|
||||
/**
|
||||
Asynchronously adds a `CSInMemoryStore` to the stack. Migrations are also initiated by default.
|
||||
|
||||
@@ -30,7 +30,7 @@ import CoreData
|
||||
// MARK: - CSDataStack
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
public extension CSDataStack {
|
||||
extension CSDataStack {
|
||||
|
||||
/**
|
||||
Creates a `CSObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
|
||||
@@ -68,7 +68,7 @@ public extension CSDataStack {
|
||||
sectionBy: nil,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
}
|
||||
).bridgeToObjectiveC
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public extension CSDataStack {
|
||||
sectionBy: nil,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
},
|
||||
createAsynchronously: {
|
||||
|
||||
@@ -131,7 +131,7 @@ public extension CSDataStack {
|
||||
sectionBy: sectionBy.bridgeToSwift,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
}
|
||||
).bridgeToObjectiveC
|
||||
}
|
||||
@@ -160,7 +160,7 @@ public extension CSDataStack {
|
||||
sectionBy: sectionBy.bridgeToSwift,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
},
|
||||
createAsynchronously: {
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CSDataStack
|
||||
|
||||
public extension CSDataStack {
|
||||
extension CSDataStack {
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
|
||||
|
||||
@@ -28,7 +28,7 @@ import Foundation
|
||||
|
||||
// MARK: - CSDataStack
|
||||
|
||||
public extension CSDataStack {
|
||||
extension CSDataStack {
|
||||
|
||||
/**
|
||||
Begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
@@ -131,21 +131,4 @@ public extension CSDataStack {
|
||||
|
||||
self.bridgeToSwift.refreshAndMergeAllObjects()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new -[CSDataStack beginSynchronous:error:] API that reports failure using an error instance.")
|
||||
@objc
|
||||
@discardableResult
|
||||
public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
||||
|
||||
return bridge {
|
||||
|
||||
self.bridgeToSwift.beginSynchronous { (transaction) in
|
||||
|
||||
closure(transaction.bridgeToObjectiveC)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,60 +204,6 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
||||
self.bridgeToSwift = swiftValue
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the -[initWithXcodeModelName:bundle:versionChain:] initializer.")
|
||||
@objc
|
||||
public convenience init(modelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
xcodeModelName: modelName ?? DataStack.applicationName,
|
||||
bundle: bundle ?? Bundle.main,
|
||||
migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the -[initWithModelName:bundle:versionChain:] initializer.")
|
||||
@objc
|
||||
public convenience init(model: NSManagedObjectModel, versionChain: [String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
model: model,
|
||||
migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the -[initWithModelName:bundle:versionTree:] initializer.")
|
||||
@objc
|
||||
public convenience init(model: NSManagedObjectModel, versionTree: [String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
model: model,
|
||||
migrationChain: versionTree.flatMap { MigrationChain($0) } ?? nil
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new -entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public var entityClassesByName: [EntityName: NSManagedObject.Type] {
|
||||
|
||||
return self.bridgeToSwift.entityTypesByName
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new -entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public func entityClassWithName(_ name: EntityName) -> NSManagedObject.Type? {
|
||||
|
||||
return self.bridgeToSwift.entityTypesByName[name]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ extension CoreStoreError: CoreStoreSwiftType, _ObjectiveCBridgeableError {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal extension Error {
|
||||
extension Error {
|
||||
|
||||
internal var bridgeToSwift: CoreStoreError {
|
||||
|
||||
|
||||
@@ -495,14 +495,15 @@ public final class CSListMonitor: NSObject {
|
||||
|
||||
`refetch(...)` broadcasts `listMonitorWillRefetch(...)` to its observers immediately, and then `listMonitorDidRefetch(...)` after the new fetch request completes.
|
||||
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses. Note that only specified clauses will be changed; unspecified clauses will use previous values.
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- Important: Starting CoreStore 4.0, all `CSFetchClause`s required by the `CSListMonitor` should be provided in the arguments list of `refetch(...)`.
|
||||
*/
|
||||
@objc
|
||||
public func refetch(_ fetchClauses: [CSFetchClause]) {
|
||||
|
||||
self.bridgeToSwift.refetch { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public var isSuccess: Bool {
|
||||
|
||||
return self.bridgeToSwift.isSuccess
|
||||
return (try? self.bridgeToSwift.get()) != nil
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public var isFailure: Bool {
|
||||
|
||||
return !self.bridgeToSwift.isSuccess
|
||||
return !self.isSuccess
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -173,7 +173,7 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: - MigrationResult
|
||||
|
||||
extension MigrationResult: CoreStoreSwiftType {
|
||||
extension MigrationResult {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
|
||||
@@ -191,23 +191,6 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
||||
self.bridgeToSwift = swiftValue
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Obsoleted
|
||||
|
||||
@available(*, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileURL:configuration:localStorageOptions:]) initializer instead.")
|
||||
@objc
|
||||
public convenience init(fileURL: URL, configuration: ModelConfiguration, mappingModelBundles: [Bundle]?, localStorageOptions: Int) {
|
||||
|
||||
fatalError()
|
||||
}
|
||||
|
||||
@available(*, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileName:configuration:localStorageOptions:]) initializer instead.")
|
||||
@objc
|
||||
public convenience init(fileName: String, configuration: ModelConfiguration, mappingModelBundles: [Bundle]?, localStorageOptions: Int) {
|
||||
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
//
|
||||
// CSSaveResult.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: - CSSaveResult
|
||||
|
||||
@available(*, deprecated, message: "Use APIs that report failures with `CSError`s instead.")
|
||||
@objc
|
||||
public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
@objc
|
||||
public var isSuccess: Bool {
|
||||
|
||||
return self.bridgeToSwift.boolValue
|
||||
}
|
||||
|
||||
@objc
|
||||
public var isFailure: Bool {
|
||||
|
||||
return !self.bridgeToSwift.boolValue
|
||||
}
|
||||
|
||||
@objc
|
||||
public var hasChanges: Bool {
|
||||
|
||||
guard case .success(let hasChanges) = self.bridgeToSwift else {
|
||||
|
||||
return false
|
||||
}
|
||||
return hasChanges
|
||||
}
|
||||
|
||||
@objc
|
||||
public var error: NSError? {
|
||||
|
||||
guard case .failure(let error) = self.bridgeToSwift else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return error.bridgeToObjectiveC
|
||||
}
|
||||
|
||||
@objc
|
||||
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void, failure: (_ error: NSError) -> Void) {
|
||||
|
||||
switch self.bridgeToSwift {
|
||||
|
||||
case .success(let hasChanges):
|
||||
success(hasChanges)
|
||||
|
||||
case .failure(let error):
|
||||
failure(error.bridgeToObjectiveC)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void) {
|
||||
|
||||
guard case .success(let hasChanges) = self.bridgeToSwift else {
|
||||
|
||||
return
|
||||
}
|
||||
success(hasChanges)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func handleFailure(_ failure: (_ error: NSError) -> Void) {
|
||||
|
||||
guard case .failure(let error) = self.bridgeToSwift else {
|
||||
|
||||
return
|
||||
}
|
||||
failure(error.bridgeToObjectiveC)
|
||||
}
|
||||
|
||||
|
||||
// MARK: NSObject
|
||||
|
||||
public override var hash: Int {
|
||||
|
||||
return self.bridgeToSwift.hashValue
|
||||
}
|
||||
|
||||
public override func isEqual(_ object: Any?) -> Bool {
|
||||
|
||||
guard let object = object as? CSSaveResult else {
|
||||
|
||||
return false
|
||||
}
|
||||
return self.bridgeToSwift == object.bridgeToSwift
|
||||
}
|
||||
|
||||
public override var description: String {
|
||||
|
||||
return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: SaveResult
|
||||
|
||||
public required init(_ swiftValue: SaveResult) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - SaveResult
|
||||
|
||||
@available(*, deprecated, message: "Use the new DataStack.perform(asynchronous:...) and DataStack.perform(synchronous:...) family of APIs")
|
||||
extension SaveResult: CoreStoreSwiftType {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
public var bridgeToObjectiveC: CSSaveResult {
|
||||
|
||||
return CSSaveResult(self)
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,7 @@ public final class CSSetupResult: NSObject {
|
||||
|
||||
// MARK: - SetupResult
|
||||
|
||||
extension SetupResult where T: CoreStoreSwiftType, T.ObjectiveCType: CSStorageInterface {
|
||||
extension SetupResult where Success: StorageInterface, Success: CoreStoreSwiftType, Success.ObjectiveCType: CSStorageInterface, Failure == CoreStoreError {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
|
||||
@@ -143,33 +143,6 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction, CoreStor
|
||||
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new -[CSSynchronousDataTransaction commitAndWaitWithError:] method")
|
||||
@objc
|
||||
public func commitAndWait() -> CSSaveResult {
|
||||
|
||||
return bridge {
|
||||
|
||||
self.bridgeToSwift.commitAndWait()
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Secondary tasks spawned from CSAsynchronousDataTransactions and CSSynchronousDataTransactions are no longer supported. ")
|
||||
@objc
|
||||
@discardableResult
|
||||
public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
||||
|
||||
return bridge {
|
||||
|
||||
self.bridgeToSwift.beginSynchronous { (transaction) in
|
||||
|
||||
closure(transaction.bridgeToObjectiveC)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -203,51 +203,6 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction, CoreStoreObje
|
||||
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, renamed: "unsafeContext()")
|
||||
@objc
|
||||
public var internalContext: NSManagedObjectContext {
|
||||
|
||||
return self.bridgeToSwift.context
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new -[CSUnsafeDataTransaction commitWithSuccess:failure:] method")
|
||||
@objc
|
||||
public func commit(_ completion: ((_ result: CSSaveResult) -> Void)?) {
|
||||
|
||||
self.bridgeToSwift.context.saveAsynchronouslyWithCompletion { (hasChanges, error) in
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
if let error = error {
|
||||
|
||||
completion?(SaveResult(error).bridgeToObjectiveC)
|
||||
}
|
||||
else {
|
||||
|
||||
completion?(SaveResult(hasChanges: hasChanges).bridgeToObjectiveC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new -[CSUnsafeDataTransaction commitAndWaitWithError:] method")
|
||||
@objc
|
||||
public func commitAndWait() -> CSSaveResult {
|
||||
|
||||
return bridge { () -> SaveResult in
|
||||
|
||||
switch self.bridgeToSwift.context.saveSynchronously(waitForMerge: true) {
|
||||
|
||||
case (let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
|
||||
case (_, let error?): return SaveResult(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -403,9 +403,16 @@ extension UnsafeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStr
|
||||
// MARK: - ListMonitor
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertible {
|
||||
fileprivate struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertible {
|
||||
|
||||
let sectionInfo: NSFetchedResultsSectionInfo
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
// MARK: CoreStoreDebugStringConvertible
|
||||
|
||||
var coreStoreDumpString: String {
|
||||
|
||||
@@ -415,6 +422,10 @@ private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertib
|
||||
("indexTitle", self.sectionInfo.indexTitle as Any)
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
let sectionInfo: NSFetchedResultsSectionInfo
|
||||
}
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
@@ -546,41 +557,7 @@ extension MigrationChain: CustomDebugStringConvertible, CoreStoreDebugStringConv
|
||||
|
||||
// MARK: - MigrationType
|
||||
|
||||
extension MigrationResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreDebugStringConvertible
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
switch self {
|
||||
|
||||
case .success(let migrationTypes):
|
||||
return createFormattedString(
|
||||
".success (", ")",
|
||||
("migrationTypes", migrationTypes)
|
||||
)
|
||||
|
||||
case .failure(let error):
|
||||
return createFormattedString(
|
||||
".failure (", ")",
|
||||
("error", error)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - MigrationType
|
||||
|
||||
extension MigrationType: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
extension MigrationType: CoreStoreDebugStringConvertible {
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
@@ -683,41 +660,6 @@ extension PartialObject: CustomDebugStringConvertible, CoreStoreDebugStringConve
|
||||
}
|
||||
|
||||
|
||||
// MARK: - SaveResult
|
||||
|
||||
@available(*, deprecated, message: "Use the new DataStack.perform(asynchronous:...) and DataStack.perform(synchronous:...) family of APIs")
|
||||
extension SaveResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreDebugStringConvertible
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
switch self {
|
||||
|
||||
case .success(let hasChanges):
|
||||
return createFormattedString(
|
||||
".success (", ")",
|
||||
("hasChanges", hasChanges)
|
||||
)
|
||||
|
||||
case .failure(let error):
|
||||
return createFormattedString(
|
||||
".failure (", ")",
|
||||
("error", error)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - SectionBy
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
@@ -837,40 +779,6 @@ extension SelectTerm: CustomDebugStringConvertible, CoreStoreDebugStringConverti
|
||||
}
|
||||
|
||||
|
||||
// MARK: - SetupResult
|
||||
|
||||
extension SetupResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreDebugStringConvertible
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
switch self {
|
||||
|
||||
case .success(let storage):
|
||||
return createFormattedString(
|
||||
".success (", ")",
|
||||
("storage", storage)
|
||||
)
|
||||
|
||||
case .failure(let error):
|
||||
return createFormattedString(
|
||||
".failure (", ")",
|
||||
("error", error)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - SQLiteStore
|
||||
|
||||
extension SQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
@@ -1014,11 +922,11 @@ extension VersionLock: CustomStringConvertible, CustomDebugStringConvertible, Co
|
||||
for (index, keyValue) in self.hashesByEntityName.sorted(by: { $0.key < $1.key }).enumerated() {
|
||||
|
||||
let data = keyValue.value
|
||||
let count = data.count
|
||||
let bytes = data.withUnsafeBytes { (pointer: UnsafePointer<HashElement>) in
|
||||
let bytes = data.withUnsafeBytes { (pointer) in
|
||||
|
||||
return (0 ..< (count / MemoryLayout<HashElement>.size))
|
||||
.map({ "\("0x\(String(pointer[$0], radix: 16, uppercase: false))")" })
|
||||
return pointer
|
||||
.bindMemory(to: VersionLock.HashElement.self)
|
||||
.map({ "\("0x\(String($0, radix: 16, uppercase: false))")" })
|
||||
}
|
||||
string.append("\(index == 0 ? "\n" : ",\n")\"\(keyValue.key)\": [\(bytes.joined(separator: ", "))]")
|
||||
}
|
||||
@@ -1111,7 +1019,7 @@ private func createFormattedString(_ firstLine: String, _ lastLine: String, _ in
|
||||
return string
|
||||
}
|
||||
|
||||
fileprivate extension String {
|
||||
extension String {
|
||||
|
||||
fileprivate static func indention(_ level: Int = 1) -> String {
|
||||
|
||||
@@ -1132,7 +1040,7 @@ fileprivate extension String {
|
||||
|
||||
// MARK: - Private: CoreStoreDebugStringConvertible
|
||||
|
||||
public protocol CoreStoreDebugStringConvertible {
|
||||
public protocol CoreStoreDebugStringConvertible: CustomDebugStringConvertible {
|
||||
|
||||
var coreStoreDumpString: String { get }
|
||||
}
|
||||
@@ -1213,6 +1121,11 @@ extension NSAttributeDescription: CoreStoreDebugStringConvertible {
|
||||
|
||||
extension NSAttributeType: CoreStoreDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
switch self {
|
||||
@@ -1232,6 +1145,8 @@ extension NSAttributeType: CoreStoreDebugStringConvertible {
|
||||
case .objectIDAttributeType: return ".objectIDAttributeType"
|
||||
case .UUIDAttributeType: return ".UUIDAttributeType"
|
||||
case .URIAttributeType: return ".URIAttributeType"
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1246,6 +1161,11 @@ extension Bundle: CoreStoreDebugStringConvertible {
|
||||
|
||||
extension NSDeleteRule: CoreStoreDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
switch self {
|
||||
@@ -1254,6 +1174,8 @@ extension NSDeleteRule: CoreStoreDebugStringConvertible {
|
||||
case .nullifyDeleteRule: return ".nullifyDeleteRule"
|
||||
case .cascadeDeleteRule: return ".cascadeDeleteRule"
|
||||
case .denyDeleteRule: return ".denyDeleteRule"
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1282,7 +1204,10 @@ extension NSEntityDescription: CoreStoreDebugStringConvertible {
|
||||
|
||||
info.append(("compoundIndexes", self.compoundIndexes))
|
||||
}
|
||||
info.append(("uniquenessConstraints", self.uniquenessConstraints))
|
||||
if #available(macOS 10.11, *) {
|
||||
|
||||
info.append(("uniquenessConstraints", self.uniquenessConstraints))
|
||||
}
|
||||
return createFormattedString(
|
||||
"(", ")",
|
||||
info
|
||||
@@ -1413,8 +1338,39 @@ extension Optional: CoreStoreDebugStringConvertible {
|
||||
}
|
||||
}
|
||||
|
||||
extension Result: CoreStoreDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
switch self {
|
||||
|
||||
case .success(let info):
|
||||
return createFormattedString(
|
||||
".success (", ")",
|
||||
("info", info)
|
||||
)
|
||||
|
||||
case .failure(let error):
|
||||
return createFormattedString(
|
||||
".failure (", ")",
|
||||
("error", error)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Selector: CoreStoreDebugStringConvertible {
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
return formattedDebugDescription(self)
|
||||
}
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
return "\"\(self)\""
|
||||
|
||||
@@ -28,7 +28,7 @@ import Foundation
|
||||
|
||||
// MARK: - CoreStore
|
||||
|
||||
public extension CoreStore {
|
||||
extension CoreStore {
|
||||
|
||||
/**
|
||||
The `CoreStoreLogger` instance to be used. The default logger is an instance of a `DefaultLogger`.
|
||||
@@ -66,8 +66,8 @@ public extension CoreStore {
|
||||
internal static func assert( _ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
|
||||
|
||||
self.logger.assert(
|
||||
condition,
|
||||
message: message,
|
||||
condition(),
|
||||
message: message(),
|
||||
fileName: fileName,
|
||||
lineNumber: lineNumber,
|
||||
functionName: functionName
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CoreStore
|
||||
|
||||
public extension CoreStore {
|
||||
extension CoreStore {
|
||||
|
||||
/**
|
||||
Asynchronously adds a `StorageInterface` to the `defaultStack`. Migrations are also initiated by default.
|
||||
|
||||
@@ -30,7 +30,7 @@ import CoreData
|
||||
// MARK: - CoreStore
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
public extension CoreStore {
|
||||
extension CoreStore {
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, creates an `ObjectMonitor` for the specified `DynamicObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `DynamicObject`.
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CoreStore
|
||||
|
||||
public extension CoreStore {
|
||||
extension CoreStore {
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, fetches the `DynamicObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CoreStore
|
||||
|
||||
public extension CoreStore {
|
||||
extension CoreStore {
|
||||
|
||||
/**
|
||||
Returns the `defaultStack`'s model version. The version string is the same as the name of a version-specific .xcdatamodeld file or `CoreStoreSchema`.
|
||||
@@ -139,22 +139,4 @@ public extension CoreStore {
|
||||
|
||||
return try self.defaultStack.addStorageAndWait(storage)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new CoreStore.entityTypesByName(for:) method passing `NSManagedObject.self` as argument.")
|
||||
public static var entityTypesByName: [EntityName: NSManagedObject.Type] {
|
||||
|
||||
return self.defaultStack.entityTypesByName
|
||||
}
|
||||
|
||||
|
||||
// MARK: Obsolete
|
||||
|
||||
@available(*, obsoleted: 3.1, renamed: "entityDescription(for:)")
|
||||
public static func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
|
||||
|
||||
return self.entityDescription(for: type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ import Foundation
|
||||
|
||||
// MARK: - CoreStore
|
||||
|
||||
public extension CoreStore {
|
||||
extension CoreStore {
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
|
||||
- parameter task: the asynchronous closure where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- parameter completion: the closure executed after the save completes. The `Result` argument of the closure will either wrap the return value of `task`, or any uncaught errors thrown from within `task`. Cancelled `task`s will be indicated by `.failure(error: CoreStoreError.userCancelled)`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||
@@ -84,20 +84,4 @@ public extension CoreStore {
|
||||
|
||||
self.defaultStack.refreshAndMergeAllObjects()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new auto-commiting methods `perform(asynchronous:completion:)` or `perform(asynchronous:success:failure:)`. Please read the documentation on the behavior of the new methods.")
|
||||
public static func beginAsynchronous(_ closure: @escaping (_ transaction: AsynchronousDataTransaction) -> Void) {
|
||||
|
||||
self.defaultStack.beginAsynchronous(closure)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new auto-commiting method `perform(synchronous:)`. Please read the documentation on the behavior of the new methods.")
|
||||
@discardableResult
|
||||
public static func beginSynchronous(_ closure: @escaping (_ transaction: SynchronousDataTransaction) -> Void) -> SaveResult? {
|
||||
|
||||
return self.defaultStack.beginSynchronous(closure)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,16 +564,4 @@ CORESTORE_EXTERN
|
||||
CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RETURNS_RETAINED;
|
||||
|
||||
|
||||
#pragma mark CoreStoreFetchRequest
|
||||
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
NS_SWIFT_NAME(CoreStoreFetchRequest)
|
||||
@interface _CSFetchRequest: NSFetchRequest
|
||||
|
||||
@property (nullable, nonatomic, copy, readonly) NSArray<NSPersistentStore *> *safeAffectedStores;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#endif /* CoreStoreBridge_h */
|
||||
|
||||
@@ -218,40 +218,3 @@ CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RE
|
||||
|
||||
return [[CSWhere alloc] initWithPredicate:predicate];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark CoreStoreFetchRequest
|
||||
|
||||
@interface _CSFetchRequest ()
|
||||
|
||||
@property (nullable, nonatomic, copy) NSArray<NSPersistentStore *> *safeAffectedStores;
|
||||
@property (nullable, nonatomic, assign) CFArrayRef releaseArray;
|
||||
|
||||
@end
|
||||
|
||||
@implementation _CSFetchRequest
|
||||
|
||||
// MARK: NSFetchRequest
|
||||
|
||||
- (void)setAffectedStores:(NSArray<NSPersistentStore *> *_Nullable)affectedStores {
|
||||
|
||||
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0
|
||||
|| [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){ 11, 0, 0 }]) {
|
||||
|
||||
self.safeAffectedStores = affectedStores;
|
||||
[super setAffectedStores:affectedStores];
|
||||
return;
|
||||
}
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
if (self.releaseArray != NULL) {
|
||||
|
||||
CFRelease(self.releaseArray);
|
||||
self.releaseArray = NULL;
|
||||
}
|
||||
self.safeAffectedStores = affectedStores;
|
||||
[super setAffectedStores:affectedStores];
|
||||
self.releaseArray = CFBridgingRetain([super affectedStores]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -332,7 +332,7 @@ public enum CoreStoreErrorCode: Int {
|
||||
|
||||
// MARK: - NSError
|
||||
|
||||
internal extension NSError {
|
||||
extension NSError {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
//
|
||||
// CoreStoreFetchRequest+CoreStore.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: - CoreStoreFetchRequest
|
||||
|
||||
internal extension CoreStoreFetchRequest {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal func dynamicCast<U>() -> NSFetchRequest<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||
}
|
||||
}
|
||||
91
Sources/CoreStoreFetchRequest.swift
Normal file
91
Sources/CoreStoreFetchRequest.swift
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// CoreStoreFetchRequest.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2019 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
|
||||
import ObjectiveC
|
||||
|
||||
|
||||
// MARK: - CoreStoreFetchRequest
|
||||
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
internal final class CoreStoreFetchRequest<T: NSFetchRequestResult>: NSFetchRequest<NSFetchRequestResult> {
|
||||
|
||||
@nonobjc
|
||||
internal func safeAffectedStores() -> [NSPersistentStore]? {
|
||||
|
||||
return self.copiedAffectedStores as! [NSPersistentStore]?
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal func staticCast() -> NSFetchRequest<T> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<T>.self)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal func dynamicCast<U>() -> NSFetchRequest<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: NSFetchRequest
|
||||
|
||||
@objc dynamic
|
||||
override var affectedStores: [NSPersistentStore]? {
|
||||
|
||||
get {
|
||||
|
||||
return super.affectedStores
|
||||
}
|
||||
set {
|
||||
|
||||
if #available(iOS 11.0, macOS 10.13, watchOS 4.0, tvOS 11.0, *) {
|
||||
|
||||
self.copiedAffectedStores = (newValue as NSArray?)?.copy() as! NSArray?
|
||||
super.affectedStores = newValue
|
||||
return
|
||||
}
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
if let releaseArray = self.releaseArray {
|
||||
|
||||
releaseArray.release()
|
||||
self.releaseArray = nil
|
||||
}
|
||||
self.copiedAffectedStores = (newValue as NSArray?)?.copy() as! NSArray?
|
||||
super.affectedStores = newValue
|
||||
self.releaseArray = (super.affectedStores as NSArray?).map(Unmanaged<NSArray>.passRetained(_:))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var copiedAffectedStores: NSArray?
|
||||
private var releaseArray: Unmanaged<NSArray>?
|
||||
}
|
||||
@@ -33,10 +33,13 @@ import CoreData
|
||||
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController<NSManagedObject> {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal let typedFetchRequest: CoreStoreFetchRequest<NSManagedObject>
|
||||
|
||||
@nonobjc
|
||||
internal convenience init<D>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
internal convenience init<D>(dataStack: DataStack, fetchRequest: CoreStoreFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
fetchRequest: fetchRequest,
|
||||
@@ -47,7 +50,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal init<D>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal init<D>(context: NSManagedObjectContext, fetchRequest: CoreStoreFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
_ = try? from.applyToFetchRequest(
|
||||
fetchRequest,
|
||||
@@ -55,14 +58,15 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
applyAffectedStores: false
|
||||
)
|
||||
applyFetchClauses(fetchRequest)
|
||||
|
||||
|
||||
self.typedFetchRequest = fetchRequest
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
try from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
|
||||
super.init(
|
||||
fetchRequest: fetchRequest,
|
||||
fetchRequest: fetchRequest.staticCast(),
|
||||
managedObjectContext: context,
|
||||
sectionNameKeyPath: sectionBy?.sectionKeyPath,
|
||||
cacheName: nil
|
||||
@@ -72,7 +76,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
@nonobjc
|
||||
internal func performFetchFromSpecifiedStores() throws {
|
||||
|
||||
try self.reapplyAffectedStores(self.fetchRequest, self.managedObjectContext)
|
||||
try self.reapplyAffectedStores(self.typedFetchRequest, self.managedObjectContext)
|
||||
try self.performFetch()
|
||||
}
|
||||
|
||||
@@ -91,5 +95,5 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
// MARK: Private
|
||||
|
||||
@nonobjc
|
||||
private let reapplyAffectedStores: (_ fetchRequest: NSFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) throws -> Void
|
||||
private let reapplyAffectedStores: (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) throws -> Void
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - CoreStoreObject
|
||||
|
||||
public extension CoreStoreObject {
|
||||
extension CoreStoreObject {
|
||||
|
||||
/**
|
||||
Exposes a `FetchableSource` that can fetch sibling objects of this `CoreStoreObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated.
|
||||
|
||||
@@ -29,7 +29,7 @@ import Foundation
|
||||
|
||||
// MARK: - ValueContainer.Required
|
||||
|
||||
public extension ValueContainer.Required {
|
||||
extension ValueContainer.Required {
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
@@ -112,7 +112,7 @@ public extension ValueContainer.Required {
|
||||
|
||||
// MARK: - ValueContainer.Optional
|
||||
|
||||
public extension ValueContainer.Optional {
|
||||
extension ValueContainer.Optional {
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
@@ -223,7 +223,7 @@ public extension ValueContainer.Optional {
|
||||
|
||||
// MARK: - RelationshipContainer.ToOne
|
||||
|
||||
public extension RelationshipContainer.ToOne {
|
||||
extension RelationshipContainer.ToOne {
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
@@ -258,69 +258,3 @@ public extension RelationshipContainer.ToOne {
|
||||
return Where(relationship.keyPath, isMemberOf: sequence)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.name)")
|
||||
public static func keyPath<O, V>(_ attribute: (Self) -> ValueContainer<O>.Required<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.name)")
|
||||
public static func keyPath<O, V>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.friend)")
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToOne<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.friends)")
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToManyOrdered<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.friends)")
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToManyUnordered<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the Where<DynamicObject>(_:) initializer that accepts the same closure argument")
|
||||
public static func `where`(_ condition: (Self) -> Where<Self>) -> Where<Self> {
|
||||
|
||||
return condition(self.meta)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(ascending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(ascending attribute: (Self) -> ValueContainer<O>.Required<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(ascending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(ascending attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(descending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(descending attribute: (Self) -> ValueContainer<O>.Required<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(descending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(descending attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
|
||||
// MARK: - DynamicObject where Self: CoreStoreObject
|
||||
|
||||
public extension DynamicObject where Self: CoreStoreObject {
|
||||
extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Returns the `PartialObject` instance for the object, which acts as a fast, type-safe KVC interface for `CoreStoreObject`.
|
||||
|
||||
@@ -450,15 +450,18 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
)
|
||||
}
|
||||
for (entity, entityDescription) in entityDescriptionsByEntity {
|
||||
|
||||
let uniqueConstraints = entity.uniqueConstraints.filter({ !$0.isEmpty })
|
||||
if !uniqueConstraints.isEmpty {
|
||||
|
||||
if #available(macOS 10.11, *) {
|
||||
|
||||
CoreStore.assert(
|
||||
entityDescription.superentity == nil,
|
||||
"Uniqueness constraints must be defined at the highest level possible."
|
||||
)
|
||||
entityDescription.uniquenessConstraints = entity.uniqueConstraints.map { $0.map { $0 as NSString } }
|
||||
let uniqueConstraints = entity.uniqueConstraints.filter({ !$0.isEmpty })
|
||||
if !uniqueConstraints.isEmpty {
|
||||
|
||||
CoreStore.assert(
|
||||
entityDescription.superentity == nil,
|
||||
"Uniqueness constraints must be defined at the highest level possible."
|
||||
)
|
||||
entityDescription.uniquenessConstraints = entity.uniqueConstraints.map { $0.map { $0 as NSString } }
|
||||
}
|
||||
}
|
||||
guard !entity.indexes.isEmpty else {
|
||||
|
||||
@@ -525,7 +528,14 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
return CoreStoreManagedObject.self
|
||||
}
|
||||
let managedObjectClass: AnyClass = className.withCString {
|
||||
|
||||
|
||||
// Xcode 10.1+ users: You may find this comment due to a crash while debugging on an iPhone XR device (or any A12 device).
|
||||
// This is a known issue that should not occur in archived builds, as the AppStore strips away arm64e build architectures from the binary. So while it crashes on DEBUG, it shouldn't be an issue for live users.
|
||||
// In the meantime, please submit a bug report to Apple and refer to similar discussions here:
|
||||
// - https://github.com/realm/realm-cocoa/issues/6013
|
||||
// - https://github.com/wordpress-mobile/WordPress-iOS/pull/10400
|
||||
// - https://github.com/JohnEstropia/CoreStore/issues/291
|
||||
// If you wish to debug with A12 devices, please use Xcode 10.0 for now.
|
||||
return objc_allocateClassPair(superClass, $0, 0)!
|
||||
}
|
||||
defer {
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - DataStack
|
||||
|
||||
public extension DataStack {
|
||||
extension DataStack {
|
||||
|
||||
/**
|
||||
Asynchronously adds a `StorageInterface` to the stack. Migrations are also initiated by default.
|
||||
@@ -55,7 +55,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
}
|
||||
catch {
|
||||
@@ -82,7 +82,7 @@ public extension DataStack {
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storeError))
|
||||
completion(.failure(storeError))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -131,7 +131,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(existingStorage))
|
||||
completion(.success(existingStorage))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -143,7 +143,7 @@ public extension DataStack {
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(error))
|
||||
completion(.failure(error))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -181,17 +181,17 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
completion(SetupResult(error))
|
||||
completion(.failure(CoreStoreError(error)))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
completion(SetupResult(error))
|
||||
completion(.failure(CoreStoreError(error)))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -201,12 +201,12 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
completion(SetupResult(error))
|
||||
completion(.failure(CoreStoreError(error)))
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -220,14 +220,14 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(error))
|
||||
completion(.failure(CoreStoreError(error)))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -241,7 +241,7 @@ public extension DataStack {
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storeError))
|
||||
completion(.failure(storeError))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -284,7 +284,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -296,7 +296,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(existingStorage))
|
||||
completion(.success(existingStorage))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -308,7 +308,7 @@ public extension DataStack {
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(error))
|
||||
completion(.failure(error))
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -328,7 +328,7 @@ public extension DataStack {
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
}
|
||||
catch let error as NSError where storage.cloudStorageOptions.contains(.recreateLocalStoreOnModelMismatch) && error.isCoreDataMigrationError {
|
||||
@@ -358,14 +358,14 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storage))
|
||||
completion(.success(storage))
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(error))
|
||||
completion(.failure(CoreStoreError(error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,7 +378,7 @@ public extension DataStack {
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(SetupResult(storeError))
|
||||
completion(.failure(storeError))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -514,7 +514,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(MigrationResult(error))
|
||||
completion(.failure(error))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -524,7 +524,7 @@ public extension DataStack {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(MigrationResult([]))
|
||||
completion(.success([]))
|
||||
return
|
||||
}
|
||||
return nil
|
||||
@@ -538,7 +538,7 @@ public extension DataStack {
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
|
||||
completion(MigrationResult(error))
|
||||
completion(.failure(error))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -586,7 +586,7 @@ public extension DataStack {
|
||||
migrationError,
|
||||
"Failed to migrate version model \"\(migrationType.sourceVersion)\" to version \"\(migrationType.destinationVersion)\"."
|
||||
)
|
||||
migrationResult = MigrationResult(migrationError)
|
||||
migrationResult = .failure(migrationError)
|
||||
cancelled = true
|
||||
}
|
||||
}
|
||||
@@ -609,7 +609,7 @@ public extension DataStack {
|
||||
DispatchQueue.main.async {
|
||||
|
||||
progress.setProgressHandler(nil)
|
||||
completion(migrationResult ?? MigrationResult(migrationTypes))
|
||||
completion(migrationResult ?? .success(migrationTypes))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -749,7 +749,16 @@ public extension DataStack {
|
||||
}
|
||||
}
|
||||
let fileManager = FileManager.default
|
||||
let temporaryDirectoryURL = fileManager.temporaryDirectory
|
||||
let systemTemporaryDirectoryURL: URL
|
||||
if #available(macOS 10.12, *) {
|
||||
|
||||
systemTemporaryDirectoryURL = fileManager.temporaryDirectory
|
||||
}
|
||||
else {
|
||||
|
||||
systemTemporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory())
|
||||
}
|
||||
let temporaryDirectoryURL = systemTemporaryDirectoryURL
|
||||
.appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack")
|
||||
.appendingPathComponent(ProcessInfo().globallyUniqueString)
|
||||
|
||||
@@ -837,7 +846,7 @@ public extension DataStack {
|
||||
|
||||
// MARK: - FilePrivate
|
||||
|
||||
fileprivate extension Array where Element == SchemaMappingProvider {
|
||||
extension Array where Element == SchemaMappingProvider {
|
||||
|
||||
func findMapping(sourceSchema: DynamicSchema, destinationSchema: DynamicSchema, storage: LocalStorage) throws -> (mappingModel: NSMappingModel, migrationType: MigrationType) {
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import CoreData
|
||||
// MARK: - DataStack
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
public extension DataStack {
|
||||
extension DataStack {
|
||||
|
||||
/**
|
||||
Creates an `ObjectMonitor` for the specified `DynamicObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `DynamicObject`.
|
||||
|
||||
@@ -507,13 +507,4 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
|
||||
return self.mainContext
|
||||
}
|
||||
|
||||
|
||||
// MARK: Obsoleted
|
||||
|
||||
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
|
||||
public func internalContext() -> NSManagedObjectContext {
|
||||
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ import CoreData
|
||||
|
||||
// MARK: - DataStack
|
||||
|
||||
public extension DataStack {
|
||||
extension DataStack {
|
||||
|
||||
/**
|
||||
Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
|
||||
- parameter task: the asynchronous closure where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- parameter completion: the closure executed after the save completes. The `Result` argument of the closure will either wrap the return value of `task`, or any uncaught errors thrown from within `task`. Cancelled `task`s will be indicated by `.failure(error: CoreStoreError.userCancelled)`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||
@@ -41,8 +41,8 @@ public extension DataStack {
|
||||
|
||||
self.perform(
|
||||
asynchronous: task,
|
||||
success: { completion(.init(userInfo: $0)) },
|
||||
failure: { completion(.init(error: $0)) }
|
||||
success: { completion(.success($0)) },
|
||||
failure: { completion(.failure($0)) }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -164,56 +164,4 @@ public extension DataStack {
|
||||
)
|
||||
self.mainContext.refreshAndMergeAllObjects()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new auto-commiting methods `perform(asynchronous:completion:)` or `perform(asynchronous:success:failure:)`. Please read the documentation on the behavior of the new methods.")
|
||||
public func beginAsynchronous(_ closure: @escaping (_ transaction: AsynchronousDataTransaction) -> Void) {
|
||||
|
||||
let transaction = AsynchronousDataTransaction(
|
||||
mainContext: self.rootSavingContext,
|
||||
queue: self.childTransactionQueue
|
||||
)
|
||||
transaction.transactionQueue.cs_async {
|
||||
|
||||
closure(transaction)
|
||||
|
||||
if !transaction.isCommitted && transaction.hasChanges {
|
||||
|
||||
CoreStore.log(
|
||||
.warning,
|
||||
message: "The closure for the \(cs_typeName(transaction)) completed without being committed. All changes made within the transaction were discarded."
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new auto-commiting method `perform(synchronous:)`. Please read the documentation on the behavior of the new methods.")
|
||||
@discardableResult
|
||||
public func beginSynchronous(_ closure: @escaping (_ transaction: SynchronousDataTransaction) -> Void) -> SaveResult? {
|
||||
|
||||
let transaction = SynchronousDataTransaction(
|
||||
mainContext: self.rootSavingContext,
|
||||
queue: self.childTransactionQueue
|
||||
)
|
||||
transaction.transactionQueue.cs_sync {
|
||||
|
||||
closure(transaction)
|
||||
|
||||
if !transaction.isCommitted && transaction.hasChanges {
|
||||
|
||||
CoreStore.log(
|
||||
.warning,
|
||||
message: "The closure for the \(cs_typeName(transaction)) completed without being committed. All changes made within the transaction were discarded."
|
||||
)
|
||||
}
|
||||
}
|
||||
switch transaction.result {
|
||||
|
||||
case .none: return nil
|
||||
case .some(let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
|
||||
case .some(_, let error?): return SaveResult(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,57 +614,4 @@ public final class DataStack: Equatable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, renamed: "init(xcodeModelName:bundle:migrationChain:)")
|
||||
public convenience init(modelName: XcodeDataModelFileName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
||||
|
||||
self.init(
|
||||
xcodeModelName: modelName,
|
||||
bundle: bundle,
|
||||
migrationChain: migrationChain
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@available(*, deprecated, message: "Use the new DataStack.init(schemaHistory:) initializer passing an UnsafeDataModelSchema instance as argument")
|
||||
public convenience init(model: NSManagedObjectModel, migrationChain: MigrationChain = nil) {
|
||||
|
||||
let modelVersion = migrationChain.leafVersions.first!
|
||||
self.init(
|
||||
schemaHistory: SchemaHistory(
|
||||
allSchema: [
|
||||
UnsafeDataModelSchema(
|
||||
modelName: modelVersion,
|
||||
model: model
|
||||
)
|
||||
],
|
||||
migrationChain: migrationChain,
|
||||
exactCurrentModelVersion: modelVersion
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new DataStack.entityTypesByName(for:) method passing `NSManagedObject.self` as argument.")
|
||||
public var entityTypesByName: [EntityName: NSManagedObject.Type] {
|
||||
|
||||
return self.entityTypesByName(for: NSManagedObject.self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Obsolete
|
||||
|
||||
@available(*, obsoleted: 3.1, renamed: "entityDescription(for:)")
|
||||
public func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
|
||||
|
||||
return self.entityDescription(for: type)
|
||||
}
|
||||
|
||||
@available(*, obsoleted: 3.1, renamed: "objectID(forURIRepresentation:)")
|
||||
public func objectIDForURIRepresentation(_ url: URL) -> NSManagedObjectID? {
|
||||
|
||||
return self.objectID(forURIRepresentation: url)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import Foundation
|
||||
|
||||
// MARK: - DispatchQueue
|
||||
|
||||
internal extension DispatchQueue {
|
||||
extension DispatchQueue {
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - AnyDynamicKeyPath
|
||||
@@ -47,7 +48,7 @@ public protocol DynamicKeyPath: AnyDynamicKeyPath {
|
||||
/**
|
||||
The DynamicObject type
|
||||
*/
|
||||
associatedtype ObjectType
|
||||
associatedtype ObjectType: DynamicObject
|
||||
|
||||
/**
|
||||
The Value type
|
||||
@@ -58,7 +59,7 @@ public protocol DynamicKeyPath: AnyDynamicKeyPath {
|
||||
|
||||
// MARK: - KeyPathString
|
||||
|
||||
public extension KeyPathString {
|
||||
extension KeyPathString {
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from the property.
|
||||
@@ -66,7 +67,7 @@ public extension KeyPathString {
|
||||
let keyPath = String(keyPath: \Person.nickname)
|
||||
```
|
||||
*/
|
||||
public init<O: NSManagedObject, V>(keyPath: KeyPath<O, V>) {
|
||||
public init<O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(keyPath: KeyPath<O, V>) {
|
||||
|
||||
self = keyPath.cs_keyPathString
|
||||
}
|
||||
@@ -78,21 +79,27 @@ public extension KeyPathString {
|
||||
```
|
||||
*/
|
||||
public init<O: CoreStoreObject, K: DynamicKeyPath>(keyPath: KeyPath<O, K>) {
|
||||
|
||||
|
||||
self = O.meta[keyPath: keyPath].cs_keyPathString
|
||||
}
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from the property.
|
||||
```
|
||||
let keyPath = String(keyPath: \Person.nickname)
|
||||
```
|
||||
*/
|
||||
public init<O: DynamicObject, T, V>(keyPath: Where<O>.Expression<T, V>) {
|
||||
|
||||
self = keyPath.cs_keyPathString
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: - KeyPath: DynamicKeyPath
|
||||
|
||||
// TODO: SE-0143 (https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md) is implemented but multiple conformances for the same type currently cannot be declared.
|
||||
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: ImportableAttributeType
|
||||
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: ImportableAttributeType?
|
||||
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: NSManagedObject?
|
||||
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: NSSet
|
||||
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: NSOrderedSet
|
||||
extension KeyPath: DynamicKeyPath {
|
||||
extension KeyPath: DynamicKeyPath, AnyDynamicKeyPath where Root: DynamicObject, Value: AllowedObjectiveCKeyPathValue {
|
||||
|
||||
public typealias ObjectType = Root
|
||||
public typealias ValueType = Value
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - DynamicObject
|
||||
|
||||
@@ -29,7 +29,7 @@ import Foundation
|
||||
|
||||
// MARK: - DynamicSchema
|
||||
|
||||
public extension DynamicSchema {
|
||||
extension DynamicSchema {
|
||||
|
||||
/**
|
||||
Prints the `DynamicSchema` as their corresponding `CoreStoreObject` Swift declarations. This is useful for converting current `XcodeDataModelSchema`-based models into the new `CoreStoreSchema` framework. Additional adjustments may need to be done to the generated source code; for example: `Transformable` concrete types need to be provided, as well as `default` values.
|
||||
@@ -153,11 +153,10 @@ public extension DynamicSchema {
|
||||
valueType = Data.self
|
||||
if let defaultValue = (attribute.defaultValue as! Data.QueryableNativeType?).flatMap(Data.cs_fromQueryableNativeType) {
|
||||
|
||||
let count = defaultValue.count
|
||||
let bytes = defaultValue.withUnsafeBytes { (pointer: UnsafePointer<UInt8>) in
|
||||
|
||||
return (0 ..< (count / MemoryLayout<UInt8>.size))
|
||||
.map({ "\("0x\(String(pointer[$0], radix: 16, uppercase: false))")" })
|
||||
let bytes = defaultValue.withUnsafeBytes { (pointer) in
|
||||
return pointer
|
||||
.bindMemory(to: UInt64.self)
|
||||
.map({ "\("0x\(String($0, radix: 16, uppercase: false))")" })
|
||||
}
|
||||
defaultString = ", initial: Data(bytes: [\(bytes.joined(separator: ", "))])"
|
||||
}
|
||||
|
||||
@@ -70,7 +70,8 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
|
||||
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
|
||||
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
|
||||
*/
|
||||
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
|
||||
@available(macOS 10.11, *)
|
||||
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]]) {
|
||||
|
||||
self.init(
|
||||
O.self,
|
||||
@@ -81,6 +82,27 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
|
||||
uniqueConstraints: uniqueConstraints
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes an `Entity`. Always provide a concrete generic type to `Entity`.
|
||||
```
|
||||
Entity<Animal>("Animal")
|
||||
```
|
||||
- parameter entityName: the `NSEntityDescription` name to use for the entity
|
||||
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
|
||||
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
|
||||
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
|
||||
*/
|
||||
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = []) {
|
||||
|
||||
self.init(
|
||||
O.self,
|
||||
entityName,
|
||||
isAbstract: isAbstract,
|
||||
versionHashModifier: versionHashModifier,
|
||||
indexes: indexes
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes an `Entity`.
|
||||
@@ -94,7 +116,8 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
|
||||
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
|
||||
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
|
||||
*/
|
||||
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
|
||||
@available(macOS 10.11, *)
|
||||
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]]) {
|
||||
|
||||
let meta = O.meta
|
||||
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
|
||||
@@ -113,6 +136,38 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
|
||||
uniqueConstraints: uniqueConstraints.map(toStringArray)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes an `Entity`.
|
||||
```
|
||||
Entity(Animal.self, "Animal")
|
||||
```
|
||||
- parameter type: the `DynamicObject` type associated with the entity
|
||||
- parameter entityName: the `NSEntityDescription` name to use for the entity
|
||||
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
|
||||
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
|
||||
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
|
||||
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
|
||||
*/
|
||||
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = []) {
|
||||
|
||||
let meta = O.meta
|
||||
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
|
||||
|
||||
return $0.map {
|
||||
|
||||
return (meta[keyPath: $0] as! AnyDynamicKeyPath).cs_keyPathString
|
||||
}
|
||||
}
|
||||
super.init(
|
||||
type: type,
|
||||
entityName: entityName,
|
||||
isAbstract: isAbstract,
|
||||
versionHashModifier: versionHashModifier,
|
||||
indexes: indexes.map(toStringArray),
|
||||
uniqueConstraints: []
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -86,6 +86,14 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if #available(iOS 10.3, tvOS 10.3, watchOS 3.2, macOS 10.13, *) {}
|
||||
else {
|
||||
|
||||
self.deletedSections = []
|
||||
self.insertedSections = []
|
||||
}
|
||||
|
||||
self.handler?.controllerWillChangeContent(controller)
|
||||
}
|
||||
|
||||
@@ -100,6 +108,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
self.handler?.controllerDidChangeContent(controller)
|
||||
}
|
||||
|
||||
@@ -110,11 +119,102 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if #available(iOS 10.3, tvOS 10.3, watchOS 3.2, macOS 10.13, *) {
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: type,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
guard var actualType = NSFetchedResultsChangeType(rawValue: type.rawValue) else {
|
||||
|
||||
// This fix is for a bug where iOS passes 0 for NSFetchedResultsChangeType, but this is not a valid enum case.
|
||||
// Swift will then always execute the first case of the switch causing strange behaviour.
|
||||
// https://forums.developer.apple.com/thread/12184#31850
|
||||
return
|
||||
}
|
||||
|
||||
// This whole dance is a workaround for a nasty bug introduced in XCode 7 targeted at iOS 8 devices
|
||||
// http://stackoverflow.com/questions/31383760/ios-9-attempt-to-delete-and-reload-the-same-index-path/31384014#31384014
|
||||
// https://forums.developer.apple.com/message/9998#9998
|
||||
// https://forums.developer.apple.com/message/31849#31849
|
||||
|
||||
if case .update = actualType,
|
||||
indexPath != nil,
|
||||
newIndexPath != nil {
|
||||
|
||||
actualType = .move
|
||||
}
|
||||
|
||||
switch actualType {
|
||||
|
||||
case .update:
|
||||
guard let section = indexPath?[0] else {
|
||||
|
||||
return
|
||||
}
|
||||
if self.deletedSections.contains(section)
|
||||
|| self.insertedSections.contains(section) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
case .move:
|
||||
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {
|
||||
|
||||
return
|
||||
}
|
||||
guard indexPath == newIndexPath else {
|
||||
|
||||
break
|
||||
}
|
||||
if self.insertedSections.contains(indexPath[0]) {
|
||||
|
||||
// Observers that handle the .Move change are advised to delete then reinsert the object instead of just moving. This is especially true when indexPath and newIndexPath are equal. For example, calling tableView.moveRowAtIndexPath(_:toIndexPath) when both indexPaths are the same will crash the tableView.
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: .move,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
return
|
||||
}
|
||||
if self.deletedSections.contains(indexPath[0]) {
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: nil,
|
||||
forChangeType: .insert,
|
||||
newIndexPath: indexPath
|
||||
)
|
||||
return
|
||||
}
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: .update,
|
||||
newIndexPath: nil
|
||||
)
|
||||
return
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: type,
|
||||
forChangeType: actualType,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
}
|
||||
@@ -126,6 +226,18 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if #available(iOS 10.3, tvOS 10.3, watchOS 3.2, macOS 10.13, *) {}
|
||||
else {
|
||||
|
||||
switch type {
|
||||
|
||||
case .delete: self.deletedSections.insert(sectionIndex)
|
||||
case .insert: self.insertedSections.insert(sectionIndex)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeSection: sectionInfo,
|
||||
@@ -142,4 +254,13 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
sectionIndexTitleForSectionName: sectionName
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@nonobjc
|
||||
private var deletedSections = Set<Int>()
|
||||
|
||||
@nonobjc
|
||||
private var insertedSections = Set<Int>()
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
|
||||
// MARK: - From
|
||||
|
||||
public extension From {
|
||||
extension From {
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that starts with the specified `Where` clause
|
||||
@@ -65,6 +65,17 @@ public extension From {
|
||||
|
||||
return self.fetchChain(appending: Where<D>(format, argumentArray: argumentArray))
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that starts with the specified `OrderBy` clause.
|
||||
|
||||
- parameter clause: the `OrderBy` clause to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that starts with the specified `OrderBy` clause
|
||||
*/
|
||||
public func orderBy(_ clause: OrderBy<D>) -> FetchChainBuilder<D> {
|
||||
|
||||
return self.fetchChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` with a series of `SortKey`s
|
||||
@@ -77,6 +88,17 @@ public extension From {
|
||||
|
||||
return self.fetchChain(appending: OrderBy<D>([sortKey] + sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` with a series of `SortKey`s
|
||||
|
||||
- parameter sortKeys: a series of `SortKey`s
|
||||
- returns: a `FetchChainBuilder` with a series of `SortKey`s
|
||||
*/
|
||||
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> FetchChainBuilder<D> {
|
||||
|
||||
return self.fetchChain(appending: OrderBy<D>(sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` with a closure where the `NSFetchRequest` may be configured
|
||||
@@ -218,7 +240,7 @@ public extension From {
|
||||
|
||||
// MARK: - From where D: NSManagedObject
|
||||
|
||||
public extension From where D: NSManagedObject {
|
||||
extension From where D: NSManagedObject {
|
||||
|
||||
/**
|
||||
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
|
||||
@@ -261,7 +283,7 @@ public extension From where D: NSManagedObject {
|
||||
|
||||
// MARK: - From where D: CoreStoreObject
|
||||
|
||||
public extension From where D: CoreStoreObject {
|
||||
extension From where D: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that starts with the specified `Where` clause
|
||||
@@ -431,7 +453,7 @@ public extension From where D: CoreStoreObject {
|
||||
|
||||
// MARK: - FetchChainBuilder
|
||||
|
||||
public extension FetchChainBuilder {
|
||||
extension FetchChainBuilder {
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `FetchChainBuilder`
|
||||
@@ -467,6 +489,17 @@ public extension FetchChainBuilder {
|
||||
|
||||
return self.fetchChain(appending: Where<D>(format, argumentArray: argumentArray))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `FetchChainBuilder`
|
||||
|
||||
- parameter clause: the `OrderBy` clause to add
|
||||
- returns: a new `FetchChainBuilder` containing the `OrderBy` clause
|
||||
*/
|
||||
public func orderBy(_ clause: OrderBy<D>) -> FetchChainBuilder<D> {
|
||||
|
||||
return self.fetchChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `FetchChainBuilder`
|
||||
@@ -479,6 +512,17 @@ public extension FetchChainBuilder {
|
||||
|
||||
return self.fetchChain(appending: OrderBy<D>([sortKey] + sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `FetchChainBuilder`
|
||||
|
||||
- parameter sortKeys: a series of `SortKey`s
|
||||
- returns: a new `FetchChainBuilder` containing the `OrderBy` clause
|
||||
*/
|
||||
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> FetchChainBuilder<D> {
|
||||
|
||||
return self.fetchChain(appending: OrderBy<D>(sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `Tweak` clause to the `FetchChainBuilder` with a closure where the `NSFetchRequest` may be configured
|
||||
@@ -536,7 +580,7 @@ public extension FetchChainBuilder {
|
||||
|
||||
// MARK: - FetchChainBuilder where D: CoreStoreObject
|
||||
|
||||
public extension FetchChainBuilder where D: CoreStoreObject {
|
||||
extension FetchChainBuilder where D: CoreStoreObject {
|
||||
|
||||
public func `where`<T: AnyWhereClause>(_ clause: (D) -> T) -> FetchChainBuilder<D> {
|
||||
|
||||
@@ -547,7 +591,7 @@ public extension FetchChainBuilder where D: CoreStoreObject {
|
||||
|
||||
// MARK: - QueryChainBuilder
|
||||
|
||||
public extension QueryChainBuilder {
|
||||
extension QueryChainBuilder {
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `QueryChainBuilder`
|
||||
@@ -583,6 +627,17 @@ public extension QueryChainBuilder {
|
||||
|
||||
return self.queryChain(appending: Where<D>(format, argumentArray: argumentArray))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `QueryChainBuilder`
|
||||
|
||||
- parameter clause: the `OrderBy` clause to add
|
||||
- returns: a new `QueryChainBuilder` containing the `OrderBy` clause
|
||||
*/
|
||||
public func orderBy(_ clause: OrderBy<D>) -> QueryChainBuilder<D, R> {
|
||||
|
||||
return self.queryChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `QueryChainBuilder`
|
||||
@@ -595,6 +650,17 @@ public extension QueryChainBuilder {
|
||||
|
||||
return self.queryChain(appending: OrderBy<D>([sortKey] + sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `QueryChainBuild`
|
||||
|
||||
- parameter sortKeys: a series of `SortKey`s
|
||||
- returns: a new `QueryChainBuilder` containing the `OrderBy` clause
|
||||
*/
|
||||
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> QueryChainBuilder<D, R> {
|
||||
|
||||
return self.queryChain(appending: OrderBy<D>(sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `Tweak` clause to the `QueryChainBuilder` with a closure where the `NSFetchRequest` may be configured
|
||||
@@ -688,7 +754,7 @@ public extension QueryChainBuilder {
|
||||
|
||||
// MARK: - QueryChainBuilder where D: NSManagedObject
|
||||
|
||||
public extension QueryChainBuilder where D: NSManagedObject {
|
||||
extension QueryChainBuilder where D: NSManagedObject {
|
||||
|
||||
/**
|
||||
Adds a `GroupBy` clause to the `QueryChainBuilder`
|
||||
@@ -705,7 +771,7 @@ public extension QueryChainBuilder where D: NSManagedObject {
|
||||
|
||||
// MARK: - QueryChainBuilder where D: CoreStoreObject
|
||||
|
||||
public extension QueryChainBuilder where D: CoreStoreObject {
|
||||
extension QueryChainBuilder where D: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `QueryChainBuilder`
|
||||
@@ -767,7 +833,7 @@ public extension QueryChainBuilder where D: CoreStoreObject {
|
||||
// MARK: - SectionMonitorChainBuilder
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
public extension SectionMonitorChainBuilder {
|
||||
extension SectionMonitorChainBuilder {
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `SectionMonitorChainBuilder`
|
||||
@@ -803,6 +869,17 @@ public extension SectionMonitorChainBuilder {
|
||||
|
||||
return self.sectionMonitorChain(appending: Where<D>(format, argumentArray: argumentArray))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
|
||||
|
||||
- parameter clause: the `OrderBy` clause to add
|
||||
- returns: a new `SectionMonitorChainBuilder` containing the `OrderBy` clause
|
||||
*/
|
||||
public func orderBy(_ clause: OrderBy<D>) -> SectionMonitorChainBuilder<D> {
|
||||
|
||||
return self.sectionMonitorChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
|
||||
@@ -815,6 +892,17 @@ public extension SectionMonitorChainBuilder {
|
||||
|
||||
return self.sectionMonitorChain(appending: OrderBy<D>([sortKey] + sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
|
||||
|
||||
- parameter sortKeys: a series of `SortKey`s
|
||||
- returns: a new `SectionMonitorChainBuilder` containing the `OrderBy` clause
|
||||
*/
|
||||
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> SectionMonitorChainBuilder<D> {
|
||||
|
||||
return self.sectionMonitorChain(appending: OrderBy<D>(sortKeys))
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `Tweak` clause to the `SectionMonitorChainBuilder` with a closure where the `NSFetchRequest` may be configured
|
||||
@@ -875,7 +963,7 @@ public extension SectionMonitorChainBuilder {
|
||||
// MARK: - SectionMonitorChainBuilder where D: CoreStoreObject
|
||||
|
||||
@available(macOS 10.12, *)
|
||||
public extension SectionMonitorChainBuilder where D: CoreStoreObject {
|
||||
extension SectionMonitorChainBuilder where D: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `SectionMonitorChainBuilder`
|
||||
|
||||
@@ -139,7 +139,7 @@ public struct From<D: DynamicObject> {
|
||||
self.findPersistentStores = findPersistentStores
|
||||
}
|
||||
|
||||
internal func applyToFetchRequest<U>(_ fetchRequest: NSFetchRequest<U>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) throws {
|
||||
internal func applyToFetchRequest<U>(_ fetchRequest: CoreStoreFetchRequest<U>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) throws {
|
||||
|
||||
fetchRequest.entity = context.parentStack!.entityDescription(for: EntityIdentifier(self.entityClass))!
|
||||
guard applyAffectedStores else {
|
||||
@@ -164,7 +164,7 @@ public struct From<D: DynamicObject> {
|
||||
}
|
||||
}
|
||||
|
||||
internal func applyAffectedStoresForFetchedRequest<U>(_ fetchRequest: NSFetchRequest<U>, context: NSManagedObjectContext) throws {
|
||||
internal func applyAffectedStoresForFetchedRequest<U>(_ fetchRequest: CoreStoreFetchRequest<U>, context: NSManagedObjectContext) throws {
|
||||
|
||||
let stores = self.findPersistentStores(context)
|
||||
fetchRequest.affectedStores = stores
|
||||
|
||||
@@ -103,7 +103,7 @@ public struct GroupBy<D: DynamicObject>: GroupByClause, QueryClause, Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
public extension GroupBy where D: NSManagedObject {
|
||||
extension GroupBy where D: NSManagedObject {
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a key path
|
||||
@@ -116,7 +116,7 @@ public extension GroupBy where D: NSManagedObject {
|
||||
}
|
||||
}
|
||||
|
||||
public extension GroupBy where D: CoreStoreObject {
|
||||
extension GroupBy where D: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a key path
|
||||
|
||||
@@ -1,569 +0,0 @@
|
||||
//
|
||||
// ICloudStore.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
|
||||
|
||||
|
||||
#if os(iOS) || os(macOS)
|
||||
|
||||
// MARK: - ICloudStore
|
||||
|
||||
/**
|
||||
A storage interface backed by an SQLite database managed by iCloud.
|
||||
*/
|
||||
@available(*, deprecated, message: "Please see the release notes and Core Data documentation.")
|
||||
public final class ICloudStore: CloudStorage, CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
|
||||
/**
|
||||
Initializes an iCloud store interface from the given ubiquitous store information. Returns `nil` if the container could not be located or if iCloud storage is unavailable for the current user or device
|
||||
```
|
||||
guard let storage = ICloudStore(
|
||||
ubiquitousContentName: "MyAppCloudData",
|
||||
ubiquitousContentTransactionLogsSubdirectory: "logs/config1",
|
||||
ubiquitousContainerID: "iCloud.com.mycompany.myapp.containername",
|
||||
ubiquitousPeerToken: "9614d658014f4151a95d8048fb717cf0",
|
||||
configuration: "Config1",
|
||||
cloudStorageOptions: .recreateLocalStoreOnModelMismatch
|
||||
) else {
|
||||
// iCloud is not available on the device
|
||||
return
|
||||
}
|
||||
CoreStore.addStorage(
|
||||
storage,
|
||||
completion: { result in
|
||||
// ...
|
||||
}
|
||||
)
|
||||
```
|
||||
- parameter ubiquitousContentName: the name of the store in iCloud. This is required and should not be empty, and should not contain periods (`.`).
|
||||
- parameter ubiquitousContentTransactionLogsSubdirectory: a required relative path for the transaction logs
|
||||
- parameter ubiquitousContainerID: a container if your app has multiple ubiquity container identifiers in its entitlements
|
||||
- parameter ubiquitousPeerToken: a per-application salt to allow multiple apps on the same device to share a Core Data store integrated with iCloud
|
||||
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `ubiquitousContentName` explicitly for each of them.
|
||||
- parameter cloudStorageOptions: When the `ICloudStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
|
||||
*/
|
||||
public required init?(ubiquitousContentName: String, ubiquitousContentTransactionLogsSubdirectory: String, ubiquitousContainerID: String? = nil, ubiquitousPeerToken: String? = nil, configuration: ModelConfiguration = nil, cloudStorageOptions: CloudStorageOptions = nil) {
|
||||
|
||||
CoreStore.assert(
|
||||
!ubiquitousContentName.isEmpty,
|
||||
"The ubiquitousContentName cannot be empty."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!ubiquitousContentName.contains("."),
|
||||
"The ubiquitousContentName cannot contain periods."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!ubiquitousContentTransactionLogsSubdirectory.isEmpty,
|
||||
"The ubiquitousContentURLRelativePath should not be empty."
|
||||
)
|
||||
CoreStore.assert(
|
||||
ubiquitousPeerToken?.isEmpty != true,
|
||||
"The ubiquitousPeerToken should not be empty if provided."
|
||||
)
|
||||
|
||||
let fileManager = FileManager.default
|
||||
guard let cacheFolderURL = fileManager.url(forUbiquityContainerIdentifier: ubiquitousContainerID) else {
|
||||
|
||||
return nil
|
||||
}
|
||||
let cacheFileURL = cacheFolderURL.appendingPathComponent(ubiquitousContentTransactionLogsSubdirectory)
|
||||
|
||||
var storeOptions: [String: Any] = [
|
||||
NSSQLitePragmasOption: ["journal_mode": "WAL"],
|
||||
NSPersistentStoreUbiquitousContentNameKey: ubiquitousContentName
|
||||
]
|
||||
storeOptions[NSPersistentStoreUbiquitousContentURLKey] = ubiquitousContentTransactionLogsSubdirectory
|
||||
storeOptions[NSPersistentStoreUbiquitousContainerIdentifierKey] = ubiquitousContainerID
|
||||
storeOptions[NSPersistentStoreUbiquitousPeerTokenOption] = ubiquitousPeerToken
|
||||
|
||||
self.cacheFileURL = cacheFileURL
|
||||
self.configuration = configuration
|
||||
self.cloudStorageOptions = cloudStorageOptions
|
||||
self.storeOptions = storeOptions
|
||||
}
|
||||
|
||||
/**
|
||||
Registers an `ICloudStoreObserver` to start receive notifications from the ubiquitous store
|
||||
|
||||
- parameter observer: the observer to start sending ubiquitous notifications to
|
||||
*/
|
||||
public func addObserver<T: ICloudStoreObserver>(_ observer: T) {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to add an observer of type \(cs_typeName(observer)) outside the main thread."
|
||||
)
|
||||
|
||||
self.removeObserver(observer)
|
||||
|
||||
self.registerNotification(
|
||||
&self.willFinishInitialImportKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreWillFinishInitialImport,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreWillFinishUbiquitousStoreInitialImport(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
self.registerNotification(
|
||||
&self.didFinishInitialImportKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreDidFinishInitialImport,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreDidFinishUbiquitousStoreInitialImport(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
self.registerNotification(
|
||||
&self.willAddAccountKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreWillAddAccount,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreWillAddAccount(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
self.registerNotification(
|
||||
&self.didAddAccountKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreDidAddAccount,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreDidAddAccount(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
self.registerNotification(
|
||||
&self.willRemoveAccountKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreWillRemoveAccount,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreWillRemoveAccount(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
self.registerNotification(
|
||||
&self.didRemoveAccountKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreDidRemoveAccount,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreDidRemoveAccount(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
self.registerNotification(
|
||||
&self.willRemoveContentKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreWillRemoveContent,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreWillRemoveContent(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
self.registerNotification(
|
||||
&self.didRemoveContentKey,
|
||||
name: Notification.Name.iCloudUbiquitousStoreDidRemoveContent,
|
||||
toObserver: observer,
|
||||
callback: { (observer, storage, dataStack) in
|
||||
|
||||
observer.iCloudStoreDidRemoveContent(storage: storage, dataStack: dataStack)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Unregisters an `ICloudStoreObserver` to stop receiving notifications from the ubiquitous store
|
||||
|
||||
- parameter observer: the observer to stop sending ubiquitous notifications to
|
||||
*/
|
||||
public func removeObserver(_ observer: ICloudStoreObserver) {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to remove an observer of type \(cs_typeName(observer)) outside the main thread."
|
||||
)
|
||||
let nilValue: AnyObject? = nil
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.willFinishInitialImportKey,
|
||||
inObject: observer
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.didFinishInitialImportKey,
|
||||
inObject: observer
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.willAddAccountKey,
|
||||
inObject: observer
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.didAddAccountKey,
|
||||
inObject: observer
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.willRemoveAccountKey,
|
||||
inObject: observer
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.didRemoveAccountKey,
|
||||
inObject: observer
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.willRemoveContentKey,
|
||||
inObject: observer
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &self.didRemoveContentKey,
|
||||
inObject: observer
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: StorageInterface
|
||||
|
||||
/**
|
||||
The string identifier for the `NSPersistentStore`'s `type` property. For `SQLiteStore`s, this is always set to `NSSQLiteStoreType`.
|
||||
*/
|
||||
public static let storeType = NSSQLiteStoreType
|
||||
|
||||
/**
|
||||
The configuration name in the model file
|
||||
*/
|
||||
public let configuration: ModelConfiguration
|
||||
|
||||
/**
|
||||
The options dictionary for the `NSPersistentStore`. For `SQLiteStore`s, this is always set to
|
||||
```
|
||||
[NSSQLitePragmasOption: ["journal_mode": "WAL"]]
|
||||
```
|
||||
*/
|
||||
public let storeOptions: [AnyHashable: Any]?
|
||||
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func cs_didAddToDataStack(_ dataStack: DataStack) {
|
||||
|
||||
self.cs_didRemoveFromDataStack(dataStack)
|
||||
|
||||
self.dataStack = dataStack
|
||||
let coordinator = dataStack.coordinator
|
||||
|
||||
cs_setAssociatedRetainedObject(
|
||||
NotificationObserver(
|
||||
notificationName: Notification.Name.NSPersistentStoreCoordinatorStoresWillChange,
|
||||
object: coordinator,
|
||||
closure: { [weak self, weak dataStack] (note) -> Void in
|
||||
|
||||
guard let `self` = self,
|
||||
let dataStack = dataStack,
|
||||
let userInfo = note.userInfo,
|
||||
let transitionType = userInfo[NSPersistentStoreUbiquitousTransitionTypeKey] as? NSNumber else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
let notification: Notification.Name
|
||||
switch NSPersistentStoreUbiquitousTransitionType(rawValue: transitionType.uintValue) {
|
||||
|
||||
case .initialImportCompleted?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreWillFinishInitialImport
|
||||
|
||||
case .accountAdded?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreWillAddAccount
|
||||
|
||||
case .accountRemoved?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreWillRemoveAccount
|
||||
|
||||
case .contentRemoved?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreWillRemoveContent
|
||||
|
||||
default:
|
||||
return
|
||||
}
|
||||
NotificationCenter.default.post(
|
||||
name: notification,
|
||||
object: self,
|
||||
userInfo: [String(describing: DataStack.self): dataStack]
|
||||
)
|
||||
}
|
||||
),
|
||||
forKey: &Static.persistentStoreCoordinatorWillChangeStores,
|
||||
inObject: self
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
NotificationObserver(
|
||||
notificationName: NSNotification.Name.NSPersistentStoreCoordinatorStoresDidChange,
|
||||
object: coordinator,
|
||||
closure: { [weak self, weak dataStack] (note) -> Void in
|
||||
|
||||
guard let `self` = self,
|
||||
let dataStack = dataStack,
|
||||
let userInfo = note.userInfo,
|
||||
let transitionType = userInfo[NSPersistentStoreUbiquitousTransitionTypeKey] as? NSNumber else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
let notification: Notification.Name
|
||||
switch NSPersistentStoreUbiquitousTransitionType(rawValue: transitionType.uintValue) {
|
||||
|
||||
case .initialImportCompleted?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreDidFinishInitialImport
|
||||
|
||||
case .accountAdded?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreDidAddAccount
|
||||
|
||||
case .accountRemoved?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreDidRemoveAccount
|
||||
|
||||
case .contentRemoved?:
|
||||
notification = Notification.Name.iCloudUbiquitousStoreDidRemoveContent
|
||||
|
||||
default:
|
||||
return
|
||||
}
|
||||
NotificationCenter.default.post(
|
||||
name: notification,
|
||||
object: self,
|
||||
userInfo: [String(describing: DataStack.self): dataStack]
|
||||
)
|
||||
}
|
||||
),
|
||||
forKey: &Static.persistentStoreCoordinatorDidChangeStores,
|
||||
inObject: self
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func cs_didRemoveFromDataStack(_ dataStack: DataStack) {
|
||||
|
||||
let coordinator = dataStack.coordinator
|
||||
let nilValue: AnyObject? = nil
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &Static.persistentStoreCoordinatorWillChangeStores,
|
||||
inObject: coordinator
|
||||
)
|
||||
cs_setAssociatedRetainedObject(
|
||||
nilValue,
|
||||
forKey: &Static.persistentStoreCoordinatorDidChangeStores,
|
||||
inObject: coordinator
|
||||
)
|
||||
|
||||
self.dataStack = nil
|
||||
}
|
||||
|
||||
|
||||
// MARK: CloudStorage
|
||||
|
||||
/**
|
||||
The `NSURL` that points to the ubiquity container file
|
||||
*/
|
||||
public let cacheFileURL: URL
|
||||
|
||||
/**
|
||||
Options that tell the `DataStack` how to setup the persistent store
|
||||
*/
|
||||
public var cloudStorageOptions: CloudStorageOptions
|
||||
|
||||
/**
|
||||
The options dictionary for the specified `CloudStorageOptions`
|
||||
*/
|
||||
public func dictionary(forOptions options: CloudStorageOptions) -> [AnyHashable: Any]? {
|
||||
|
||||
if options == .none {
|
||||
|
||||
return self.storeOptions
|
||||
}
|
||||
|
||||
var storeOptions = self.storeOptions ?? [:]
|
||||
if options.contains(.allowSynchronousLightweightMigration) {
|
||||
|
||||
storeOptions[NSMigratePersistentStoresAutomaticallyOption] = true
|
||||
storeOptions[NSInferMappingModelAutomaticallyOption] = true
|
||||
}
|
||||
if options.contains(.recreateLocalStoreOnModelMismatch) {
|
||||
|
||||
storeOptions[NSPersistentStoreRebuildFromUbiquitousContentOption] = true
|
||||
}
|
||||
return storeOptions
|
||||
}
|
||||
|
||||
/**
|
||||
Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
|
||||
*/
|
||||
public func cs_eraseStorageAndWait(soureModel: NSManagedObjectModel) throws {
|
||||
|
||||
let cacheFileURL = self.cacheFileURL
|
||||
try autoreleasepool {
|
||||
|
||||
let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel)
|
||||
let options = [
|
||||
NSSQLitePragmasOption: ["journal_mode": "DELETE"],
|
||||
NSPersistentStoreRemoveUbiquitousMetadataOption: true
|
||||
] as [String : Any]
|
||||
let store = try journalUpdatingCoordinator.addPersistentStore(
|
||||
ofType: type(of: self).storeType,
|
||||
configurationName: self.configuration,
|
||||
at: cacheFileURL,
|
||||
options: options
|
||||
)
|
||||
try journalUpdatingCoordinator.remove(store)
|
||||
try NSPersistentStoreCoordinator.removeUbiquitousContentAndPersistentStore(
|
||||
at: cacheFileURL,
|
||||
options: options
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
public var debugDescription: String {
|
||||
|
||||
func formattedValue(_ any: Any) -> String {
|
||||
|
||||
switch any {
|
||||
|
||||
case let any as CoreStoreDebugStringConvertible:
|
||||
return any.coreStoreDumpString
|
||||
|
||||
default:
|
||||
return "\(any)"
|
||||
}
|
||||
}
|
||||
var string = "(\(String(reflecting: type(of: self)))) "
|
||||
string.append(formattedValue(self))
|
||||
return string
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreDebugStringConvertible
|
||||
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
func formattedValue(_ any: Any) -> String {
|
||||
|
||||
switch any {
|
||||
|
||||
case let any as CoreStoreDebugStringConvertible:
|
||||
return any.coreStoreDumpString
|
||||
|
||||
default:
|
||||
return "\(any)"
|
||||
}
|
||||
}
|
||||
func createFormattedString(_ firstLine: String, _ lastLine: String, _ info: [(key: String, value: Any)]) -> String {
|
||||
|
||||
var string = firstLine
|
||||
for (key, value) in info {
|
||||
|
||||
string.append("\n.\(key) = \(formattedValue(value));")
|
||||
}
|
||||
string = string.replacingOccurrences(of: "\n", with: "\n\(String(repeating: " ", count: 4))")
|
||||
string.append("\n\(lastLine)")
|
||||
return string
|
||||
}
|
||||
return createFormattedString(
|
||||
"(", ")",
|
||||
[
|
||||
("configuration", self.configuration as Any),
|
||||
("storeOptions", self.storeOptions as Any),
|
||||
("cacheFileURL", self.cacheFileURL),
|
||||
("cloudStorageOptions", self.cloudStorageOptions)
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
fileprivate struct Static {
|
||||
|
||||
fileprivate static var persistentStoreCoordinatorWillChangeStores: Void?
|
||||
fileprivate static var persistentStoreCoordinatorDidChangeStores: Void?
|
||||
}
|
||||
|
||||
private var willFinishInitialImportKey: Void?
|
||||
private var didFinishInitialImportKey: Void?
|
||||
private var willAddAccountKey: Void?
|
||||
private var didAddAccountKey: Void?
|
||||
private var willRemoveAccountKey: Void?
|
||||
private var didRemoveAccountKey: Void?
|
||||
private var willRemoveContentKey: Void?
|
||||
private var didRemoveContentKey: Void?
|
||||
|
||||
private weak var dataStack: DataStack?
|
||||
|
||||
private func registerNotification<T: ICloudStoreObserver>(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: T, callback: @escaping (_ observer: T, _ storage: ICloudStore, _ dataStack: DataStack) -> Void) {
|
||||
|
||||
cs_setAssociatedRetainedObject(
|
||||
NotificationObserver(
|
||||
notificationName: name,
|
||||
object: self,
|
||||
closure: { [weak self, weak observer] (note) -> Void in
|
||||
|
||||
guard let `self` = self,
|
||||
let observer = observer,
|
||||
let dataStack = note.userInfo?[String(describing: DataStack.self)] as? DataStack,
|
||||
self.dataStack === dataStack else {
|
||||
|
||||
return
|
||||
}
|
||||
callback(observer, self, dataStack)
|
||||
}
|
||||
),
|
||||
forKey: notificationKey,
|
||||
inObject: observer
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Notification Keys
|
||||
|
||||
fileprivate extension Notification.Name {
|
||||
|
||||
fileprivate static let iCloudUbiquitousStoreWillFinishInitialImport = Notification.Name(rawValue: "iCloudUbiquitousStoreWillFinishInitialImport")
|
||||
fileprivate static let iCloudUbiquitousStoreDidFinishInitialImport = Notification.Name(rawValue: "iCloudUbiquitousStoreDidFinishInitialImport")
|
||||
fileprivate static let iCloudUbiquitousStoreWillAddAccount = Notification.Name(rawValue: "iCloudUbiquitousStoreWillAddAccount")
|
||||
fileprivate static let iCloudUbiquitousStoreDidAddAccount = Notification.Name(rawValue: "iCloudUbiquitousStoreDidAddAccount")
|
||||
fileprivate static let iCloudUbiquitousStoreWillRemoveAccount = Notification.Name(rawValue: "iCloudUbiquitousStoreWillRemoveAccount")
|
||||
fileprivate static let iCloudUbiquitousStoreDidRemoveAccount = Notification.Name(rawValue: "iCloudUbiquitousStoreDidRemoveAccount")
|
||||
fileprivate static let iCloudUbiquitousStoreWillRemoveContent = Notification.Name(rawValue: "iCloudUbiquitousStoreWillRemoveContent")
|
||||
fileprivate static let iCloudUbiquitousStoreDidRemoveContent = Notification.Name(rawValue: "iCloudUbiquitousStoreDidRemoveContent")
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,108 +0,0 @@
|
||||
//
|
||||
// ICloudStoreObserver.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
|
||||
|
||||
|
||||
#if os(iOS) || os(macOS)
|
||||
|
||||
// MARK: - ICloudStoreObserver
|
||||
|
||||
/**
|
||||
Implement the `ICloudStoreObserver` protocol to observe ubiquitous storage notifications from the specified iCloud store.
|
||||
Note that `ICloudStoreObserver` methods are only called when all the following conditions are true:
|
||||
- the observer is registered to the `ICloudStore` via the `ICloudStore.addObserver(_:)` method
|
||||
- the `ICloudStore` was added to a `DataStack`
|
||||
- the `ICloudStore` and the `DataStack` are still persisted in memory
|
||||
*/
|
||||
@available(*, deprecated, message: "Please see the release notes and Core Data documentation.")
|
||||
public protocol ICloudStoreObserver: class {
|
||||
|
||||
/**
|
||||
Notifies that the initial ubiquitous store import will complete
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreWillFinishUbiquitousStoreInitialImport(storage: ICloudStore, dataStack: DataStack)
|
||||
|
||||
/**
|
||||
Notifies that the initial ubiquitous store import completed
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreDidFinishUbiquitousStoreInitialImport(storage: ICloudStore, dataStack: DataStack)
|
||||
|
||||
/**
|
||||
Notifies that an iCloud account will be added to the coordinator
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreWillAddAccount(storage: ICloudStore, dataStack: DataStack)
|
||||
|
||||
/**
|
||||
Notifies that an iCloud account was added to the coordinator
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreDidAddAccount(storage: ICloudStore, dataStack: DataStack)
|
||||
|
||||
/**
|
||||
Notifies that an iCloud account will be removed from the coordinator
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreWillRemoveAccount(storage: ICloudStore, dataStack: DataStack)
|
||||
|
||||
/**
|
||||
Notifies that an iCloud account was removed from the coordinator
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreDidRemoveAccount(storage: ICloudStore, dataStack: DataStack)
|
||||
|
||||
/**
|
||||
Notifies that iCloud contents will be deleted
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreWillRemoveContent(storage: ICloudStore, dataStack: DataStack)
|
||||
|
||||
/**
|
||||
Notifies that iCloud contents were deleted
|
||||
|
||||
- parameter storage: the `ICloudStore` instance being observed
|
||||
- parameter dataStack: the `DataStack` that manages the peristent store
|
||||
*/
|
||||
func iCloudStoreDidRemoveContent(storage: ICloudStore, dataStack: DataStack)
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user