mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-01 10:57:45 +01:00
Compare commits
75 Commits
3.1.1
...
temp/devel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
981b560d53 | ||
|
|
c4c4dd55cd | ||
|
|
1ddbe20c86 | ||
|
|
da9e8c1550 | ||
|
|
ef0937fec4 | ||
|
|
35885b40de | ||
|
|
d669569196 | ||
|
|
ae919ff3c8 | ||
|
|
1a7a4690d1 | ||
|
|
b9b96d1a35 | ||
|
|
da3a9590ac | ||
|
|
6b3d75bea1 | ||
|
|
d44721fef0 | ||
|
|
3f268e8376 | ||
|
|
303fea4ebe | ||
|
|
77173cdad0 | ||
|
|
1e24a7d739 | ||
|
|
a3b33bedb8 | ||
|
|
eaf7544c50 | ||
|
|
67863120e0 | ||
|
|
1b0e305d9a | ||
|
|
91fda01071 | ||
|
|
feb0e30735 | ||
|
|
9c25336ff6 | ||
|
|
66bef87422 | ||
|
|
dd2949ee18 | ||
|
|
e0abb9b0af | ||
|
|
8ff163af30 | ||
|
|
19abedfa9f | ||
|
|
48828fdca3 | ||
|
|
9d65a27557 | ||
|
|
6d04806608 | ||
|
|
54129f7362 | ||
|
|
54c81d23f5 | ||
|
|
53ab140341 | ||
|
|
9dc4331b26 | ||
|
|
e6aa72fb5f | ||
|
|
274a54451a | ||
|
|
fe70b7a27d | ||
|
|
02a660e4a6 | ||
|
|
a543a4c94a | ||
|
|
fd14a18248 | ||
|
|
b0e2655bdf | ||
|
|
b6bc7c2edf | ||
|
|
1938f0d9de | ||
|
|
94e6db669f | ||
|
|
b1972b82f1 | ||
|
|
5ffaca1375 | ||
|
|
a73306fecb | ||
|
|
9f3db61ff7 | ||
|
|
e5ef4992d3 | ||
|
|
c0ae129b22 | ||
|
|
4aa1a63f9a | ||
|
|
4fc10afe1e | ||
|
|
8b77e4e5a0 | ||
|
|
258c237100 | ||
|
|
6948db516d | ||
|
|
b5d80fd272 | ||
|
|
cdcd7d0416 | ||
|
|
a5162239d5 | ||
|
|
1ad6ac5769 | ||
|
|
ecb3d0cfa0 | ||
|
|
81355fd9c5 | ||
|
|
97d7a276fe | ||
|
|
d72d1afe8b | ||
|
|
b97f6d6a0a | ||
|
|
818abfc1a1 | ||
|
|
cb6d5b015b | ||
|
|
494965de23 | ||
|
|
fe25a9aa36 | ||
|
|
f21e4e12e0 | ||
|
|
6055685c00 | ||
|
|
ee71442b08 | ||
|
|
8569c3c524 | ||
|
|
7ee027f44d |
@@ -1 +1 @@
|
|||||||
3.0.1
|
3.1
|
||||||
|
|||||||
29
.travis.yml
29
.travis.yml
@@ -1,5 +1,5 @@
|
|||||||
language: objective-c
|
language: objective-c
|
||||||
osx_image: xcode8.2
|
osx_image: xcode8.3
|
||||||
sudo: false
|
sudo: false
|
||||||
git:
|
git:
|
||||||
submodules: false
|
submodules: false
|
||||||
@@ -10,21 +10,22 @@ env:
|
|||||||
- LC_CTYPE=en_US.UTF-8
|
- LC_CTYPE=en_US.UTF-8
|
||||||
- LANG=en_US.UTF-8
|
- LANG=en_US.UTF-8
|
||||||
matrix:
|
matrix:
|
||||||
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
|
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.12 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.12 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="OS=3.1,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.1 RUN_TESTS="NO" POD_LINT="NO"
|
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
|
||||||
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.1 RUN_TESTS="NO" POD_LINT="NO"
|
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
|
||||||
- DESTINATION="OS=10.1,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.1 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.1 RUN_TESTS="YES" POD_LINT="NO"
|
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
||||||
before_install:
|
before_install:
|
||||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||||
- gem install xcpretty --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.18/Carthage.pkg"
|
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.23.0/Carthage.pkg"
|
||||||
- sudo installer -pkg "Carthage.pkg" -target /
|
- sudo installer -pkg "Carthage.pkg" -target /
|
||||||
- rm "Carthage.pkg"
|
- rm "Carthage.pkg"
|
||||||
before_script:
|
before_script:
|
||||||
@@ -37,8 +38,8 @@ script:
|
|||||||
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||||
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||||
fi
|
fi
|
||||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.2" -destination "OS=10.1,name=iPhone 7" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.2" -destination "OS=10.1,name=iPhone 7" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||||
- if [ $POD_LINT == "YES" ]; then
|
- if [ $POD_LINT == "YES" ]; then
|
||||||
pod lib lint --quick;
|
pod lib lint --quick;
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "CoreStore"
|
s.name = "CoreStore"
|
||||||
s.version = "3.1.1"
|
s.version = "4.0.1"
|
||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
|
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
|
||||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||||
|
|||||||
@@ -63,7 +63,6 @@
|
|||||||
82BA18D41C4BBD7100A0916E /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
|
82BA18D41C4BBD7100A0916E /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
|
||||||
82BA18D51C4BBD7100A0916E /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
|
82BA18D51C4BBD7100A0916E /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
|
||||||
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
||||||
82BA18D71C4BBD7100A0916E /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; };
|
|
||||||
82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; };
|
82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; };
|
||||||
82BA18DC1C4BBD9C00A0916E /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; };
|
82BA18DC1C4BBD9C00A0916E /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; };
|
||||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
|
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
|
||||||
@@ -80,11 +79,22 @@
|
|||||||
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
||||||
B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
||||||
B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */; };
|
B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */; };
|
||||||
B509C7F41E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* CoreStoreImportableAttributeType.swift */; };
|
B509C7F41E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; };
|
||||||
B509C7F51E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* CoreStoreImportableAttributeType.swift */; };
|
B509C7F51E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; };
|
||||||
B509C7F61E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* CoreStoreImportableAttributeType.swift */; };
|
B509C7F61E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; };
|
||||||
B509C7F71E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* CoreStoreImportableAttributeType.swift */; };
|
B509C7F71E54511B0061C547 /* ImportableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */; };
|
||||||
B51BE06A1B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; };
|
B512607F1E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; };
|
||||||
|
B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; };
|
||||||
|
B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; };
|
||||||
|
B51260821E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */; };
|
||||||
|
B51260891E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */; };
|
||||||
|
B512608A1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */; };
|
||||||
|
B512608B1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */; };
|
||||||
|
B512608C1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */; };
|
||||||
|
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260921E9B28F100402229 /* EntityIdentifier.swift */; };
|
||||||
|
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260921E9B28F100402229 /* EntityIdentifier.swift */; };
|
||||||
|
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260921E9B28F100402229 /* EntityIdentifier.swift */; };
|
||||||
|
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260921E9B28F100402229 /* EntityIdentifier.swift */; };
|
||||||
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
|
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
|
||||||
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
|
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
|
||||||
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
|
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
|
||||||
@@ -195,8 +205,27 @@
|
|||||||
B52DD1C71BE1F94600949AFE /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
|
B52DD1C71BE1F94600949AFE /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
|
||||||
B52DD1C81BE1F94600949AFE /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
|
B52DD1C81BE1F94600949AFE /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
|
||||||
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
||||||
B52DD1CA1BE1F94600949AFE /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; };
|
|
||||||
B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; };
|
B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; };
|
||||||
|
B52F742F1E9B50D0005F3DAC /* SchemaHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */; };
|
||||||
|
B52F74301E9B50D0005F3DAC /* SchemaHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */; };
|
||||||
|
B52F74311E9B50D0005F3DAC /* SchemaHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */; };
|
||||||
|
B52F74321E9B50D0005F3DAC /* SchemaHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */; };
|
||||||
|
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; };
|
||||||
|
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; };
|
||||||
|
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; };
|
||||||
|
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; };
|
||||||
|
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||||
|
B52F74421E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||||
|
B52F74431E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||||
|
B52F74441E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||||
|
B52F74451E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; };
|
||||||
|
B52F74461E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; };
|
||||||
|
B52F74471E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; };
|
||||||
|
B52F74481E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; };
|
||||||
|
B52F744A1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */; };
|
||||||
|
B52F744B1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */; };
|
||||||
|
B52F744C1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */; };
|
||||||
|
B52F744D1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */; };
|
||||||
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
||||||
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
||||||
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
||||||
@@ -263,10 +292,10 @@
|
|||||||
B5489F501CF603D5008B4978 /* FromTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* FromTests.swift */; };
|
B5489F501CF603D5008B4978 /* FromTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* FromTests.swift */; };
|
||||||
B5489F511CF603D5008B4978 /* FromTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* FromTests.swift */; };
|
B5489F511CF603D5008B4978 /* FromTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* FromTests.swift */; };
|
||||||
B5489F521CF603D5008B4978 /* FromTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* FromTests.swift */; };
|
B5489F521CF603D5008B4978 /* FromTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F4F1CF603D5008B4978 /* FromTests.swift */; };
|
||||||
B549F65E1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift */; };
|
B549F65E1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */; };
|
||||||
B549F65F1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift */; };
|
B549F65F1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */; };
|
||||||
B549F6601E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift */; };
|
B549F6601E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */; };
|
||||||
B549F6611E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift */; };
|
B549F6611E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */; };
|
||||||
B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */; };
|
B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */; };
|
||||||
B549F6741E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */; };
|
B549F6741E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */; };
|
||||||
B549F6751E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */; };
|
B549F6751E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */; };
|
||||||
@@ -354,7 +383,6 @@
|
|||||||
B56321B21BD6521C006C9394 /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
|
B56321B21BD6521C006C9394 /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
|
||||||
B56321B31BD6521C006C9394 /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
|
B56321B31BD6521C006C9394 /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
|
||||||
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
||||||
B56321B51BD6521C006C9394 /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; };
|
|
||||||
B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; };
|
B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; };
|
||||||
B56507941D3930BC000596DA /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B56507931D3930BC000596DA /* CoreData.framework */; };
|
B56507941D3930BC000596DA /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B56507931D3930BC000596DA /* CoreData.framework */; };
|
||||||
B56507961D3930C1000596DA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B56507951D3930C1000596DA /* Foundation.framework */; };
|
B56507961D3930C1000596DA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B56507951D3930C1000596DA /* Foundation.framework */; };
|
||||||
@@ -366,6 +394,42 @@
|
|||||||
B5677D3F1CD3B1E400322BFC /* 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 */; };
|
B5677D401CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5677D3C1CD3B1E400322BFC /* ICloudStoreObserver.swift */; };
|
||||||
B5677D411CD3B1E400322BFC /* 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 */; };
|
||||||
|
B56923C71EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */; };
|
||||||
|
B56923C91EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C81EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift */; };
|
||||||
|
B56923CA1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C81EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift */; };
|
||||||
|
B56923CB1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C81EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift */; };
|
||||||
|
B56923CC1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923C81EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift */; };
|
||||||
|
B56923E41EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DC1EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift */; };
|
||||||
|
B56923E51EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DC1EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift */; };
|
||||||
|
B56923E61EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DC1EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift */; };
|
||||||
|
B56923E71EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DC1EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift */; };
|
||||||
|
B56923E81EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DD1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift */; };
|
||||||
|
B56923E91EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DD1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift */; };
|
||||||
|
B56923EA1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DD1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift */; };
|
||||||
|
B56923EB1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DD1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift */; };
|
||||||
|
B56923EC1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DE1EB827F5007C4DC9 /* SchemaMappingProvider.swift */; };
|
||||||
|
B56923ED1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DE1EB827F5007C4DC9 /* SchemaMappingProvider.swift */; };
|
||||||
|
B56923EE1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DE1EB827F5007C4DC9 /* SchemaMappingProvider.swift */; };
|
||||||
|
B56923EF1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DE1EB827F5007C4DC9 /* SchemaMappingProvider.swift */; };
|
||||||
|
B56923F01EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */; };
|
||||||
|
B56923F11EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */; };
|
||||||
|
B56923F21EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */; };
|
||||||
|
B56923F31EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */; };
|
||||||
|
B56923F51EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */; };
|
||||||
|
B56923F61EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */; };
|
||||||
|
B56923F71EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */; };
|
||||||
|
B56923F81EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */; };
|
||||||
|
B56923FA1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; };
|
||||||
|
B56923FB1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; };
|
||||||
|
B56923FC1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; };
|
||||||
|
B56923FD1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; };
|
||||||
|
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||||
|
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||||
|
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||||
|
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||||
B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */; };
|
B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */; };
|
||||||
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965231B356B820075EE4A /* MigrationResult.swift */; };
|
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965231B356B820075EE4A /* MigrationResult.swift */; };
|
||||||
B57D27BE1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */; };
|
B57D27BE1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */; };
|
||||||
@@ -378,6 +442,10 @@
|
|||||||
B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
|
B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
|
||||||
B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
|
B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
|
||||||
B58B22F51C93C1BA00521925 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F03A53019C5C6DA005002A5 /* CoreStore.framework */; };
|
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 */; };
|
||||||
|
B58D0C651EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
|
||||||
|
B58D0C661EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
|
||||||
B596BBB21DD5A014001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
|
B596BBB21DD5A014001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
|
||||||
B596BBB31DD5A014001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
|
B596BBB31DD5A014001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
|
||||||
B596BBB41DD5A016001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
|
B596BBB41DD5A016001DCDD9 /* ConvenienceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */; };
|
||||||
@@ -402,6 +470,14 @@
|
|||||||
B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
||||||
B5A5F2691CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
B5A5F2691CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
||||||
B5A5F26A1CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
B5A5F26A1CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
||||||
|
B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */; };
|
||||||
|
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */; };
|
||||||
|
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */; };
|
||||||
|
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */; };
|
||||||
|
B5A9921F1EA898710091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||||
|
B5A992201EA898720091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||||
|
B5A992211EA898720091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||||
|
B5A992221EA898720091A2E3 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A9921E1EA898710091A2E3 /* UserInfo.swift */; };
|
||||||
B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
||||||
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
||||||
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */; };
|
||||||
@@ -413,6 +489,37 @@
|
|||||||
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
|
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
|
||||||
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
|
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
|
||||||
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; };
|
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; };
|
||||||
|
B5D339B41E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
|
||||||
|
B5D339B51E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
|
||||||
|
B5D339B61E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
|
||||||
|
B5D339D81E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; };
|
||||||
|
B5D339D91E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; };
|
||||||
|
B5D339DA1E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; };
|
||||||
|
B5D339DB1E9489AB00C880DE /* CoreStoreObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */; };
|
||||||
|
B5D339DD1E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; };
|
||||||
|
B5D339DE1E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; };
|
||||||
|
B5D339DF1E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; };
|
||||||
|
B5D339E01E9489C700C880DE /* DynamicObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339DC1E9489C700C880DE /* DynamicObject.swift */; };
|
||||||
|
B5D339E21E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; };
|
||||||
|
B5D339E31E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; };
|
||||||
|
B5D339E41E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; };
|
||||||
|
B5D339E51E948C3600C880DE /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E11E948C3600C880DE /* Value.swift */; };
|
||||||
|
B5D339E71E9493A500C880DE /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E61E9493A500C880DE /* Entity.swift */; };
|
||||||
|
B5D339E81E9493A500C880DE /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E61E9493A500C880DE /* Entity.swift */; };
|
||||||
|
B5D339E91E9493A500C880DE /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E61E9493A500C880DE /* Entity.swift */; };
|
||||||
|
B5D339EA1E9493A500C880DE /* Entity.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339E61E9493A500C880DE /* Entity.swift */; };
|
||||||
|
B5D339EC1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */; };
|
||||||
|
B5D339ED1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */; };
|
||||||
|
B5D339EE1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */; };
|
||||||
|
B5D339EF1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */; };
|
||||||
|
B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */; };
|
||||||
|
B5D339F21E94AF5800C880DE /* CoreStoreStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */; };
|
||||||
|
B5D339F31E94AF5800C880DE /* CoreStoreStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */; };
|
||||||
|
B5D339F41E94AF5800C880DE /* CoreStoreStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */; };
|
||||||
|
B5D33A011E96012400C880DE /* Relationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D33A001E96012400C880DE /* Relationship.swift */; };
|
||||||
|
B5D33A021E96012400C880DE /* Relationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D33A001E96012400C880DE /* Relationship.swift */; };
|
||||||
|
B5D33A031E96012400C880DE /* Relationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D33A001E96012400C880DE /* Relationship.swift */; };
|
||||||
|
B5D33A041E96012400C880DE /* Relationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D33A001E96012400C880DE /* Relationship.swift */; };
|
||||||
B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; };
|
B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; };
|
||||||
B5D39A0219FD00C9000E91BB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5D39A0119FD00C9000E91BB /* Foundation.framework */; };
|
B5D39A0219FD00C9000E91BB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5D39A0119FD00C9000E91BB /* Foundation.framework */; };
|
||||||
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; };
|
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */; };
|
||||||
@@ -464,6 +571,10 @@
|
|||||||
B5E2222C1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */; };
|
B5E2222C1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */; };
|
||||||
B5E2222D1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */; };
|
B5E2222D1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */; };
|
||||||
B5E2222E1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */; };
|
B5E2222E1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */; };
|
||||||
|
B5E41EC01EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */; };
|
||||||
|
B5E41EC11EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */; };
|
||||||
|
B5E41EC21EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */; };
|
||||||
|
B5E41EC31EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */; };
|
||||||
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */; };
|
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */; };
|
||||||
B5E834BB1B7691F3001D3D50 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834BA1B7691F3001D3D50 /* Functions.swift */; };
|
B5E834BB1B7691F3001D3D50 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834BA1B7691F3001D3D50 /* Functions.swift */; };
|
||||||
B5E84EDF1AFF84500064E85B /* DataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDB1AFF84500064E85B /* DataStack.swift */; };
|
B5E84EDF1AFF84500064E85B /* DataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDB1AFF84500064E85B /* DataStack.swift */; };
|
||||||
@@ -612,8 +723,10 @@
|
|||||||
B501FDE61CA8D20500BE22EF /* CSListObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSListObserver.swift; sourceTree = "<group>"; };
|
B501FDE61CA8D20500BE22EF /* CSListObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSListObserver.swift; sourceTree = "<group>"; };
|
||||||
B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Transaction.swift"; sourceTree = "<group>"; };
|
B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Transaction.swift"; sourceTree = "<group>"; };
|
||||||
B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Setup.swift"; sourceTree = "<group>"; };
|
B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Setup.swift"; sourceTree = "<group>"; };
|
||||||
B509C7F31E54511B0061C547 /* CoreStoreImportableAttributeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreImportableAttributeType.swift; sourceTree = "<group>"; };
|
B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportableAttributeType.swift; sourceTree = "<group>"; };
|
||||||
B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectModel+Setup.swift"; sourceTree = "<group>"; };
|
B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Convenience.swift"; sourceTree = "<group>"; };
|
||||||
|
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSEntityDescription+DynamicModel.swift"; sourceTree = "<group>"; };
|
||||||
|
B51260921E9B28F100402229 /* EntityIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntityIdentifier.swift; sourceTree = "<group>"; };
|
||||||
B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+CustomDebugStringConvertible.swift"; sourceTree = "<group>"; };
|
B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+CustomDebugStringConvertible.swift"; sourceTree = "<group>"; };
|
||||||
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFetchedResultsController+Convenience.swift"; sourceTree = "<group>"; };
|
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFetchedResultsController+Convenience.swift"; sourceTree = "<group>"; };
|
||||||
B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverTests.swift; sourceTree = "<group>"; };
|
B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverTests.swift; sourceTree = "<group>"; };
|
||||||
@@ -631,6 +744,11 @@
|
|||||||
B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSaveResult.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; };
|
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; };
|
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>"; };
|
||||||
|
B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicSchema.swift; sourceTree = "<group>"; };
|
||||||
|
B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||||
|
B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||||
|
B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreSchema.swift; sourceTree = "<group>"; };
|
||||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Logging.swift"; sourceTree = "<group>"; };
|
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Logging.swift"; sourceTree = "<group>"; };
|
||||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
|
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
|
||||||
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
||||||
@@ -649,7 +767,7 @@
|
|||||||
B5489F451CF5F017008B4978 /* TransactionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionTests.swift; sourceTree = "<group>"; };
|
B5489F451CF5F017008B4978 /* TransactionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionTests.swift; sourceTree = "<group>"; };
|
||||||
B5489F4B1CF5F743008B4978 /* BaseTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestCase.swift; sourceTree = "<group>"; };
|
B5489F4B1CF5F743008B4978 /* BaseTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestCase.swift; sourceTree = "<group>"; };
|
||||||
B5489F4F1CF603D5008B4978 /* FromTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FromTests.swift; sourceTree = "<group>"; };
|
B5489F4F1CF603D5008B4978 /* FromTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FromTests.swift; sourceTree = "<group>"; };
|
||||||
B549F65D1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreQueryableAttributeType.swift; sourceTree = "<group>"; };
|
B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryableAttributeType.swift; sourceTree = "<group>"; };
|
||||||
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataNativeType.swift; sourceTree = "<group>"; };
|
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataNativeType.swift; sourceTree = "<group>"; };
|
||||||
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchedResultsControllerDelegate.swift; sourceTree = "<group>"; };
|
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchedResultsControllerDelegate.swift; sourceTree = "<group>"; };
|
||||||
B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = "<group>"; };
|
B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = "<group>"; };
|
||||||
@@ -674,11 +792,21 @@
|
|||||||
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; };
|
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; };
|
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>"; };
|
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>"; };
|
||||||
|
B56923DD1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InferredSchemaMappingProvider.swift; sourceTree = "<group>"; };
|
||||||
|
B56923DE1EB827F5007C4DC9 /* SchemaMappingProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaMappingProvider.swift; sourceTree = "<group>"; };
|
||||||
|
B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodeSchemaMappingProvider.swift; sourceTree = "<group>"; };
|
||||||
|
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>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||||
B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.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>"; };
|
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>"; };
|
B57D27C11D0BC20100539C58 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
|
||||||
B58085741CDF7F00004C2EEB /* SetupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupTests.swift; sourceTree = "<group>"; };
|
B58085741CDF7F00004C2EEB /* SetupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupTests.swift; sourceTree = "<group>"; };
|
||||||
|
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+DynamicModel.swift"; sourceTree = "<group>"; };
|
||||||
B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvenienceTests.swift; sourceTree = "<group>"; };
|
B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvenienceTests.swift; sourceTree = "<group>"; };
|
||||||
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchableSource.swift; sourceTree = "<group>"; };
|
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>"; };
|
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryableSource.swift; sourceTree = "<group>"; };
|
||||||
@@ -686,6 +814,8 @@
|
|||||||
B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStore.swift; sourceTree = "<group>"; };
|
B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStore.swift; sourceTree = "<group>"; };
|
||||||
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.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>"; };
|
B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = "<group>"; };
|
||||||
|
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; };
|
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
|
||||||
B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreBridge.swift; sourceTree = "<group>"; };
|
B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreBridge.swift; sourceTree = "<group>"; };
|
||||||
B5BDC91A1C202269008147CD /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cartfile; path = ../Cartfile; sourceTree = "<group>"; };
|
B5BDC91A1C202269008147CD /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cartfile; path = ../Cartfile; sourceTree = "<group>"; };
|
||||||
@@ -693,6 +823,14 @@
|
|||||||
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = "<group>"; };
|
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = "<group>"; };
|
||||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = "<group>"; };
|
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = "<group>"; };
|
||||||
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = "<group>"; };
|
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = "<group>"; };
|
||||||
|
B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicModelTests.swift; sourceTree = "<group>"; };
|
||||||
|
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreObject.swift; sourceTree = "<group>"; };
|
||||||
|
B5D339DC1E9489C700C880DE /* DynamicObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicObject.swift; sourceTree = "<group>"; };
|
||||||
|
B5D339E11E948C3600C880DE /* Value.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Value.swift; sourceTree = "<group>"; };
|
||||||
|
B5D339E61E9493A500C880DE /* Entity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Entity.swift; sourceTree = "<group>"; };
|
||||||
|
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Querying.swift"; sourceTree = "<group>"; };
|
||||||
|
B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreStrings.swift; sourceTree = "<group>"; };
|
||||||
|
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>"; };
|
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; };
|
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>"; };
|
B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacySQLiteStore.swift; sourceTree = "<group>"; };
|
||||||
@@ -712,6 +850,7 @@
|
|||||||
B5E1B5A71CAA49E2007FD580 /* CSDataStack+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSDataStack+Migrating.swift"; sourceTree = "<group>"; };
|
B5E1B5A71CAA49E2007FD580 /* CSDataStack+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSDataStack+Migrating.swift"; sourceTree = "<group>"; };
|
||||||
B5E222221CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSynchronousDataTransaction.swift; sourceTree = "<group>"; };
|
B5E222221CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSynchronousDataTransaction.swift; sourceTree = "<group>"; };
|
||||||
B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataTransaction.swift; sourceTree = "<group>"; };
|
B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataTransaction.swift; sourceTree = "<group>"; };
|
||||||
|
B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DynamicSchema+Convenience.swift"; sourceTree = "<group>"; };
|
||||||
B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseDataTransaction+Importing.swift"; sourceTree = "<group>"; };
|
B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseDataTransaction+Importing.swift"; sourceTree = "<group>"; };
|
||||||
B5E834BA1B7691F3001D3D50 /* Functions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = "<group>"; };
|
B5E834BA1B7691F3001D3D50 /* Functions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = "<group>"; };
|
||||||
B5E84ED81AFF82360064E85B /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
|
B5E84ED81AFF82360064E85B /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -892,6 +1031,7 @@
|
|||||||
B5489F4A1CF5F743008B4978 /* BaseTests */,
|
B5489F4A1CF5F743008B4978 /* BaseTests */,
|
||||||
B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */,
|
B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */,
|
||||||
B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */,
|
B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */,
|
||||||
|
B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */,
|
||||||
B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */,
|
B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */,
|
||||||
B52557871D02DE8100E51965 /* FetchTests.swift */,
|
B52557871D02DE8100E51965 /* FetchTests.swift */,
|
||||||
B5489F4F1CF603D5008B4978 /* FromTests.swift */,
|
B5489F4F1CF603D5008B4978 /* FromTests.swift */,
|
||||||
@@ -962,6 +1102,17 @@
|
|||||||
name = Observing;
|
name = Observing;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
B52F74391E9B8724005F3DAC /* Dynamic Schema */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */,
|
||||||
|
B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */,
|
||||||
|
B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */,
|
||||||
|
B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */,
|
||||||
|
);
|
||||||
|
name = "Dynamic Schema";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B53FBA101CAB607000F0D40A /* Convenience */ = {
|
B53FBA101CAB607000F0D40A /* Convenience */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -977,6 +1128,7 @@
|
|||||||
children = (
|
children = (
|
||||||
B546F9571C99B17400D5AC55 /* CSCoreStore+Setup.swift */,
|
B546F9571C99B17400D5AC55 /* CSCoreStore+Setup.swift */,
|
||||||
B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */,
|
B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */,
|
||||||
|
B56923D71EB8279B007C4DC9 /* Dynamic Models */,
|
||||||
B546F9621C9A140E00D5AC55 /* StorageInterfaces */,
|
B546F9621C9A140E00D5AC55 /* StorageInterfaces */,
|
||||||
);
|
);
|
||||||
name = Setup;
|
name = Setup;
|
||||||
@@ -1025,6 +1177,35 @@
|
|||||||
name = Transactions;
|
name = Transactions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
B56923D71EB8279B007C4DC9 /* Dynamic Models */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B56923D81EB827B1007C4DC9 /* Dynamic Schema */,
|
||||||
|
);
|
||||||
|
name = "Dynamic Models";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B56923D81EB827B1007C4DC9 /* Dynamic Schema */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */,
|
||||||
|
B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */,
|
||||||
|
B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */,
|
||||||
|
);
|
||||||
|
name = "Dynamic Schema";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B56923DB1EB827F5007C4DC9 /* Schema Mapping Providers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B56923DE1EB827F5007C4DC9 /* SchemaMappingProvider.swift */,
|
||||||
|
B56923DD1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift */,
|
||||||
|
B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */,
|
||||||
|
B56923DC1EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift */,
|
||||||
|
);
|
||||||
|
name = "Schema Mapping Providers";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B56964D11B22FF700075EE4A /* Migrating */ = {
|
B56964D11B22FF700075EE4A /* Migrating */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1034,16 +1215,33 @@
|
|||||||
B56007151B4018AB00A9A8F9 /* MigrationChain.swift */,
|
B56007151B4018AB00A9A8F9 /* MigrationChain.swift */,
|
||||||
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */,
|
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */,
|
||||||
B56965231B356B820075EE4A /* MigrationResult.swift */,
|
B56965231B356B820075EE4A /* MigrationResult.swift */,
|
||||||
|
B56923DB1EB827F5007C4DC9 /* Schema Mapping Providers */,
|
||||||
);
|
);
|
||||||
name = Migrating;
|
name = Migrating;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
B57358D71E5A7F9B0094B50A /* Dynamic Models */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */,
|
||||||
|
B52F74391E9B8724005F3DAC /* Dynamic Schema */,
|
||||||
|
B5D339DC1E9489C700C880DE /* DynamicObject.swift */,
|
||||||
|
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */,
|
||||||
|
B5D339E61E9493A500C880DE /* Entity.swift */,
|
||||||
|
B5D33A001E96012400C880DE /* Relationship.swift */,
|
||||||
|
B5D339E11E948C3600C880DE /* Value.swift */,
|
||||||
|
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */,
|
||||||
|
);
|
||||||
|
name = "Dynamic Models";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B5A5F26B1CAFF8D0004AB9AF /* Swift */ = {
|
B5A5F26B1CAFF8D0004AB9AF /* Swift */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
2F291E2619C6D3CF007AF63F /* CoreStore.swift */,
|
2F291E2619C6D3CF007AF63F /* CoreStore.swift */,
|
||||||
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */,
|
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */,
|
||||||
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */,
|
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */,
|
||||||
|
B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */,
|
||||||
B5E84EDA1AFF84500064E85B /* Setup */,
|
B5E84EDA1AFF84500064E85B /* Setup */,
|
||||||
B5E84EE21AFF84610064E85B /* Logging */,
|
B5E84EE21AFF84610064E85B /* Logging */,
|
||||||
B5E84EE91AFF846E0064E85B /* Transactions */,
|
B5E84EE91AFF846E0064E85B /* Transactions */,
|
||||||
@@ -1114,7 +1312,7 @@
|
|||||||
B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */,
|
B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */,
|
||||||
B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */,
|
B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */,
|
||||||
B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */,
|
B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */,
|
||||||
B509C7F31E54511B0061C547 /* CoreStoreImportableAttributeType.swift */,
|
B509C7F31E54511B0061C547 /* ImportableAttributeType.swift */,
|
||||||
);
|
);
|
||||||
name = Importing;
|
name = Importing;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1124,6 +1322,7 @@
|
|||||||
children = (
|
children = (
|
||||||
B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */,
|
B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */,
|
||||||
B5E84EDB1AFF84500064E85B /* DataStack.swift */,
|
B5E84EDB1AFF84500064E85B /* DataStack.swift */,
|
||||||
|
B57358D71E5A7F9B0094B50A /* Dynamic Models */,
|
||||||
B5FE4DA01C84818B00FA6A91 /* StorageInterfaces */,
|
B5FE4DA01C84818B00FA6A91 /* StorageInterfaces */,
|
||||||
);
|
);
|
||||||
name = Setup;
|
name = Setup;
|
||||||
@@ -1159,12 +1358,13 @@
|
|||||||
B5E84EFD1AFF847B0064E85B /* Fetching and Querying */ = {
|
B5E84EFD1AFF847B0064E85B /* Fetching and Querying */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
|
||||||
B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */,
|
B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */,
|
||||||
B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */,
|
B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */,
|
||||||
B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */,
|
B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */,
|
||||||
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */,
|
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */,
|
||||||
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */,
|
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */,
|
||||||
B549F65D1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift */,
|
B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */,
|
||||||
B5E84F0A1AFF847B0064E85B /* Protocol Clauses */,
|
B5E84F0A1AFF847B0064E85B /* Protocol Clauses */,
|
||||||
B5E84EFF1AFF847B0064E85B /* Concrete Clauses */,
|
B5E84EFF1AFF847B0064E85B /* Concrete Clauses */,
|
||||||
);
|
);
|
||||||
@@ -1211,8 +1411,11 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
B5E84F271AFF84920064E85B /* NSManagedObject+Convenience.swift */,
|
B5E84F271AFF84920064E85B /* NSManagedObject+Convenience.swift */,
|
||||||
|
B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */,
|
||||||
B5FAD6A81B50A4B300714891 /* Progress+Convenience.swift */,
|
B5FAD6A81B50A4B300714891 /* Progress+Convenience.swift */,
|
||||||
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */,
|
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */,
|
||||||
|
B5A9921E1EA898710091A2E3 /* UserInfo.swift */,
|
||||||
|
B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */,
|
||||||
);
|
);
|
||||||
name = Convenience;
|
name = Convenience;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1222,17 +1425,21 @@
|
|||||||
children = (
|
children = (
|
||||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
|
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
|
||||||
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
|
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
|
||||||
|
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
|
||||||
|
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
|
||||||
|
B51260921E9B28F100402229 /* EntityIdentifier.swift */,
|
||||||
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */,
|
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */,
|
||||||
B5E834BA1B7691F3001D3D50 /* Functions.swift */,
|
B5E834BA1B7691F3001D3D50 /* Functions.swift */,
|
||||||
B5FAD6AB1B51285300714891 /* MigrationManager.swift */,
|
B5FAD6AB1B51285300714891 /* MigrationManager.swift */,
|
||||||
B5E84F2B1AFF849C0064E85B /* NotificationObserver.swift */,
|
B5E84F2B1AFF849C0064E85B /* NotificationObserver.swift */,
|
||||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
||||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
|
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
|
||||||
|
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */,
|
||||||
B5E84F2C1AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift */,
|
B5E84F2C1AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift */,
|
||||||
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */,
|
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */,
|
||||||
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */,
|
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */,
|
||||||
B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */,
|
B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */,
|
||||||
B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */,
|
B56923C81EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift */,
|
||||||
B5FEC18D1C9166E200532541 /* NSPersistentStore+Setup.swift */,
|
B5FEC18D1C9166E200532541 /* NSPersistentStore+Setup.swift */,
|
||||||
B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */,
|
B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */,
|
||||||
B5E84F2D1AFF849C0064E85B /* WeakObject.swift */,
|
B5E84F2D1AFF849C0064E85B /* WeakObject.swift */,
|
||||||
@@ -1565,20 +1772,27 @@
|
|||||||
B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */,
|
B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */,
|
||||||
B5ECDBF91CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
B5ECDBF91CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||||
B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||||
|
B56923F51EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||||
B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */,
|
B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */,
|
||||||
|
B51260891E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||||
B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */,
|
B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */,
|
||||||
B529C2041CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */,
|
B529C2041CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */,
|
||||||
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */,
|
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */,
|
||||||
B5E84F131AFF847B0064E85B /* Where.swift in Sources */,
|
B5E84F131AFF847B0064E85B /* Where.swift in Sources */,
|
||||||
|
B5D339D81E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||||
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||||
|
B56923FA1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||||
B596BBBB1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
B596BBBB1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||||
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||||
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||||
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||||
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||||
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||||
|
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||||
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||||
|
B5A9921F1EA898710091A2E3 /* UserInfo.swift in Sources */,
|
||||||
B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */,
|
B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||||
|
B5D339E21E948C3600C880DE /* Value.swift in Sources */,
|
||||||
B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */,
|
B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */,
|
||||||
B53FBA0B1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
B53FBA0B1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
||||||
B5E84F141AFF847B0064E85B /* DataStack+Querying.swift in Sources */,
|
B5E84F141AFF847B0064E85B /* DataStack+Querying.swift in Sources */,
|
||||||
@@ -1589,14 +1803,16 @@
|
|||||||
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||||
B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||||
B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||||
|
B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||||
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
|
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
|
||||||
B5E1B59D1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
B5E1B59D1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
||||||
B5ECDC231CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
B5ECDC231CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
||||||
B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
||||||
B509C7F41E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */,
|
B509C7F41E54511B0061C547 /* ImportableAttributeType.swift in Sources */,
|
||||||
B5E84F0E1AFF847B0064E85B /* Tweak.swift in Sources */,
|
B5E84F0E1AFF847B0064E85B /* Tweak.swift in Sources */,
|
||||||
B5E1B5931CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
|
B5E1B5931CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
|
||||||
B5ECDC291CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
B5ECDC291CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||||
|
B56923F01EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
|
||||||
B5E84F121AFF847B0064E85B /* OrderBy.swift in Sources */,
|
B5E84F121AFF847B0064E85B /* OrderBy.swift in Sources */,
|
||||||
B546F9581C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
B546F9581C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
||||||
B5677D3D1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
B5677D3D1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||||
@@ -1606,6 +1822,7 @@
|
|||||||
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||||
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
||||||
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
||||||
|
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
B5FE4DA21C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
B5FE4DA21C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||||
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||||
B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||||
@@ -1621,11 +1838,14 @@
|
|||||||
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */,
|
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */,
|
||||||
B5FE4DAC1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
B5FE4DAC1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||||
B501FDE71CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
B501FDE71CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||||
|
B5E41EC01EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||||
B501FDE21CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
B501FDE21CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||||
2F291E2719C6D3CF007AF63F /* CoreStore.swift in Sources */,
|
2F291E2719C6D3CF007AF63F /* CoreStore.swift in Sources */,
|
||||||
B5ECDC111CA816E500C7F112 /* CSTweak.swift in Sources */,
|
B5ECDC111CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||||
|
B56923C41EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||||
B5E84F411AFF8CCD0064E85B /* ClauseTypes.swift in Sources */,
|
B5E84F411AFF8CCD0064E85B /* ClauseTypes.swift in Sources */,
|
||||||
B5E84F0D1AFF847B0064E85B /* BaseDataTransaction+Querying.swift in Sources */,
|
B5E84F0D1AFF847B0064E85B /* BaseDataTransaction+Querying.swift in Sources */,
|
||||||
|
B52F74451E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
|
||||||
B5FAD6AC1B51285300714891 /* MigrationManager.swift in Sources */,
|
B5FAD6AC1B51285300714891 /* MigrationManager.swift in Sources */,
|
||||||
B5E84EF61AFF846E0064E85B /* DataStack+Transaction.swift in Sources */,
|
B5E84EF61AFF846E0064E85B /* DataStack+Transaction.swift in Sources */,
|
||||||
B5FEC18E1C9166E200532541 /* NSPersistentStore+Setup.swift in Sources */,
|
B5FEC18E1C9166E200532541 /* NSPersistentStore+Setup.swift in Sources */,
|
||||||
@@ -1637,21 +1857,29 @@
|
|||||||
B5E84F231AFF84860064E85B /* ListMonitor.swift in Sources */,
|
B5E84F231AFF84860064E85B /* ListMonitor.swift in Sources */,
|
||||||
B5E84EF71AFF846E0064E85B /* UnsafeDataTransaction.swift in Sources */,
|
B5E84EF71AFF846E0064E85B /* UnsafeDataTransaction.swift in Sources */,
|
||||||
B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */,
|
B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */,
|
||||||
|
B5D339DD1E9489C700C880DE /* DynamicObject.swift in Sources */,
|
||||||
B5A5F2661CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
B5A5F2661CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
||||||
B5ECDBE51CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
B5ECDBE51CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
||||||
B5519A4A1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
B5519A4A1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
||||||
|
B52F742F1E9B50D0005F3DAC /* SchemaHistory.swift in Sources */,
|
||||||
B5E84EF51AFF846E0064E85B /* BaseDataTransaction.swift in Sources */,
|
B5E84EF51AFF846E0064E85B /* BaseDataTransaction.swift in Sources */,
|
||||||
B5E84EFB1AFF846E0064E85B /* SaveResult.swift in Sources */,
|
B5E84EFB1AFF846E0064E85B /* SaveResult.swift in Sources */,
|
||||||
|
B5D339EC1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */,
|
||||||
B5E84F0F1AFF847B0064E85B /* From.swift in Sources */,
|
B5E84F0F1AFF847B0064E85B /* From.swift in Sources */,
|
||||||
B5FAD6A91B50A4B400714891 /* Progress+Convenience.swift in Sources */,
|
B5FAD6A91B50A4B400714891 /* Progress+Convenience.swift in Sources */,
|
||||||
B5E84EFC1AFF846E0064E85B /* SynchronousDataTransaction.swift in Sources */,
|
B5E84EFC1AFF846E0064E85B /* SynchronousDataTransaction.swift in Sources */,
|
||||||
B5E222231CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
B5E222231CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||||
B5E84F281AFF84920064E85B /* NSManagedObject+Convenience.swift in Sources */,
|
B5E84F281AFF84920064E85B /* NSManagedObject+Convenience.swift in Sources */,
|
||||||
B51BE06A1B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift in Sources */,
|
B52F744A1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||||
B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
B5AEFAB51C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||||
B5E2222A1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
B5E2222A1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
||||||
B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */,
|
B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */,
|
||||||
|
B56923E81EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||||
|
B5D33A011E96012400C880DE /* Relationship.swift in Sources */,
|
||||||
B5E84EE81AFF84610064E85B /* CoreStoreLogger.swift in Sources */,
|
B5E84EE81AFF84610064E85B /* CoreStoreLogger.swift in Sources */,
|
||||||
|
B56923C91EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||||
|
B56923E41EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */,
|
||||||
|
B58D0C631EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */,
|
||||||
B533C4DB1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
B533C4DB1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
||||||
B559CD491CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
B559CD491CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||||
B5ECDC2F1CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
B5ECDC2F1CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||||
@@ -1660,22 +1888,28 @@
|
|||||||
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
|
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
|
||||||
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||||
B538BA771D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
B538BA771D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||||
|
B512607F1E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||||
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */,
|
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */,
|
||||||
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
|
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
|
||||||
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||||
B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||||
B53FBA1E1CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
B53FBA1E1CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||||
B549F65E1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */,
|
B549F65E1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||||
B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */,
|
B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */,
|
||||||
B559CD431CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
B559CD431CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
||||||
|
B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||||
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||||
|
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||||
|
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||||
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||||
|
B56923EC1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||||
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */,
|
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */,
|
||||||
B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */,
|
B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */,
|
||||||
B53FBA041CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
B53FBA041CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||||
B5E84EF41AFF846E0064E85B /* AsynchronousDataTransaction.swift in Sources */,
|
B5E84EF41AFF846E0064E85B /* AsynchronousDataTransaction.swift in Sources */,
|
||||||
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||||
B546F95D1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
B546F95D1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||||
|
B5D339E71E9493A500C880DE /* Entity.swift in Sources */,
|
||||||
B5ECDC0B1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
B5ECDC0B1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||||
B5E84F151AFF847B0064E85B /* CoreStore+Querying.swift in Sources */,
|
B5E84F151AFF847B0064E85B /* CoreStore+Querying.swift in Sources */,
|
||||||
B5E84F241AFF84860064E85B /* ListObserver.swift in Sources */,
|
B5E84F241AFF84860064E85B /* ListObserver.swift in Sources */,
|
||||||
@@ -1695,6 +1929,7 @@
|
|||||||
B5DC47C61C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */,
|
B5DC47C61C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */,
|
||||||
B525576C1CFAF18F00E51965 /* IntoTests.swift in Sources */,
|
B525576C1CFAF18F00E51965 /* IntoTests.swift in Sources */,
|
||||||
B5220E0C1D0D0D19009BC71E /* ImportTests.swift in Sources */,
|
B5220E0C1D0D0D19009BC71E /* ImportTests.swift in Sources */,
|
||||||
|
B5D339B41E925C2B00C880DE /* DynamicModelTests.swift in Sources */,
|
||||||
B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */,
|
B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */,
|
||||||
B52557881D02DE8100E51965 /* FetchTests.swift in Sources */,
|
B52557881D02DE8100E51965 /* FetchTests.swift in Sources */,
|
||||||
B5489F501CF603D5008B4978 /* FromTests.swift in Sources */,
|
B5489F501CF603D5008B4978 /* FromTests.swift in Sources */,
|
||||||
@@ -1721,20 +1956,27 @@
|
|||||||
82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */,
|
82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */,
|
||||||
B5ECDBFB1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
B5ECDBFB1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||||
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||||
|
B56923F61EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||||
82BA18A21C4BBD1D00A0916E /* CoreStoreError.swift in Sources */,
|
82BA18A21C4BBD1D00A0916E /* CoreStoreError.swift in Sources */,
|
||||||
|
B512608A1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||||
82BA18B21C4BBD3900A0916E /* ImportableObject.swift in Sources */,
|
82BA18B21C4BBD3900A0916E /* ImportableObject.swift in Sources */,
|
||||||
B529C2061CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */,
|
B529C2061CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */,
|
||||||
82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */,
|
82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */,
|
||||||
82BA18AB1C4BBD3100A0916E /* AsynchronousDataTransaction.swift in Sources */,
|
82BA18AB1C4BBD3100A0916E /* AsynchronousDataTransaction.swift in Sources */,
|
||||||
|
B5D339D91E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||||
82BA18CE1C4BBD7100A0916E /* FetchedResultsControllerDelegate.swift in Sources */,
|
82BA18CE1C4BBD7100A0916E /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||||
|
B56923FB1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||||
B596BBBC1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
B596BBBC1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||||
B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||||
B5ECDC071CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
B5ECDC071CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||||
B5E1B59A1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
B5E1B59A1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||||
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||||
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||||
|
B52F74421E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||||
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||||
|
B5A992201EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||||
B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||||
|
B5D339E31E948C3600C880DE /* Value.swift in Sources */,
|
||||||
82BA18C51C4BBD5300A0916E /* ListObserver.swift in Sources */,
|
82BA18C51C4BBD5300A0916E /* ListObserver.swift in Sources */,
|
||||||
B53FBA0D1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
B53FBA0D1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
||||||
82BA18C21C4BBD5300A0916E /* ObjectMonitor.swift in Sources */,
|
82BA18C21C4BBD5300A0916E /* ObjectMonitor.swift in Sources */,
|
||||||
@@ -1745,14 +1987,16 @@
|
|||||||
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||||
B53FBA141CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
B53FBA141CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||||
B5E1B5AA1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
B5E1B5AA1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||||
|
B5D339F21E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||||
B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||||
B5E1B59F1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
B5E1B59F1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
||||||
B5ECDC251CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
B5ECDC251CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
||||||
B549F6741E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
B549F6741E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
||||||
B509C7F51E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */,
|
B509C7F51E54511B0061C547 /* ImportableAttributeType.swift in Sources */,
|
||||||
82BA18B31C4BBD3900A0916E /* ImportableUniqueObject.swift in Sources */,
|
82BA18B31C4BBD3900A0916E /* ImportableUniqueObject.swift in Sources */,
|
||||||
B5E1B5951CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
|
B5E1B5951CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
|
||||||
B5ECDC2B1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
B5ECDC2B1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||||
|
B56923F11EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
|
||||||
82BA18A11C4BBD1D00A0916E /* CoreStore.swift in Sources */,
|
82BA18A11C4BBD1D00A0916E /* CoreStore.swift in Sources */,
|
||||||
B546F9591C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
B546F9591C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
||||||
B5677D3F1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
B5677D3F1CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||||
@@ -1762,6 +2006,7 @@
|
|||||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||||
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
||||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||||
|
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||||
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||||
B5DBE2D31C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
B5DBE2D31C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||||
@@ -1777,11 +2022,14 @@
|
|||||||
82BA18D41C4BBD7100A0916E /* NSManagedObjectContext+Querying.swift in Sources */,
|
82BA18D41C4BBD7100A0916E /* NSManagedObjectContext+Querying.swift in Sources */,
|
||||||
82BA18D51C4BBD7100A0916E /* NSManagedObjectContext+Setup.swift in Sources */,
|
82BA18D51C4BBD7100A0916E /* NSManagedObjectContext+Setup.swift in Sources */,
|
||||||
B501FDE91CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
B501FDE91CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||||
|
B5E41EC11EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||||
B501FDE41CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
B501FDE41CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||||
B5FE4DA31C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
B5FE4DA31C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||||
B5ECDC131CA816E500C7F112 /* CSTweak.swift in Sources */,
|
B5ECDC131CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||||
|
B56923C51EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||||
82BA18C91C4BBD5900A0916E /* MigrationType.swift in Sources */,
|
82BA18C91C4BBD5900A0916E /* MigrationType.swift in Sources */,
|
||||||
82BA18D01C4BBD7100A0916E /* MigrationManager.swift in Sources */,
|
82BA18D01C4BBD7100A0916E /* MigrationManager.swift in Sources */,
|
||||||
|
B52F74461E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
|
||||||
82BA18C61C4BBD5900A0916E /* DataStack+Migration.swift in Sources */,
|
82BA18C61C4BBD5900A0916E /* DataStack+Migration.swift in Sources */,
|
||||||
B59851491C90289D00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
B59851491C90289D00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
||||||
B5E1B5A41CAA4365007FD580 /* CSCoreStore+Observing.swift in Sources */,
|
B5E1B5A41CAA4365007FD580 /* CSCoreStore+Observing.swift in Sources */,
|
||||||
@@ -1793,21 +2041,29 @@
|
|||||||
82BA18D11C4BBD7100A0916E /* NotificationObserver.swift in Sources */,
|
82BA18D11C4BBD7100A0916E /* NotificationObserver.swift in Sources */,
|
||||||
82BA18BB1C4BBD4A00A0916E /* Where.swift in Sources */,
|
82BA18BB1C4BBD4A00A0916E /* Where.swift in Sources */,
|
||||||
B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
||||||
|
B5D339DE1E9489C700C880DE /* DynamicObject.swift in Sources */,
|
||||||
B5ECDBE71CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
B5ECDBE71CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
||||||
B5519A4B1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
B5519A4B1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
||||||
82BA18D71C4BBD7100A0916E /* NSManagedObjectModel+Setup.swift in Sources */,
|
B52F74301E9B50D0005F3DAC /* SchemaHistory.swift in Sources */,
|
||||||
82BA18C31C4BBD5300A0916E /* ObjectObserver.swift in Sources */,
|
82BA18C31C4BBD5300A0916E /* ObjectObserver.swift in Sources */,
|
||||||
82BA18BF1C4BBD5300A0916E /* SectionBy.swift in Sources */,
|
82BA18BF1C4BBD5300A0916E /* SectionBy.swift in Sources */,
|
||||||
|
B5D339ED1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */,
|
||||||
82BA18AC1C4BBD3100A0916E /* SynchronousDataTransaction.swift in Sources */,
|
82BA18AC1C4BBD3100A0916E /* SynchronousDataTransaction.swift in Sources */,
|
||||||
82BA18C71C4BBD5900A0916E /* CoreStore+Migration.swift in Sources */,
|
82BA18C71C4BBD5900A0916E /* CoreStore+Migration.swift in Sources */,
|
||||||
B5E222251CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
B5E222251CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||||
82BA18C41C4BBD5300A0916E /* ListMonitor.swift in Sources */,
|
82BA18C41C4BBD5300A0916E /* ListMonitor.swift in Sources */,
|
||||||
82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */,
|
82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */,
|
||||||
|
B52F744B1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||||
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||||
B5E2222C1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
B5E2222C1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
||||||
82BA18A71C4BBD2900A0916E /* CoreStore+Logging.swift in Sources */,
|
82BA18A71C4BBD2900A0916E /* CoreStore+Logging.swift in Sources */,
|
||||||
82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */,
|
82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */,
|
||||||
|
B56923E91EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||||
|
B5D33A021E96012400C880DE /* Relationship.swift in Sources */,
|
||||||
B559CD4B1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
B559CD4B1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||||
|
B56923CA1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||||
|
B56923E51EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */,
|
||||||
|
B58D0C641EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */,
|
||||||
B533C4DC1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
B533C4DC1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
||||||
B5ECDC311CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
B5ECDC311CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||||
82BA18AF1C4BBD3100A0916E /* CoreStore+Transaction.swift in Sources */,
|
82BA18AF1C4BBD3100A0916E /* CoreStore+Transaction.swift in Sources */,
|
||||||
@@ -1816,22 +2072,28 @@
|
|||||||
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||||
B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
||||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||||
|
B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||||
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
||||||
B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||||
B53FBA201CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
B53FBA201CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||||
82BA18A81C4BBD2900A0916E /* CoreStoreLogger.swift in Sources */,
|
82BA18A81C4BBD2900A0916E /* CoreStoreLogger.swift in Sources */,
|
||||||
B549F65F1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */,
|
B549F65F1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||||
B559CD451CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
B559CD451CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
||||||
82BA18B81C4BBD4200A0916E /* ClauseTypes.swift in Sources */,
|
82BA18B81C4BBD4200A0916E /* ClauseTypes.swift in Sources */,
|
||||||
|
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||||
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||||
|
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||||
|
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||||
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
|
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||||
|
B56923ED1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||||
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */,
|
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */,
|
||||||
B53FBA061CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
B53FBA061CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||||
82BA18BE1C4BBD4A00A0916E /* Tweak.swift in Sources */,
|
82BA18BE1C4BBD4A00A0916E /* Tweak.swift in Sources */,
|
||||||
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||||
B546F95E1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
B546F95E1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||||
B5ECDC0D1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
B5ECDC0D1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||||
|
B5D339E81E9493A500C880DE /* Entity.swift in Sources */,
|
||||||
82BA18CC1C4BBD6400A0916E /* Progress+Convenience.swift in Sources */,
|
82BA18CC1C4BBD6400A0916E /* Progress+Convenience.swift in Sources */,
|
||||||
82BA18C01C4BBD5300A0916E /* DataStack+Observing.swift in Sources */,
|
82BA18C01C4BBD5300A0916E /* DataStack+Observing.swift in Sources */,
|
||||||
82BA18A61C4BBD2900A0916E /* DefaultLogger.swift in Sources */,
|
82BA18A61C4BBD2900A0916E /* DefaultLogger.swift in Sources */,
|
||||||
@@ -1851,6 +2113,7 @@
|
|||||||
B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */,
|
B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */,
|
||||||
B5DBE2E01C9939E100B5CEFA /* BridgingTests.m in Sources */,
|
B5DBE2E01C9939E100B5CEFA /* BridgingTests.m in Sources */,
|
||||||
B5220E0D1D0D0D19009BC71E /* ImportTests.swift in Sources */,
|
B5220E0D1D0D0D19009BC71E /* ImportTests.swift in Sources */,
|
||||||
|
B5D339B51E925C2B00C880DE /* DynamicModelTests.swift in Sources */,
|
||||||
B525576D1CFAF18F00E51965 /* IntoTests.swift in Sources */,
|
B525576D1CFAF18F00E51965 /* IntoTests.swift in Sources */,
|
||||||
B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */,
|
B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */,
|
||||||
B52557891D02DE8100E51965 /* FetchTests.swift in Sources */,
|
B52557891D02DE8100E51965 /* FetchTests.swift in Sources */,
|
||||||
@@ -1877,20 +2140,27 @@
|
|||||||
B5220E1E1D13080D009BC71E /* CSListMonitor.swift in Sources */,
|
B5220E1E1D13080D009BC71E /* CSListMonitor.swift in Sources */,
|
||||||
B5DBE2D01C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
B5DBE2D01C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||||
B5677D411CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
B5677D411CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||||
|
B56923F81EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||||
B52DD1BE1BE1F94300949AFE /* Progress+Convenience.swift in Sources */,
|
B52DD1BE1BE1F94300949AFE /* Progress+Convenience.swift in Sources */,
|
||||||
|
B512608C1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||||
B5ECDC151CA816E500C7F112 /* CSTweak.swift in Sources */,
|
B5ECDC151CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||||
B546F9761C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
B546F9761C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||||
B53FBA161CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
B53FBA161CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||||
B5ECDC271CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
B5ECDC271CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
||||||
|
B5D339DB1E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||||
B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */,
|
B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */,
|
||||||
|
B56923FD1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||||
B596BBBE1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
B596BBBE1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||||
B546F9601C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
B546F9601C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||||
B5ECDC0F1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
B5ECDC0F1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||||
B5ECDC211CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
B5ECDC211CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
||||||
B52DD1C21BE1F94600949AFE /* MigrationManager.swift in Sources */,
|
B52DD1C21BE1F94600949AFE /* MigrationManager.swift in Sources */,
|
||||||
B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||||
|
B52F74441E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||||
B5ECDC2D1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
B5ECDC2D1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||||
|
B5A992221EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||||
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */,
|
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */,
|
||||||
|
B5D339E51E948C3600C880DE /* Value.swift in Sources */,
|
||||||
B5A5F26A1CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
B5A5F26A1CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
||||||
B5220E1B1D13079B009BC71E /* CSCoreStore+Observing.swift in Sources */,
|
B5220E1B1D13079B009BC71E /* CSCoreStore+Observing.swift in Sources */,
|
||||||
B5FEC1911C9166E700532541 /* NSPersistentStore+Setup.swift in Sources */,
|
B5FEC1911C9166E700532541 /* NSPersistentStore+Setup.swift in Sources */,
|
||||||
@@ -1901,14 +2171,16 @@
|
|||||||
B5220E1C1D130801009BC71E /* FetchedResultsControllerDelegate.swift in Sources */,
|
B5220E1C1D130801009BC71E /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||||
B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */,
|
B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */,
|
||||||
B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */,
|
B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */,
|
||||||
|
B5D339F41E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||||
B5220E241D13085E009BC71E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
B5220E241D13085E009BC71E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||||
B559CD471CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
B559CD471CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
||||||
B5ECDBF01CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
B5ECDBF01CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||||
B549F6761E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
B549F6761E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
||||||
B509C7F71E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */,
|
B509C7F71E54511B0061C547 /* ImportableAttributeType.swift in Sources */,
|
||||||
B5220E1F1D130810009BC71E /* CSListObserver.swift in Sources */,
|
B5220E1F1D130810009BC71E /* CSListObserver.swift in Sources */,
|
||||||
B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */,
|
B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */,
|
||||||
B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */,
|
B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */,
|
||||||
|
B56923F31EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
|
||||||
B5220E1D1D13080A009BC71E /* CSDataStack+Observing.swift in Sources */,
|
B5220E1D1D13080A009BC71E /* CSDataStack+Observing.swift in Sources */,
|
||||||
B52DD1A91BE1F93200949AFE /* CoreStore+Querying.swift in Sources */,
|
B52DD1A91BE1F93200949AFE /* CoreStore+Querying.swift in Sources */,
|
||||||
B5519A4D1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
B5519A4D1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
||||||
@@ -1918,6 +2190,7 @@
|
|||||||
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
||||||
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
||||||
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||||
|
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
B5ECDBE31CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
|
B5ECDBE31CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
|
||||||
B5ECDC031CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
B5ECDC031CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||||
B52DD1AC1BE1F93900949AFE /* Select.swift in Sources */,
|
B52DD1AC1BE1F93900949AFE /* Select.swift in Sources */,
|
||||||
@@ -1933,11 +2206,14 @@
|
|||||||
B52DD19D1BE1F92C00949AFE /* BaseDataTransaction.swift in Sources */,
|
B52DD19D1BE1F92C00949AFE /* BaseDataTransaction.swift in Sources */,
|
||||||
B5220E131D1305ED009BC71E /* SectionBy.swift in Sources */,
|
B5220E131D1305ED009BC71E /* SectionBy.swift in Sources */,
|
||||||
B559CD4D1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
B559CD4D1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||||
|
B5E41EC31EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||||
B5ECDBE91CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
B5ECDBE91CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
||||||
B52DD1B81BE1F94000949AFE /* DataStack+Migration.swift in Sources */,
|
B52DD1B81BE1F94000949AFE /* DataStack+Migration.swift in Sources */,
|
||||||
B5ECDC091CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
B5ECDC091CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||||
|
B56923C71EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||||
B52DD1A51BE1F92F00949AFE /* ImportableUniqueObject.swift in Sources */,
|
B52DD1A51BE1F92F00949AFE /* ImportableUniqueObject.swift in Sources */,
|
||||||
B5E222271CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
B5E222271CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||||
|
B52F74481E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
|
||||||
B5519A621CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
B5519A621CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||||
B52DD19C1BE1F92C00949AFE /* Into.swift in Sources */,
|
B52DD19C1BE1F92C00949AFE /* Into.swift in Sources */,
|
||||||
B5FE4DA51C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
B5FE4DA51C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||||
@@ -1946,24 +2222,32 @@
|
|||||||
B5FE4DAA1C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
B5FE4DAA1C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||||
B52DD1AF1BE1F93900949AFE /* GroupBy.swift in Sources */,
|
B52DD1AF1BE1F93900949AFE /* GroupBy.swift in Sources */,
|
||||||
B52DD1B01BE1F93900949AFE /* Tweak.swift in Sources */,
|
B52DD1B01BE1F93900949AFE /* Tweak.swift in Sources */,
|
||||||
B52DD1CA1BE1F94600949AFE /* NSManagedObjectModel+Setup.swift in Sources */,
|
|
||||||
B52DD1A41BE1F92F00949AFE /* ImportableObject.swift in Sources */,
|
B52DD1A41BE1F92F00949AFE /* ImportableObject.swift in Sources */,
|
||||||
B5220E161D13067C009BC71E /* ObjectMonitor.swift in Sources */,
|
B5220E161D13067C009BC71E /* ObjectMonitor.swift in Sources */,
|
||||||
|
B5D339E01E9489C700C880DE /* DynamicObject.swift in Sources */,
|
||||||
B52DD1AE1BE1F93900949AFE /* OrderBy.swift in Sources */,
|
B52DD1AE1BE1F93900949AFE /* OrderBy.swift in Sources */,
|
||||||
B52DD1BA1BE1F94000949AFE /* MigrationChain.swift in Sources */,
|
B52DD1BA1BE1F94000949AFE /* MigrationChain.swift in Sources */,
|
||||||
B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */,
|
B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */,
|
||||||
|
B52F74321E9B50D0005F3DAC /* SchemaHistory.swift in Sources */,
|
||||||
B52DD1A31BE1F92C00949AFE /* SaveResult.swift in Sources */,
|
B52DD1A31BE1F92C00949AFE /* SaveResult.swift in Sources */,
|
||||||
B5220E211D130816009BC71E /* CSObjectObserver.swift in Sources */,
|
B5220E211D130816009BC71E /* CSObjectObserver.swift in Sources */,
|
||||||
|
B5D339EF1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */,
|
||||||
B52DD19F1BE1F92C00949AFE /* SynchronousDataTransaction.swift in Sources */,
|
B52DD19F1BE1F92C00949AFE /* SynchronousDataTransaction.swift in Sources */,
|
||||||
B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */,
|
B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */,
|
||||||
B52DD1C11BE1F94600949AFE /* Functions.swift in Sources */,
|
B52DD1C11BE1F94600949AFE /* Functions.swift in Sources */,
|
||||||
B5220E1A1D130791009BC71E /* CoreStoreFetchedResultsController.swift in Sources */,
|
B5220E1A1D130791009BC71E /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||||
B53FBA0F1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
B53FBA0F1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
||||||
|
B52F744D1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||||
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */,
|
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */,
|
||||||
B52DD19A1BE1F92800949AFE /* CoreStore+Logging.swift in Sources */,
|
B52DD19A1BE1F92800949AFE /* CoreStore+Logging.swift in Sources */,
|
||||||
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */,
|
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */,
|
||||||
B546F96C1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
B546F96C1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||||
|
B56923EB1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||||
|
B5D33A041E96012400C880DE /* Relationship.swift in Sources */,
|
||||||
B52DD1C61BE1F94600949AFE /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
B52DD1C61BE1F94600949AFE /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||||
|
B56923CC1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||||
|
B56923E71EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */,
|
||||||
|
B58D0C661EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */,
|
||||||
B533C4DE1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
B533C4DE1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
||||||
B5220E141D130614009BC71E /* DataStack+Observing.swift in Sources */,
|
B5220E141D130614009BC71E /* DataStack+Observing.swift in Sources */,
|
||||||
B52DD1A21BE1F92C00949AFE /* CoreStore+Transaction.swift in Sources */,
|
B52DD1A21BE1F92C00949AFE /* CoreStore+Transaction.swift in Sources */,
|
||||||
@@ -1972,22 +2256,28 @@
|
|||||||
B5220E181D130711009BC71E /* ObjectObserver.swift in Sources */,
|
B5220E181D130711009BC71E /* ObjectObserver.swift in Sources */,
|
||||||
B5220E251D13088E009BC71E /* ListObserver.swift in Sources */,
|
B5220E251D13088E009BC71E /* ListObserver.swift in Sources */,
|
||||||
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||||
|
B51260821E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||||
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
||||||
B5ECDC331CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
B5ECDC331CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||||
B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */,
|
B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */,
|
||||||
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */,
|
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||||
B5220E151D130663009BC71E /* CoreStore+Observing.swift in Sources */,
|
B5220E151D130663009BC71E /* CoreStore+Observing.swift in Sources */,
|
||||||
B549F6611E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */,
|
B549F6611E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||||
B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */,
|
B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */,
|
||||||
B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */,
|
B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */,
|
||||||
|
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||||
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
|
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
|
||||||
|
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||||
|
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||||
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
|
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||||
|
B56923EF1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||||
B53FBA081CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
B53FBA081CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||||
B52DD1B91BE1F94000949AFE /* CoreStore+Migration.swift in Sources */,
|
B52DD1B91BE1F94000949AFE /* CoreStore+Migration.swift in Sources */,
|
||||||
B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
|
B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
|
||||||
B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||||
B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||||
B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
||||||
|
B5D339EA1E9493A500C880DE /* Entity.swift in Sources */,
|
||||||
B52DD1AA1BE1F93500949AFE /* ClauseTypes.swift in Sources */,
|
B52DD1AA1BE1F93500949AFE /* ClauseTypes.swift in Sources */,
|
||||||
B53FBA021CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
B53FBA021CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||||
B51FE5AF1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
B51FE5AF1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||||
@@ -2007,6 +2297,7 @@
|
|||||||
B5DBE2E11C9939E100B5CEFA /* BridgingTests.m in Sources */,
|
B5DBE2E11C9939E100B5CEFA /* BridgingTests.m in Sources */,
|
||||||
B5220E0E1D0D0D19009BC71E /* ImportTests.swift in Sources */,
|
B5220E0E1D0D0D19009BC71E /* ImportTests.swift in Sources */,
|
||||||
B525576E1CFAF18F00E51965 /* IntoTests.swift in Sources */,
|
B525576E1CFAF18F00E51965 /* IntoTests.swift in Sources */,
|
||||||
|
B5D339B61E925C2B00C880DE /* DynamicModelTests.swift in Sources */,
|
||||||
B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */,
|
B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */,
|
||||||
B525578A1D02DE8100E51965 /* FetchTests.swift in Sources */,
|
B525578A1D02DE8100E51965 /* FetchTests.swift in Sources */,
|
||||||
B5220E281D1308E5009BC71E /* SectionByTests.swift in Sources */,
|
B5220E281D1308E5009BC71E /* SectionByTests.swift in Sources */,
|
||||||
@@ -2033,20 +2324,27 @@
|
|||||||
B56321A91BD65219006C9394 /* Progress+Convenience.swift in Sources */,
|
B56321A91BD65219006C9394 /* Progress+Convenience.swift in Sources */,
|
||||||
B5ECDBFC1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
B5ECDBFC1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||||
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||||
|
B56923F71EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||||
B56321801BD65216006C9394 /* CoreStoreError.swift in Sources */,
|
B56321801BD65216006C9394 /* CoreStoreError.swift in Sources */,
|
||||||
|
B512608B1E9B252B00402229 /* NSEntityDescription+DynamicModel.swift in Sources */,
|
||||||
B56321AD1BD6521C006C9394 /* MigrationManager.swift in Sources */,
|
B56321AD1BD6521C006C9394 /* MigrationManager.swift in Sources */,
|
||||||
B529C2071CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */,
|
B529C2071CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */,
|
||||||
B563219D1BD65216006C9394 /* DataStack+Observing.swift in Sources */,
|
B563219D1BD65216006C9394 /* DataStack+Observing.swift in Sources */,
|
||||||
B56321961BD65216006C9394 /* From.swift in Sources */,
|
B56321961BD65216006C9394 /* From.swift in Sources */,
|
||||||
|
B5D339DA1E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||||
B5ECDC021CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
B5ECDC021CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||||
|
B56923FC1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||||
B596BBBD1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
B596BBBD1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||||
B5ECDC081CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
B5ECDC081CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||||
B5E1B59B1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
B5E1B59B1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||||
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||||
B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||||
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||||
|
B52F74431E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||||
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||||
|
B5A992211EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||||
B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */,
|
B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */,
|
||||||
|
B5D339E41E948C3600C880DE /* Value.swift in Sources */,
|
||||||
B53FBA0E1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
B53FBA0E1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
||||||
B563219E1BD65216006C9394 /* CoreStore+Observing.swift in Sources */,
|
B563219E1BD65216006C9394 /* CoreStore+Observing.swift in Sources */,
|
||||||
B5D7A5B91CA3BF8F005C752B /* CSInto.swift in Sources */,
|
B5D7A5B91CA3BF8F005C752B /* CSInto.swift in Sources */,
|
||||||
@@ -2057,14 +2355,16 @@
|
|||||||
B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||||
B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||||
B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||||
|
B5D339F31E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||||
B5E1B5A01CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
B5E1B5A01CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
||||||
B5ECDC261CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
B5ECDC261CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
|
||||||
B563217F1BD65216006C9394 /* CoreStore.swift in Sources */,
|
B563217F1BD65216006C9394 /* CoreStore.swift in Sources */,
|
||||||
B549F6751E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
B549F6751E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */,
|
||||||
B509C7F61E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */,
|
B509C7F61E54511B0061C547 /* ImportableAttributeType.swift in Sources */,
|
||||||
B5E1B5961CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
|
B5E1B5961CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */,
|
||||||
B5ECDC2C1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
B5ECDC2C1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||||
B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */,
|
B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */,
|
||||||
|
B56923F21EB827F6007C4DC9 /* XcodeSchemaMappingProvider.swift in Sources */,
|
||||||
B546F95A1C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
B546F95A1C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */,
|
||||||
B5677D401CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
B5677D401CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||||
B56321941BD65216006C9394 /* CoreStore+Querying.swift in Sources */,
|
B56321941BD65216006C9394 /* CoreStore+Querying.swift in Sources */,
|
||||||
@@ -2074,6 +2374,7 @@
|
|||||||
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
||||||
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||||
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||||
|
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||||
B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||||
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */,
|
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */,
|
||||||
@@ -2089,11 +2390,14 @@
|
|||||||
B56321B31BD6521C006C9394 /* NSManagedObjectContext+Setup.swift in Sources */,
|
B56321B31BD6521C006C9394 /* NSManagedObjectContext+Setup.swift in Sources */,
|
||||||
B501FDEA1CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
B501FDEA1CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||||
B501FDE51CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
B501FDE51CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||||
|
B5E41EC21EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||||
B5ECDC141CA816E500C7F112 /* CSTweak.swift in Sources */,
|
B5ECDC141CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||||
B56321AE1BD6521C006C9394 /* NotificationObserver.swift in Sources */,
|
B56321AE1BD6521C006C9394 /* NotificationObserver.swift in Sources */,
|
||||||
B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */,
|
B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */,
|
||||||
|
B56923C61EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||||
B56321A71BD65216006C9394 /* MigrationResult.swift in Sources */,
|
B56321A71BD65216006C9394 /* MigrationResult.swift in Sources */,
|
||||||
B598514A1C90289E00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
B598514A1C90289E00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
||||||
|
B52F74471E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
|
||||||
B5FEC1901C9166E700532541 /* NSPersistentStore+Setup.swift in Sources */,
|
B5FEC1901C9166E700532541 /* NSPersistentStore+Setup.swift in Sources */,
|
||||||
B56321A11BD65216006C9394 /* ListMonitor.swift in Sources */,
|
B56321A11BD65216006C9394 /* ListMonitor.swift in Sources */,
|
||||||
B5E1B5A51CAA4365007FD580 /* CSCoreStore+Observing.swift in Sources */,
|
B5E1B5A51CAA4365007FD580 /* CSCoreStore+Observing.swift in Sources */,
|
||||||
@@ -2105,21 +2409,29 @@
|
|||||||
B563219A1BD65216006C9394 /* GroupBy.swift in Sources */,
|
B563219A1BD65216006C9394 /* GroupBy.swift in Sources */,
|
||||||
B5ECDBE81CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
B5ECDBE81CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
||||||
B5A5F2691CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
B5A5F2691CAEC50F004AB9AF /* CSSelect.swift in Sources */,
|
||||||
|
B5D339DF1E9489C700C880DE /* DynamicObject.swift in Sources */,
|
||||||
B5519A4C1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
B5519A4C1CA1F4FB002BEF78 /* CSError.swift in Sources */,
|
||||||
B563219B1BD65216006C9394 /* Tweak.swift in Sources */,
|
B563219B1BD65216006C9394 /* Tweak.swift in Sources */,
|
||||||
B56321B51BD6521C006C9394 /* NSManagedObjectModel+Setup.swift in Sources */,
|
B52F74311E9B50D0005F3DAC /* SchemaHistory.swift in Sources */,
|
||||||
B563218F1BD65216006C9394 /* ImportableObject.swift in Sources */,
|
B563218F1BD65216006C9394 /* ImportableObject.swift in Sources */,
|
||||||
B56321991BD65216006C9394 /* OrderBy.swift in Sources */,
|
B56321991BD65216006C9394 /* OrderBy.swift in Sources */,
|
||||||
|
B5D339EE1E9495E500C880DE /* CoreStoreObject+Querying.swift in Sources */,
|
||||||
B56321A51BD65216006C9394 /* MigrationChain.swift in Sources */,
|
B56321A51BD65216006C9394 /* MigrationChain.swift in Sources */,
|
||||||
B563218E1BD65216006C9394 /* SaveResult.swift in Sources */,
|
B563218E1BD65216006C9394 /* SaveResult.swift in Sources */,
|
||||||
B5E222261CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
B5E222261CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||||
B56321A21BD65216006C9394 /* ListObserver.swift in Sources */,
|
B56321A21BD65216006C9394 /* ListObserver.swift in Sources */,
|
||||||
B563218A1BD65216006C9394 /* SynchronousDataTransaction.swift in Sources */,
|
B563218A1BD65216006C9394 /* SynchronousDataTransaction.swift in Sources */,
|
||||||
|
B52F744C1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||||
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||||
B5E2222D1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
B5E2222D1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
||||||
B563219F1BD65216006C9394 /* ObjectMonitor.swift in Sources */,
|
B563219F1BD65216006C9394 /* ObjectMonitor.swift in Sources */,
|
||||||
B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */,
|
B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */,
|
||||||
|
B56923EA1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||||
|
B5D33A031E96012400C880DE /* Relationship.swift in Sources */,
|
||||||
B559CD4C1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
B559CD4C1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||||
|
B56923CB1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||||
|
B56923E61EB827F5007C4DC9 /* CustomSchemaMappingProvider.swift in Sources */,
|
||||||
|
B58D0C651EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */,
|
||||||
B533C4DD1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
B533C4DD1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */,
|
||||||
B5ECDC321CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
B5ECDC321CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||||
B56321AC1BD6521C006C9394 /* Functions.swift in Sources */,
|
B56321AC1BD6521C006C9394 /* Functions.swift in Sources */,
|
||||||
@@ -2128,22 +2440,28 @@
|
|||||||
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||||
B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
||||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||||
|
B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
||||||
B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||||
B53FBA211CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
B53FBA211CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||||
B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */,
|
B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */,
|
||||||
B549F6601E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */,
|
B549F6601E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||||
B559CD461CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
B559CD461CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
||||||
B56321A61BD65216006C9394 /* MigrationType.swift in Sources */,
|
B56321A61BD65216006C9394 /* MigrationType.swift in Sources */,
|
||||||
|
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||||
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||||
|
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||||
|
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||||
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
|
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||||
|
B56923EE1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||||
B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */,
|
B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */,
|
||||||
B53FBA071CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
B53FBA071CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||||
B56321841BD65216006C9394 /* DefaultLogger.swift in Sources */,
|
B56321841BD65216006C9394 /* DefaultLogger.swift in Sources */,
|
||||||
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||||
B546F95F1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
B546F95F1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||||
B5ECDC0E1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
B5ECDC0E1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||||
|
B5D339E91E9493A500C880DE /* Entity.swift in Sources */,
|
||||||
B56321A41BD65216006C9394 /* CoreStore+Migration.swift in Sources */,
|
B56321A41BD65216006C9394 /* CoreStore+Migration.swift in Sources */,
|
||||||
B56321A01BD65216006C9394 /* ObjectObserver.swift in Sources */,
|
B56321A01BD65216006C9394 /* ObjectObserver.swift in Sources */,
|
||||||
B56321951BD65216006C9394 /* ClauseTypes.swift in Sources */,
|
B56321951BD65216006C9394 /* ClauseTypes.swift in Sources */,
|
||||||
@@ -2183,6 +2501,7 @@
|
|||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
@@ -2241,6 +2560,7 @@
|
|||||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
|||||||
@@ -63,6 +63,11 @@
|
|||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
|
<AdditionalOption
|
||||||
|
key = "NSZombieEnabled"
|
||||||
|
value = "YES"
|
||||||
|
isEnabled = "YES">
|
||||||
|
</AdditionalOption>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADD1AFDC71700F90881 /* Palette.swift */; };
|
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADD1AFDC71700F90881 /* Palette.swift */; };
|
||||||
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */; };
|
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B503FADE1AFDC71700F90881 /* PaletteTableViewCell.swift */; };
|
||||||
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */; };
|
B5125C121B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B5125C111B521B78003A42C7 /* OrganismV2ToV3.xcmappingmodel */; };
|
||||||
B5125C141B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B5125C131B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel */; };
|
|
||||||
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977D81B120B80003D50A5 /* ObserversViewController.swift */; };
|
B52977D91B120B80003D50A5 /* ObserversViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977D81B120B80003D50A5 /* ObserversViewController.swift */; };
|
||||||
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */; };
|
B52977DD1B120F3B003D50A5 /* TransactionsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52977DC1B120F3B003D50A5 /* TransactionsDemoViewController.swift */; };
|
||||||
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977DE1B120F83003D50A5 /* MapKit.framework */; };
|
B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52977DE1B120F83003D50A5 /* MapKit.framework */; };
|
||||||
@@ -331,7 +330,6 @@
|
|||||||
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */,
|
B503FAE11AFDC71700F90881 /* Palette.swift in Sources */,
|
||||||
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */,
|
B503FAE21AFDC71700F90881 /* PaletteTableViewCell.swift in Sources */,
|
||||||
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */,
|
B560070F1B3EC90F00A9A8F9 /* OrganismV2ToV3MigrationPolicy.swift in Sources */,
|
||||||
B5125C141B521BA7003A42C7 /* OrganismV3ToV2.xcmappingmodel in Sources */,
|
|
||||||
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */,
|
B503FADF1AFDC71700F90881 /* ListObserverDemoViewController.swift in Sources */,
|
||||||
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */,
|
B54AAD4F1AF4D26E00848AE0 /* AppDelegate.swift in Sources */,
|
||||||
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */,
|
B56964D71B231AE90075EE4A /* StackSetupDemo.xcdatamodeld in Sources */,
|
||||||
|
|||||||
@@ -18,10 +18,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {
|
||||||
|
|
||||||
application.statusBarStyle = .lightContent
|
application.statusBarStyle = .lightContent
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,28 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10112" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="Ni8-QF-XHB">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12113" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Ni8-QF-XHB">
|
||||||
|
<device id="retina4_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10083"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12078"/>
|
||||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<customFonts key="customFonts">
|
<customFonts key="customFonts">
|
||||||
<mutableArray key="AppleSDGothicNeo.ttc">
|
<array key="AppleSDGothicNeo.ttc">
|
||||||
<string>AppleSDGothicNeo-Regular</string>
|
<string>AppleSDGothicNeo-Regular</string>
|
||||||
</mutableArray>
|
</array>
|
||||||
<mutableArray key="HelveticaNeue.ttc">
|
<array key="HelveticaNeue.ttc">
|
||||||
<string>HelveticaNeue-Bold</string>
|
|
||||||
<string>HelveticaNeue-Bold</string>
|
|
||||||
<string>HelveticaNeue</string>
|
<string>HelveticaNeue</string>
|
||||||
<string>HelveticaNeue</string>
|
<string>HelveticaNeue-Bold</string>
|
||||||
</mutableArray>
|
</array>
|
||||||
<mutableArray key="HelveticaNeueLights.ttc">
|
<array key="HelveticaNeueLights.ttc">
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
<string>HelveticaNeue-Light</string>
|
||||||
<string>HelveticaNeue-Thin</string>
|
<string>HelveticaNeue-Thin</string>
|
||||||
<string>HelveticaNeue-Light</string>
|
</array>
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
<string>HelveticaNeue-Light</string>
|
|
||||||
</mutableArray>
|
|
||||||
</customFonts>
|
</customFonts>
|
||||||
<scenes>
|
<scenes>
|
||||||
<!--SNS Accounts-->
|
<!--SNS Accounts-->
|
||||||
@@ -41,34 +30,34 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="AW4-lY-JNk" customClass="StackSetupDemoViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController id="AW4-lY-JNk" customClass="StackSetupDemoViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="S3A-lm-AuA">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="S3A-lm-AuA">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="separatorColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="separatorColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<view key="tableHeaderView" contentMode="scaleToFill" id="yud-WH-MPa">
|
<view key="tableHeaderView" contentMode="scaleToFill" id="yud-WH-MPa">
|
||||||
<rect key="frame" x="0.0" y="64" width="600" height="150"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="150"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="sns" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="czc-nd-es9">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="sns" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="czc-nd-es9">
|
||||||
<rect key="frame" x="20" y="20" width="560" height="26.5"/>
|
<rect key="frame" x="20" y="20" width="335" height="26.5"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="22"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="22"/>
|
||||||
<color key="textColor" red="0.92549019610000005" green="0.94117647059999998" blue="0.94509803920000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="name" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1eh-91-O2N">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="name" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1eh-91-O2N">
|
||||||
<rect key="frame" x="20" y="70" width="41" height="20.5"/>
|
<rect key="frame" x="20" y="70" width="41" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="17"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="17"/>
|
||||||
<color key="textColor" red="0.92549019610000005" green="0.94117647059999998" blue="0.94509803920000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="friends" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p2y-0T-hQs">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="friends" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p2y-0T-hQs">
|
||||||
<rect key="frame" x="539.5" y="72" width="40.5" height="17"/>
|
<rect key="frame" x="314.5" y="72" width="40.5" height="17"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="14"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="14"/>
|
||||||
<color key="textColor" red="0.92549019610000005" green="0.94117647059999998" blue="0.94509803920000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" red="0.20392156862745098" green="0.28627450980392155" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="1eh-91-O2N" firstAttribute="top" secondItem="czc-nd-es9" secondAttribute="bottom" constant="23.5" id="F6q-Jt-glI"/>
|
<constraint firstItem="1eh-91-O2N" firstAttribute="top" secondItem="czc-nd-es9" secondAttribute="bottom" constant="23.5" id="F6q-Jt-glI"/>
|
||||||
<constraint firstItem="p2y-0T-hQs" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1eh-91-O2N" secondAttribute="trailing" constant="20" id="GVS-6o-rmj"/>
|
<constraint firstItem="p2y-0T-hQs" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1eh-91-O2N" secondAttribute="trailing" constant="20" id="GVS-6o-rmj"/>
|
||||||
@@ -82,24 +71,24 @@
|
|||||||
</view>
|
</view>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="8b8-lM-Krq" detailTextLabel="hR1-Zb-BOk" style="IBUITableViewCellStyleValue1" id="dMt-nx-EO5">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="8b8-lM-Krq" detailTextLabel="hR1-Zb-BOk" style="IBUITableViewCellStyleValue1" id="dMt-nx-EO5">
|
||||||
<rect key="frame" x="0.0" y="236" width="600" height="44"/>
|
<rect key="frame" x="0.0" y="172" width="375" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dMt-nx-EO5" id="gdK-VV-zNb">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dMt-nx-EO5" id="gdK-VV-zNb">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8b8-lM-Krq">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8b8-lM-Krq">
|
||||||
<rect key="frame" x="15" y="13" width="28.5" height="19"/>
|
<rect key="frame" x="15" y="13" width="28.5" height="19"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="16"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="16"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hR1-Zb-BOk">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hR1-Zb-BOk">
|
||||||
<rect key="frame" x="533" y="13" width="52" height="19"/>
|
<rect key="frame" x="308" y="13" width="52" height="19"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="16"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="16"/>
|
||||||
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -131,23 +120,23 @@
|
|||||||
<viewControllerLayoutGuide type="bottom" id="t9A-zf-Iew"/>
|
<viewControllerLayoutGuide type="bottom" id="t9A-zf-Iew"/>
|
||||||
</layoutGuides>
|
</layoutGuides>
|
||||||
<view key="view" contentMode="scaleToFill" id="75P-2m-6cr">
|
<view key="view" contentMode="scaleToFill" id="75P-2m-6cr">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="WUc-3Y-Quw">
|
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="WUc-3Y-Quw">
|
||||||
<rect key="frame" x="0.0" y="324" width="600" height="276"/>
|
<rect key="frame" x="0.0" y="324" width="375" height="343"/>
|
||||||
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="separatorColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="separatorColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="OrganismTableViewCell" id="WVb-th-o8c" customClass="OrganismTableViewCell" customModule="CoreStoreDemo" customModuleProvider="target">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="OrganismTableViewCell" id="WVb-th-o8c" customClass="OrganismTableViewCell" customModule="CoreStoreDemo" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="22" width="600" height="44"/>
|
<rect key="frame" x="0.0" y="22" width="375" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WVb-th-o8c" id="JBq-Ml-a9p">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WVb-th-o8c" id="JBq-Ml-a9p">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OQf-Bd-Zze">
|
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OQf-Bd-Zze">
|
||||||
<rect key="frame" x="520" y="8" width="72" height="27.5"/>
|
<rect key="frame" x="295" y="8" width="72" height="27.5"/>
|
||||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||||
<inset key="contentEdgeInsets" minX="7" minY="0.0" maxX="7" maxY="0.0"/>
|
<inset key="contentEdgeInsets" minX="7" minY="0.0" maxX="7" maxY="0.0"/>
|
||||||
<state key="normal" title="mutate!"/>
|
<state key="normal" title="mutate!"/>
|
||||||
@@ -156,9 +145,9 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VZk-6K-4ut">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VZk-6K-4ut">
|
||||||
<rect key="frame" x="15" y="8" width="495" height="27.5"/>
|
<rect key="frame" x="15" y="8" width="270" height="27.5"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Thin" family="Helvetica Neue" pointSize="17"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Thin" family="Helvetica Neue" pointSize="17"/>
|
||||||
<color key="textColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -184,42 +173,42 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableView>
|
</tableView>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XKA-Ub-c2X">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XKA-Ub-c2X">
|
||||||
<rect key="frame" x="0.0" y="64" width="600" height="260"/>
|
<rect key="frame" x="0.0" y="64" width="375" height="260"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="i7U-bW-juB" customClass="UIButton">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="i7U-bW-juB" customClass="UIButton">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="260"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="260"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Organism" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zxy-nY-P44">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Organism" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zxy-nY-P44">
|
||||||
<rect key="frame" x="20" y="90.5" width="560" height="26.5"/>
|
<rect key="frame" x="20" y="90.5" width="335" height="26.5"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="22"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Bold" family="Helvetica Neue" pointSize="22"/>
|
||||||
<color key="textColor" red="0.92549019610000005" green="0.94117647059999998" blue="0.94509803920000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="attributes" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6Ac-xl-ldZ">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="attributes" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6Ac-xl-ldZ">
|
||||||
<rect key="frame" x="20" y="131.5" width="560" height="20.5"/>
|
<rect key="frame" x="20" y="131.5" width="335" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="17"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="17"/>
|
||||||
<color key="textColor" red="0.92549019610000005" green="0.94117647059999998" blue="0.94509803920000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="rAZ-eJ-sxy">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="rAZ-eJ-sxy">
|
||||||
<rect key="frame" x="20" y="20" width="560" height="29"/>
|
<rect key="frame" x="20" y="20" width="335" height="29"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="First"/>
|
<segment title="First"/>
|
||||||
<segment title="Second"/>
|
<segment title="Second"/>
|
||||||
<segment title=""/>
|
<segment title=""/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="segmentedControlValueChanged:" destination="iVv-Vc-nCL" eventType="valueChanged" id="RwG-kW-RPg"/>
|
<action selector="segmentedControlValueChanged:" destination="iVv-Vc-nCL" eventType="valueChanged" id="RwG-kW-RPg"/>
|
||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<progressView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="869-wx-Odb">
|
<progressView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="869-wx-Odb">
|
||||||
<rect key="frame" x="20" y="68" width="560" height="2"/>
|
<rect key="frame" x="20" y="68" width="335" height="2"/>
|
||||||
<color key="progressTintColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="progressTintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="trackTintColor" white="1" alpha="0.20000000000000001" colorSpace="calibratedWhite"/>
|
<color key="trackTintColor" red="1" green="1" blue="1" alpha="0.20000000000000001" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</progressView>
|
</progressView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="zxy-nY-P44" firstAttribute="leading" secondItem="i7U-bW-juB" secondAttribute="leading" constant="20" id="1u1-Tq-hRn"/>
|
<constraint firstItem="zxy-nY-P44" firstAttribute="leading" secondItem="i7U-bW-juB" secondAttribute="leading" constant="20" id="1u1-Tq-hRn"/>
|
||||||
<constraint firstItem="6Ac-xl-ldZ" firstAttribute="top" secondItem="zxy-nY-P44" secondAttribute="bottom" constant="14.5" id="39B-9l-O3g"/>
|
<constraint firstItem="6Ac-xl-ldZ" firstAttribute="top" secondItem="zxy-nY-P44" secondAttribute="bottom" constant="14.5" id="39B-9l-O3g"/>
|
||||||
@@ -237,7 +226,7 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="260" id="90R-Mf-iAB"/>
|
<constraint firstAttribute="height" constant="260" id="90R-Mf-iAB"/>
|
||||||
<constraint firstItem="i7U-bW-juB" firstAttribute="leading" secondItem="XKA-Ub-c2X" secondAttribute="leading" id="e9h-f4-c37"/>
|
<constraint firstItem="i7U-bW-juB" firstAttribute="leading" secondItem="XKA-Ub-c2X" secondAttribute="leading" id="e9h-f4-c37"/>
|
||||||
@@ -246,7 +235,7 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="trailing" secondItem="XKA-Ub-c2X" secondAttribute="trailing" id="U0P-51-KT9"/>
|
<constraint firstAttribute="trailing" secondItem="XKA-Ub-c2X" secondAttribute="trailing" id="U0P-51-KT9"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="WUc-3Y-Quw" secondAttribute="trailing" id="i7I-7B-97K"/>
|
<constraint firstAttribute="trailing" secondItem="WUc-3Y-Quw" secondAttribute="trailing" id="i7I-7B-97K"/>
|
||||||
@@ -276,31 +265,31 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="t0d-B0-B7U" sceneMemberID="viewController">
|
<tableViewController id="t0d-B0-B7U" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="50" sectionHeaderHeight="10" sectionFooterHeight="10" id="uHB-Yr-ujV">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="50" sectionHeaderHeight="10" sectionFooterHeight="10" id="uHB-Yr-ujV">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<sections>
|
<sections>
|
||||||
<tableViewSection id="wIP-Hn-YfF">
|
<tableViewSection id="wIP-Hn-YfF">
|
||||||
<cells>
|
<cells>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="Q3n-Df-v1t" detailTextLabel="Hbn-cf-Y7m" style="IBUITableViewCellStyleSubtitle" id="AXm-KE-45G">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="Q3n-Df-v1t" detailTextLabel="Hbn-cf-Y7m" style="IBUITableViewCellStyleSubtitle" id="AXm-KE-45G">
|
||||||
<rect key="frame" x="0.0" y="99" width="600" height="50"/>
|
<rect key="frame" x="0.0" y="35" width="375" height="50"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="AXm-KE-45G" id="9te-Wx-hkf">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="AXm-KE-45G" id="9te-Wx-hkf">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="567" height="49.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Accounts" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Q3n-Df-v1t">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Accounts" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Q3n-Df-v1t">
|
||||||
<rect key="frame" x="15" y="6" width="82" height="24"/>
|
<rect key="frame" x="15" y="6" width="82" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901960784313" green="0.24313725490196078" blue="0.31372549019607843" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Setting up multiple persistent store configurations" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Hbn-cf-Y7m">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Setting up multiple persistent store configurations" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Hbn-cf-Y7m">
|
||||||
<rect key="frame" x="15" y="30" width="263.5" height="13.5"/>
|
<rect key="frame" x="15" y="30" width="263.5" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -310,24 +299,24 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="vpt-cT-gMo" detailTextLabel="ou9-TZ-8bf" style="IBUITableViewCellStyleSubtitle" id="fsb-zw-8Ii">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="vpt-cT-gMo" detailTextLabel="ou9-TZ-8bf" style="IBUITableViewCellStyleSubtitle" id="fsb-zw-8Ii">
|
||||||
<rect key="frame" x="0.0" y="149" width="600" height="50"/>
|
<rect key="frame" x="0.0" y="85" width="375" height="50"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fsb-zw-8Ii" id="Upm-AO-Fw3">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fsb-zw-8Ii" id="Upm-AO-Fw3">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="567" height="49.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Colors" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="vpt-cT-gMo">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Colors" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="vpt-cT-gMo">
|
||||||
<rect key="frame" x="15" y="6" width="56" height="24"/>
|
<rect key="frame" x="15" y="6" width="56" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Observing list changes and single object changes" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ou9-TZ-8bf">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Observing list changes and single object changes" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ou9-TZ-8bf">
|
||||||
<rect key="frame" x="15" y="30" width="260.5" height="13.5"/>
|
<rect key="frame" x="15" y="30" width="260.5" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -337,24 +326,24 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="UbU-Kd-yrY" detailTextLabel="uP1-Jc-o9v" style="IBUITableViewCellStyleSubtitle" id="ekW-PJ-mbo">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="UbU-Kd-yrY" detailTextLabel="uP1-Jc-o9v" style="IBUITableViewCellStyleSubtitle" id="ekW-PJ-mbo">
|
||||||
<rect key="frame" x="0.0" y="199" width="600" height="50"/>
|
<rect key="frame" x="0.0" y="135" width="375" height="50"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ekW-PJ-mbo" id="CYq-mg-PVS">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ekW-PJ-mbo" id="CYq-mg-PVS">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="567" height="49.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Placemarks" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UbU-Kd-yrY">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Placemarks" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UbU-Kd-yrY">
|
||||||
<rect key="frame" x="15" y="6" width="100.5" height="24"/>
|
<rect key="frame" x="15" y="6" width="100.5" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Making changes with transactions" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="uP1-Jc-o9v">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Making changes with transactions" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="uP1-Jc-o9v">
|
||||||
<rect key="frame" x="15" y="30" width="179" height="13.5"/>
|
<rect key="frame" x="15" y="30" width="179" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -364,24 +353,24 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="C8Y-0y-lEG" detailTextLabel="jZw-qE-0ws" style="IBUITableViewCellStyleSubtitle" id="ph1-8z-C1m">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="C8Y-0y-lEG" detailTextLabel="jZw-qE-0ws" style="IBUITableViewCellStyleSubtitle" id="ph1-8z-C1m">
|
||||||
<rect key="frame" x="0.0" y="249" width="600" height="50"/>
|
<rect key="frame" x="0.0" y="185" width="375" height="50"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ph1-8z-C1m" id="nNz-rd-ksg">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ph1-8z-C1m" id="nNz-rd-ksg">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="567" height="49.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Time Zones" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="C8Y-0y-lEG">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Time Zones" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="C8Y-0y-lEG">
|
||||||
<rect key="frame" x="15" y="6" width="101.5" height="24"/>
|
<rect key="frame" x="15" y="6" width="101.5" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Fetching objects and raw values" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jZw-qE-0ws">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Fetching objects and raw values" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jZw-qE-0ws">
|
||||||
<rect key="frame" x="15" y="30" width="168.5" height="13.5"/>
|
<rect key="frame" x="15" y="30" width="168.5" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -391,24 +380,24 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="ZfY-Aq-Ykq" detailTextLabel="QzD-9b-k1j" style="IBUITableViewCellStyleSubtitle" id="wyK-rk-3tI">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="ZfY-Aq-Ykq" detailTextLabel="QzD-9b-k1j" style="IBUITableViewCellStyleSubtitle" id="wyK-rk-3tI">
|
||||||
<rect key="frame" x="0.0" y="299" width="600" height="50"/>
|
<rect key="frame" x="0.0" y="235" width="375" height="50"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wyK-rk-3tI" id="fLd-KK-QcW">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wyK-rk-3tI" id="fLd-KK-QcW">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="567" height="49.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Logger" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZfY-Aq-Ykq">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Logger" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZfY-Aq-Ykq">
|
||||||
<rect key="frame" x="15" y="6" width="61" height="24"/>
|
<rect key="frame" x="15" y="6" width="61" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Implementing a custom logger" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QzD-9b-k1j">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Implementing a custom logger" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QzD-9b-k1j">
|
||||||
<rect key="frame" x="15" y="30" width="159" height="13.5"/>
|
<rect key="frame" x="15" y="30" width="159" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -418,24 +407,24 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="hSG-mG-YBw" detailTextLabel="X9P-TQ-LYh" style="IBUITableViewCellStyleSubtitle" id="xTM-Cf-0if">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" textLabel="hSG-mG-YBw" detailTextLabel="X9P-TQ-LYh" style="IBUITableViewCellStyleSubtitle" id="xTM-Cf-0if">
|
||||||
<rect key="frame" x="0.0" y="349" width="600" height="50"/>
|
<rect key="frame" x="0.0" y="285" width="375" height="50"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="xTM-Cf-0if" id="DfO-BW-krd">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="xTM-Cf-0if" id="DfO-BW-krd">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="567" height="49.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Evolution" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hSG-mG-YBw">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Evolution" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hSG-mG-YBw">
|
||||||
<rect key="frame" x="15" y="6" width="78.5" height="24"/>
|
<rect key="frame" x="15" y="6" width="78.5" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Migrating and de-migrating stores" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="X9P-TQ-LYh">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Migrating and de-migrating stores" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="X9P-TQ-LYh">
|
||||||
<rect key="frame" x="15" y="30" width="179.5" height="13.5"/>
|
<rect key="frame" x="15" y="30" width="179.5" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -467,69 +456,69 @@
|
|||||||
<viewControllerLayoutGuide type="bottom" id="aI4-O3-OCi"/>
|
<viewControllerLayoutGuide type="bottom" id="aI4-O3-OCi"/>
|
||||||
</layoutGuides>
|
</layoutGuides>
|
||||||
<view key="view" contentMode="scaleToFill" id="w8K-eN-RvU">
|
<view key="view" contentMode="scaleToFill" id="w8K-eN-RvU">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="592" height="268"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="301.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
|
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
|
||||||
<rect key="frame" x="20" y="69.5" width="552" height="36.5"/>
|
<rect key="frame" x="20" y="69.5" width="552" height="36.5"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" id="TIX-qi-B34"/>
|
<constraint firstAttribute="height" relation="greaterThanOrEqual" id="TIX-qi-B34"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="250" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vfe-Yq-3Xa">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="250" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vfe-Yq-3Xa">
|
||||||
<rect key="frame" x="20" y="116" width="552" height="18"/>
|
<rect key="frame" x="16" y="149.5" width="343" height="18"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" id="4h9-ha-EzR"/>
|
<constraint firstAttribute="height" relation="greaterThanOrEqual" id="4h9-ha-EzR"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
||||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hue" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sgg-Md-Nf3">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hue" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sgg-Md-Nf3">
|
||||||
<rect key="frame" x="20" y="154" width="74" height="18"/>
|
<rect key="frame" x="16" y="187.5" width="74" height="18"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Saturation" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rry-vh-bRK">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Saturation" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rry-vh-bRK">
|
||||||
<rect key="frame" x="20" y="192" width="74" height="18"/>
|
<rect key="frame" x="16" y="225.5" width="74" height="18"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Brightness" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vTa-ly-eyO">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Brightness" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vTa-ly-eyO">
|
||||||
<rect key="frame" x="20" y="230" width="74" height="18"/>
|
<rect key="frame" x="16" y="263.5" width="74" height="18"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="359" translatesAutoresizingMaskIntoConstraints="NO" id="YQ6-fq-3Wb">
|
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="359" translatesAutoresizingMaskIntoConstraints="NO" id="YQ6-fq-3Wb">
|
||||||
<rect key="frame" x="102" y="148" width="472" height="31"/>
|
<rect key="frame" x="98" y="181.5" width="263" height="31"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="hueSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="9Hy-3h-llE"/>
|
<action selector="hueSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="9Hy-3h-llE"/>
|
||||||
</connections>
|
</connections>
|
||||||
</slider>
|
</slider>
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="xXz-78-tAd">
|
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="xXz-78-tAd">
|
||||||
<rect key="frame" x="102" y="186" width="472" height="31"/>
|
<rect key="frame" x="98" y="219.5" width="263" height="31"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="saturationSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="qtU-ua-ZTc"/>
|
<action selector="saturationSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="qtU-ua-ZTc"/>
|
||||||
</connections>
|
</connections>
|
||||||
</slider>
|
</slider>
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="hpy-2d-eOP">
|
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="hpy-2d-eOP">
|
||||||
<rect key="frame" x="102" y="224" width="472" height="31"/>
|
<rect key="frame" x="98" y="257.5" width="263" height="31"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="brightnessSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="F09-EP-2iD"/>
|
<action selector="brightnessSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="F09-EP-2iD"/>
|
||||||
</connections>
|
</connections>
|
||||||
</slider>
|
</slider>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p4O-tf-dgt">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p4O-tf-dgt">
|
||||||
<rect key="frame" x="20" y="49" width="552" height="20.5"/>
|
<rect key="frame" x="20" y="49" width="552" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="p4O-tf-dgt" firstAttribute="trailing" secondItem="w8K-eN-RvU" secondAttribute="trailingMargin" id="022-ll-1s1"/>
|
<constraint firstItem="p4O-tf-dgt" firstAttribute="trailing" secondItem="w8K-eN-RvU" secondAttribute="trailingMargin" id="022-ll-1s1"/>
|
||||||
<constraint firstItem="vTa-ly-eyO" firstAttribute="top" secondItem="rry-vh-bRK" secondAttribute="bottom" constant="20" id="1hd-Ti-CnT"/>
|
<constraint firstItem="vTa-ly-eyO" firstAttribute="top" secondItem="rry-vh-bRK" secondAttribute="bottom" constant="20" id="1hd-Ti-CnT"/>
|
||||||
@@ -591,23 +580,23 @@
|
|||||||
<viewControllerLayoutGuide type="bottom" id="LNL-mj-D7l"/>
|
<viewControllerLayoutGuide type="bottom" id="LNL-mj-D7l"/>
|
||||||
</layoutGuides>
|
</layoutGuides>
|
||||||
<view key="view" contentMode="scaleToFill" id="6x3-vn-Egt">
|
<view key="view" contentMode="scaleToFill" id="6x3-vn-Egt">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="L5f-tW-lXf">
|
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="L5f-tW-lXf">
|
||||||
<rect key="frame" x="4" y="64" width="592" height="268"/>
|
<rect key="frame" x="0.0" y="64" width="375" height="301.5"/>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="5Fw-je-9gI" kind="embed" id="YcI-2Z-ijV"/>
|
<segue destination="5Fw-je-9gI" kind="embed" id="YcI-2Z-ijV"/>
|
||||||
</connections>
|
</connections>
|
||||||
</containerView>
|
</containerView>
|
||||||
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6So-f3-4Gp">
|
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6So-f3-4Gp">
|
||||||
<rect key="frame" x="4" y="332" width="592" height="268"/>
|
<rect key="frame" x="0.0" y="365.5" width="375" height="301.5"/>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="sll-yo-mBc" kind="embed" id="AAl-HS-dq2"/>
|
<segue destination="sll-yo-mBc" kind="embed" id="AAl-HS-dq2"/>
|
||||||
</connections>
|
</connections>
|
||||||
</containerView>
|
</containerView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="6So-f3-4Gp" firstAttribute="top" secondItem="L5f-tW-lXf" secondAttribute="bottom" id="3m8-tj-Nd4"/>
|
<constraint firstItem="6So-f3-4Gp" firstAttribute="top" secondItem="L5f-tW-lXf" secondAttribute="bottom" id="3m8-tj-Nd4"/>
|
||||||
<constraint firstAttribute="trailingMargin" secondItem="6So-f3-4Gp" secondAttribute="trailing" constant="-16" id="4L8-wZ-F59"/>
|
<constraint firstAttribute="trailingMargin" secondItem="6So-f3-4Gp" secondAttribute="trailing" constant="-16" id="4L8-wZ-F59"/>
|
||||||
@@ -636,11 +625,11 @@
|
|||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="00L-5k-Eno">
|
<navigationBar key="navigationBar" contentMode="scaleToFill" id="00L-5k-Eno">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<color key="tintColor" red="0.92549019610000005" green="0.94117647059999998" blue="0.94509803920000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="barTintColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="barTintColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<textAttributes key="titleTextAttributes">
|
<textAttributes key="titleTextAttributes">
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="24"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="24"/>
|
||||||
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</textAttributes>
|
</textAttributes>
|
||||||
</navigationBar>
|
</navigationBar>
|
||||||
<nil name="viewControllers"/>
|
<nil name="viewControllers"/>
|
||||||
@@ -657,19 +646,19 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="3AE-ED-0oj" customClass="ListObserverDemoViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController id="3AE-ED-0oj" customClass="ListObserverDemoViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="DAz-BE-6Ca">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="DAz-BE-6Ca">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="592" height="268"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="301.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="PaletteTableViewCell" id="G3X-70-BCD" customClass="PaletteTableViewCell" customModule="CoreStoreDemo" customModuleProvider="target">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="PaletteTableViewCell" id="G3X-70-BCD" customClass="PaletteTableViewCell" customModule="CoreStoreDemo" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="66" width="592" height="44"/>
|
<rect key="frame" x="0.0" y="22" width="375" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="G3X-70-BCD" id="aT8-nz-i5l">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="G3X-70-BCD" id="aT8-nz-i5l">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="559" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uQX-PI-UWF">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uQX-PI-UWF">
|
||||||
<rect key="frame" x="8" y="8" width="27" height="27"/>
|
<rect key="frame" x="8" y="8" width="27" height="27"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" secondItem="uQX-PI-UWF" secondAttribute="height" multiplier="1:1" id="9qA-iN-Neb"/>
|
<constraint firstAttribute="width" secondItem="uQX-PI-UWF" secondAttribute="height" multiplier="1:1" id="9qA-iN-Neb"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
@@ -677,7 +666,7 @@
|
|||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HJC-5w-lIN">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HJC-5w-lIN">
|
||||||
<rect key="frame" x="45" y="8" width="34.5" height="27"/>
|
<rect key="frame" x="45" y="8" width="34.5" height="27"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="14"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="14"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -716,20 +705,20 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="lCE-i6-UCT" customClass="ListObserverDemoViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController id="lCE-i6-UCT" customClass="ListObserverDemoViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="Zba-8M-Zd7">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="Zba-8M-Zd7">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="592" height="268"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="301.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="PaletteTableViewCell" id="zSO-3e-OVq" customClass="PaletteTableViewCell" customModule="CoreStoreDemo" customModuleProvider="target">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="PaletteTableViewCell" id="zSO-3e-OVq" customClass="PaletteTableViewCell" customModule="CoreStoreDemo" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="66" width="592" height="44"/>
|
<rect key="frame" x="0.0" y="22" width="375" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zSO-3e-OVq" id="cHA-by-n4b">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zSO-3e-OVq" id="cHA-by-n4b">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="559" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5uq-Yi-XwH">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5uq-Yi-XwH">
|
||||||
<rect key="frame" x="8" y="8" width="27" height="27"/>
|
<rect key="frame" x="8" y="8" width="27" height="27"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" secondItem="5uq-Yi-XwH" secondAttribute="height" multiplier="1:1" id="oOe-HC-VyN"/>
|
<constraint firstAttribute="width" secondItem="5uq-Yi-XwH" secondAttribute="height" multiplier="1:1" id="oOe-HC-VyN"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
@@ -737,7 +726,7 @@
|
|||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Zyu-PC-WmO">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Zyu-PC-WmO">
|
||||||
<rect key="frame" x="45" y="8" width="34.5" height="27"/>
|
<rect key="frame" x="45" y="8" width="34.5" height="27"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="14"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="14"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -780,11 +769,11 @@
|
|||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="6XA-6M-yvZ">
|
<navigationBar key="navigationBar" contentMode="scaleToFill" id="6XA-6M-yvZ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<color key="tintColor" red="0.74117647060000003" green="0.76470588240000004" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.68773996829986572" green="0.71417498588562012" blue="0.73246318101882935" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="barTintColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="barTintColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<textAttributes key="titleTextAttributes">
|
<textAttributes key="titleTextAttributes">
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Thin" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Thin" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.74117647060000003" green="0.76470588240000004" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.68773996829986572" green="0.71417498588562012" blue="0.73246318101882935" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</textAttributes>
|
</textAttributes>
|
||||||
</navigationBar>
|
</navigationBar>
|
||||||
<nil name="viewControllers"/>
|
<nil name="viewControllers"/>
|
||||||
@@ -805,17 +794,17 @@
|
|||||||
<viewControllerLayoutGuide type="bottom" id="RZg-hi-T8O"/>
|
<viewControllerLayoutGuide type="bottom" id="RZg-hi-T8O"/>
|
||||||
</layoutGuides>
|
</layoutGuides>
|
||||||
<view key="view" contentMode="scaleToFill" id="k4s-iL-Krh">
|
<view key="view" contentMode="scaleToFill" id="k4s-iL-Krh">
|
||||||
<rect key="frame" x="0.0" y="64" width="600" height="536"/>
|
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="V2U-0R-Ts0">
|
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="V2U-0R-Ts0">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="536"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="536"/>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="delegate" destination="jPl-fH-NlD" id="Sjn-YC-haS"/>
|
<outlet property="delegate" destination="jPl-fH-NlD" id="Sjn-YC-haS"/>
|
||||||
</connections>
|
</connections>
|
||||||
</mapView>
|
</mapView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="RZg-hi-T8O" firstAttribute="top" secondItem="V2U-0R-Ts0" secondAttribute="bottom" id="GcS-Jz-Wcm"/>
|
<constraint firstItem="RZg-hi-T8O" firstAttribute="top" secondItem="V2U-0R-Ts0" secondAttribute="bottom" id="GcS-Jz-Wcm"/>
|
||||||
<constraint firstItem="V2U-0R-Ts0" firstAttribute="top" secondItem="k4s-iL-Krh" secondAttribute="top" id="S5Z-Da-V6J"/>
|
<constraint firstItem="V2U-0R-Ts0" firstAttribute="top" secondItem="k4s-iL-Krh" secondAttribute="top" id="S5Z-Da-V6J"/>
|
||||||
@@ -842,30 +831,30 @@
|
|||||||
<viewControllerLayoutGuide type="bottom" id="Cwn-Jd-4Lr"/>
|
<viewControllerLayoutGuide type="bottom" id="Cwn-Jd-4Lr"/>
|
||||||
</layoutGuides>
|
</layoutGuides>
|
||||||
<view key="view" contentMode="scaleToFill" id="n9M-Je-Dj0">
|
<view key="view" contentMode="scaleToFill" id="n9M-Je-Dj0">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" alwaysBounceVertical="YES" indicatorStyle="white" editable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TpK-gX-CTN">
|
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" alwaysBounceVertical="YES" indicatorStyle="white" editable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="TpK-gX-CTN">
|
||||||
<rect key="frame" x="0.0" y="142" width="600" height="458"/>
|
<rect key="frame" x="0.0" y="142" width="375" height="525"/>
|
||||||
<color key="backgroundColor" red="0.20392156862745098" green="0.28627450980392155" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="textColor" red="0.94509803921568625" green="0.7686274509803922" blue="0.058823529411764705" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.92706394195556641" green="0.72759377956390381" blue="0.064024783670902252" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<fontDescription key="fontDescription" name="AppleSDGothicNeo-Regular" family="Apple SD Gothic Neo" pointSize="15"/>
|
<fontDescription key="fontDescription" name="AppleSDGothicNeo-Regular" family="Apple SD Gothic Neo" pointSize="15"/>
|
||||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||||
</textView>
|
</textView>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bordered" momentary="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4iq-B4-k0p">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bordered" momentary="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4iq-B4-k0p">
|
||||||
<rect key="frame" x="20" y="94" width="560" height="29"/>
|
<rect key="frame" x="20" y="94" width="335" height="29"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Log"/>
|
<segment title="Log"/>
|
||||||
<segment title="Error"/>
|
<segment title="Error"/>
|
||||||
<segment title="Assert"/>
|
<segment title="Assert"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="segmentedControlValueChanged:" destination="5yy-0N-QDU" eventType="valueChanged" id="2pp-Vt-2Os"/>
|
<action selector="segmentedControlValueChanged:" destination="5yy-0N-QDU" eventType="valueChanged" id="2pp-Vt-2Os"/>
|
||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="4iq-B4-k0p" firstAttribute="leading" secondItem="n9M-Je-Dj0" secondAttribute="leading" constant="20" id="6SM-eN-NxP"/>
|
<constraint firstItem="4iq-B4-k0p" firstAttribute="leading" secondItem="n9M-Je-Dj0" secondAttribute="leading" constant="20" id="6SM-eN-NxP"/>
|
||||||
<constraint firstItem="TpK-gX-CTN" firstAttribute="leading" secondItem="n9M-Je-Dj0" secondAttribute="leading" id="AAw-IG-taz"/>
|
<constraint firstItem="TpK-gX-CTN" firstAttribute="leading" secondItem="n9M-Je-Dj0" secondAttribute="leading" id="AAw-IG-taz"/>
|
||||||
@@ -901,11 +890,11 @@
|
|||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="wJo-mp-1pS">
|
<navigationBar key="navigationBar" contentMode="scaleToFill" id="wJo-mp-1pS">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<color key="tintColor" red="0.74117647058823533" green="0.76470588235294112" blue="0.7803921568627451" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.68773996829986572" green="0.71417498588562012" blue="0.73246318101882935" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="barTintColor" red="0.17254901960784313" green="0.24313725490196078" blue="0.31372549019607843" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="barTintColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<textAttributes key="titleTextAttributes">
|
<textAttributes key="titleTextAttributes">
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Thin" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Thin" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.74117647060000003" green="0.76470588240000004" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.68773996829986572" green="0.71417498588562012" blue="0.73246318101882935" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</textAttributes>
|
</textAttributes>
|
||||||
</navigationBar>
|
</navigationBar>
|
||||||
<nil name="viewControllers"/>
|
<nil name="viewControllers"/>
|
||||||
@@ -926,15 +915,15 @@
|
|||||||
<viewControllerLayoutGuide type="bottom" id="DlN-cN-JXd"/>
|
<viewControllerLayoutGuide type="bottom" id="DlN-cN-JXd"/>
|
||||||
</layoutGuides>
|
</layoutGuides>
|
||||||
<view key="view" contentMode="scaleToFill" id="eC3-ql-d2o">
|
<view key="view" contentMode="scaleToFill" id="eC3-ql-d2o">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="WGY-kX-mAx">
|
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="WGY-kX-mAx">
|
||||||
<rect key="frame" x="0.0" y="64" width="600" height="536"/>
|
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
|
||||||
<color key="backgroundColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="separatorColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="separatorColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<view key="tableHeaderView" contentMode="scaleToFill" id="iaH-1W-Sbo">
|
<view key="tableHeaderView" contentMode="scaleToFill" id="iaH-1W-Sbo">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="80"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="80"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bordered" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="YVj-dA-fyV">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bordered" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="YVj-dA-fyV">
|
||||||
@@ -943,13 +932,13 @@
|
|||||||
<segment title="Fetch"/>
|
<segment title="Fetch"/>
|
||||||
<segment title="Query"/>
|
<segment title="Query"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="segmentedControlValueChanged:" destination="qbj-MK-nIY" eventType="valueChanged" id="Wok-dl-uq7"/>
|
<action selector="segmentedControlValueChanged:" destination="qbj-MK-nIY" eventType="valueChanged" id="Wok-dl-uq7"/>
|
||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="0.80000000000000004" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="YVj-dA-fyV" firstAttribute="leading" secondItem="iaH-1W-Sbo" secondAttribute="leading" constant="20" id="1dX-t7-dyR"/>
|
<constraint firstItem="YVj-dA-fyV" firstAttribute="leading" secondItem="iaH-1W-Sbo" secondAttribute="leading" constant="20" id="1dX-t7-dyR"/>
|
||||||
<constraint firstAttribute="centerY" secondItem="YVj-dA-fyV" secondAttribute="centerY" id="HXU-Z7-jfu"/>
|
<constraint firstAttribute="centerY" secondItem="YVj-dA-fyV" secondAttribute="centerY" id="HXU-Z7-jfu"/>
|
||||||
@@ -958,17 +947,17 @@
|
|||||||
</view>
|
</view>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="6db-P0-6Ms" style="IBUITableViewCellStyleDefault" id="vUr-WV-qur">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="6db-P0-6Ms" style="IBUITableViewCellStyleDefault" id="vUr-WV-qur">
|
||||||
<rect key="frame" x="0.0" y="102" width="600" height="44"/>
|
<rect key="frame" x="0.0" y="102" width="375" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="vUr-WV-qur" id="Vr0-hE-cn9">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="vUr-WV-qur" id="Vr0-hE-cn9">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="567" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6db-P0-6Ms">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="6db-P0-6Ms">
|
||||||
<rect key="frame" x="15" y="0.0" width="550" height="43.5"/>
|
<rect key="frame" x="15" y="0.0" width="325" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="18"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="18"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -981,7 +970,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</tableView>
|
</tableView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="WGY-kX-mAx" firstAttribute="top" secondItem="dgu-PC-LiB" secondAttribute="bottom" id="0pS-cU-ibk"/>
|
<constraint firstItem="WGY-kX-mAx" firstAttribute="top" secondItem="dgu-PC-LiB" secondAttribute="bottom" id="0pS-cU-ibk"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="WGY-kX-mAx" secondAttribute="trailing" id="NeY-g5-CaB"/>
|
<constraint firstAttribute="trailing" secondItem="WGY-kX-mAx" secondAttribute="trailing" id="NeY-g5-CaB"/>
|
||||||
@@ -1006,30 +995,30 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="tIs-pN-OgO" customClass="FetchingResultsViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController id="tIs-pN-OgO" customClass="FetchingResultsViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="60" sectionHeaderHeight="36" sectionFooterHeight="22" id="tVl-tT-UDk">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="60" sectionHeaderHeight="36" sectionFooterHeight="22" id="tVl-tT-UDk">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="separatorColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="separatorColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="RgX-yK-1L2" detailTextLabel="QZ4-A2-x4h" style="IBUITableViewCellStyleSubtitle" id="uBt-Iy-nWP">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="RgX-yK-1L2" detailTextLabel="QZ4-A2-x4h" style="IBUITableViewCellStyleSubtitle" id="uBt-Iy-nWP">
|
||||||
<rect key="frame" x="0.0" y="100" width="600" height="60"/>
|
<rect key="frame" x="0.0" y="36" width="375" height="60"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="uBt-Iy-nWP" id="6SD-ur-9zp">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="uBt-Iy-nWP" id="6SD-ur-9zp">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="59.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="59.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="name" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RgX-yK-1L2">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="name" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RgX-yK-1L2">
|
||||||
<rect key="frame" x="15" y="11" width="48.5" height="24"/>
|
<rect key="frame" x="15" y="11" width="48.5" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="offset" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QZ4-A2-x4h">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="offset" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QZ4-A2-x4h">
|
||||||
<rect key="frame" x="15" y="35" width="31" height="13.5"/>
|
<rect key="frame" x="15" y="35" width="31" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
@@ -1052,30 +1041,30 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<tableViewController id="o9D-Xm-13g" customClass="QueryingResultsViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController id="o9D-Xm-13g" customClass="QueryingResultsViewController" customModule="CoreStoreDemo" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="60" sectionHeaderHeight="36" sectionFooterHeight="22" id="bMh-zR-xwu">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="60" sectionHeaderHeight="36" sectionFooterHeight="22" id="bMh-zR-xwu">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="separatorColor" red="0.20392156859999999" green="0.28627450980000002" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="separatorColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="Syt-QJ-KXg" detailTextLabel="yHS-dP-IKS" style="IBUITableViewCellStyleSubtitle" id="q7Q-aF-Ftl">
|
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="UITableViewCell" textLabel="Syt-QJ-KXg" detailTextLabel="yHS-dP-IKS" style="IBUITableViewCellStyleSubtitle" id="q7Q-aF-Ftl">
|
||||||
<rect key="frame" x="0.0" y="100" width="600" height="60"/>
|
<rect key="frame" x="0.0" y="36" width="375" height="60"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="q7Q-aF-Ftl" id="fc3-eg-yes">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="q7Q-aF-Ftl" id="fc3-eg-yes">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="600" height="59.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="59.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="name" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Syt-QJ-KXg">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="name" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Syt-QJ-KXg">
|
||||||
<rect key="frame" x="15" y="11" width="48.5" height="24"/>
|
<rect key="frame" x="15" y="11" width="48.5" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="offset" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="yHS-dP-IKS">
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="offset" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="yHS-dP-IKS">
|
||||||
<rect key="frame" x="15" y="35" width="31" height="13.5"/>
|
<rect key="frame" x="15" y="35" width="31" height="13.5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||||
<color key="textColor" red="0.17254901959999999" green="0.24313725489999999" blue="0.31372549020000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ private struct Static {
|
|||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
_ = try? dataStack.perform(
|
||||||
_ = dataStack.beginSynchronous { (transaction) -> Void in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
transaction.deleteAll(From<TimeZone>())
|
transaction.deleteAll(From<TimeZone>())
|
||||||
|
|
||||||
@@ -38,10 +38,8 @@ private struct Static {
|
|||||||
cachedTimeZone.hasDaylightSavingTime = rawTimeZone.isDaylightSavingTime
|
cachedTimeZone.hasDaylightSavingTime = rawTimeZone.isDaylightSavingTime
|
||||||
cachedTimeZone.daylightSavingTimeOffset = rawTimeZone.daylightSavingTimeOffset
|
cachedTimeZone.daylightSavingTimeOffset = rawTimeZone.daylightSavingTimeOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = transaction.commitAndWait()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
return dataStack
|
return dataStack
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.0.1</string>
|
<string>4.0.1</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>4</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ private struct Static {
|
|||||||
|
|
||||||
didSet {
|
didSet {
|
||||||
|
|
||||||
self.palettes.refetch(self.filter.whereClause())
|
self.palettes.refetch(
|
||||||
|
self.filter.whereClause(),
|
||||||
|
OrderBy(.ascending(#keyPath(Palette.hue)))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,11 +175,13 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
|||||||
|
|
||||||
case .delete:
|
case .delete:
|
||||||
let palette = Static.palettes[indexPath]
|
let palette = Static.palettes[indexPath]
|
||||||
CoreStore.beginAsynchronous{ (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
transaction.delete(palette)
|
transaction.delete(palette)
|
||||||
transaction.commit { (result) -> Void in }
|
},
|
||||||
}
|
completion: { _ in }
|
||||||
|
)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@@ -263,11 +268,13 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
|||||||
|
|
||||||
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
|
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
|
||||||
|
|
||||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
transaction.deleteAll(From<Palette>())
|
transaction.deleteAll(From<Palette>())
|
||||||
transaction.commit()
|
},
|
||||||
}
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
|
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
|
||||||
@@ -277,13 +284,14 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
|||||||
|
|
||||||
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
|
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
|
||||||
|
|
||||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
let palette = transaction.create(Into<Palette>())
|
let palette = transaction.create(Into<Palette>())
|
||||||
palette.setInitialValues()
|
palette.setInitialValues()
|
||||||
|
},
|
||||||
transaction.commit()
|
completion: { _ in }
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setTable(enabled: Bool) {
|
private func setTable(enabled: Bool) {
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
CoreStore.beginSynchronous { (transaction) -> Void in
|
_ = try? CoreStore.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let palette = transaction.create(Into(Palette.self))
|
let palette = transaction.create(Into(Palette.self))
|
||||||
palette.setInitialValues()
|
palette.setInitialValues()
|
||||||
|
|
||||||
_ = transaction.commitAndWait()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue))))!
|
let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue))))!
|
||||||
self.monitor = CoreStore.monitorObject(palette)
|
self.monitor = CoreStore.monitorObject(palette)
|
||||||
@@ -121,49 +121,57 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
|||||||
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
|
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
|
||||||
|
|
||||||
let hue = self.hueSlider?.value ?? 0
|
let hue = self.hueSlider?.value ?? 0
|
||||||
CoreStore.beginAsynchronous { [weak self] (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { [weak self] (transaction) in
|
||||||
|
|
||||||
if let palette = transaction.edit(self?.monitor?.object) {
|
if let palette = transaction.edit(self?.monitor?.object) {
|
||||||
|
|
||||||
palette.hue = Int32(hue)
|
palette.hue = Int32(hue)
|
||||||
transaction.commit()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
|
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
|
||||||
|
|
||||||
let saturation = self.saturationSlider?.value ?? 0
|
let saturation = self.saturationSlider?.value ?? 0
|
||||||
CoreStore.beginAsynchronous { [weak self] (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { [weak self] (transaction) in
|
||||||
|
|
||||||
if let palette = transaction.edit(self?.monitor?.object) {
|
if let palette = transaction.edit(self?.monitor?.object) {
|
||||||
|
|
||||||
palette.saturation = saturation
|
palette.saturation = saturation
|
||||||
transaction.commit()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
|
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
|
||||||
|
|
||||||
let brightness = self.brightnessSlider?.value ?? 0
|
let brightness = self.brightnessSlider?.value ?? 0
|
||||||
CoreStore.beginAsynchronous { [weak self] (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { [weak self] (transaction) in
|
||||||
|
|
||||||
if let palette = transaction.edit(self?.monitor?.object) {
|
if let palette = transaction.edit(self?.monitor?.object) {
|
||||||
|
|
||||||
palette.brightness = brightness
|
palette.brightness = brightness
|
||||||
transaction.commit()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
|
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
|
||||||
|
|
||||||
CoreStore.beginAsynchronous { [weak self] (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { [weak self] (transaction) in
|
||||||
|
|
||||||
transaction.delete(self?.monitor?.object)
|
transaction.delete(self?.monitor?.object)
|
||||||
transaction.commit()
|
},
|
||||||
}
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
|
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class Palette: NSManagedObject {
|
|||||||
get {
|
get {
|
||||||
|
|
||||||
let KVCKey = #keyPath(Palette.colorName)
|
let KVCKey = #keyPath(Palette.colorName)
|
||||||
if let colorName = self.accessValueForKVCKey(KVCKey) as? String {
|
if let colorName = self.getValue(forKvcKey: KVCKey) as? String {
|
||||||
|
|
||||||
return colorName
|
return colorName
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ class Palette: NSManagedObject {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
|
||||||
self.setValue(newValue, forKVCKey: #keyPath(Palette.colorName))
|
self.setValue(newValue.cs_toImportableNativeType(), forKvcKey: #keyPath(Palette.colorName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,10 +98,9 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
|
|||||||
switch self.segmentedControl?.selectedSegmentIndex {
|
switch self.segmentedControl?.selectedSegmentIndex {
|
||||||
|
|
||||||
case 0?:
|
case 0?:
|
||||||
self.dataStack.beginAsynchronous { (transaction) -> Void in
|
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||||
|
Where(true).applyToFetchRequest(request)
|
||||||
_ = transaction.create(Into<Palette>())
|
Where(false).applyToFetchRequest(request)
|
||||||
}
|
|
||||||
|
|
||||||
case 1?:
|
case 1?:
|
||||||
_ = try? dataStack.addStorageAndWait(
|
_ = try? dataStack.addStorageAndWait(
|
||||||
@@ -112,10 +111,9 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
|
|||||||
)
|
)
|
||||||
|
|
||||||
case 2?:
|
case 2?:
|
||||||
self.dataStack.beginAsynchronous { (transaction) -> Void in
|
DispatchQueue.global(qos: .background).async {
|
||||||
|
|
||||||
transaction.commit()
|
_ = self.dataStack.fetchOne(From<Palette>())
|
||||||
transaction.commit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
}
|
}
|
||||||
for model in models {
|
for model in models {
|
||||||
|
|
||||||
if model.version == storeVersion {
|
if model.schemaHistory.currentModelVersion == storeVersion {
|
||||||
|
|
||||||
return model
|
return model
|
||||||
}
|
}
|
||||||
@@ -91,6 +91,11 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func listMonitorDidRefetch(_ monitor: ListMonitor<NSManagedObject>) {
|
||||||
|
|
||||||
|
self.listMonitorDidChange(monitor)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: UITableViewDataSource
|
// MARK: UITableViewDataSource
|
||||||
|
|
||||||
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
@@ -115,16 +120,17 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
|
|
||||||
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
|
self.setSelectedIndexPath(indexPath, scrollToSelection: false)
|
||||||
self.setEnabled(false)
|
self.setEnabled(false)
|
||||||
dataStack.beginAsynchronous { [weak self] (transaction) -> Void in
|
dataStack.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
let organism = transaction.edit(organism) as! OrganismProtocol
|
let organism = transaction.edit(organism) as! OrganismProtocol
|
||||||
organism.mutate()
|
organism.mutate()
|
||||||
|
},
|
||||||
transaction.commit { _ -> Void in
|
completion: { [weak self] _ in
|
||||||
|
|
||||||
self?.setEnabled(true)
|
self?.setEnabled(true)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
@@ -140,29 +146,47 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private typealias ModelMetadata = (label: String, version: String, entityType: AnyClass, migrationChain: MigrationChain)
|
private typealias ModelMetadata = (label: String, entityType: NSManagedObject.Type, schemaHistory: SchemaHistory)
|
||||||
|
|
||||||
private let models: [ModelMetadata] = [
|
private let models: [ModelMetadata] = [
|
||||||
(
|
(
|
||||||
label: "Model V1",
|
label: "Model V1",
|
||||||
version: "MigrationDemo",
|
|
||||||
entityType: OrganismV1.self,
|
entityType: OrganismV1.self,
|
||||||
|
schemaHistory: SchemaHistory(
|
||||||
|
XcodeDataModelSchema.from(
|
||||||
|
modelName: "MigrationDemo",
|
||||||
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
||||||
),
|
),
|
||||||
|
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
||||||
|
)
|
||||||
|
),
|
||||||
(
|
(
|
||||||
label: "Model V2",
|
label: "Model V2",
|
||||||
version: "MigrationDemoV2",
|
|
||||||
entityType: OrganismV2.self,
|
entityType: OrganismV2.self,
|
||||||
|
schemaHistory: SchemaHistory(
|
||||||
|
XcodeDataModelSchema.from(
|
||||||
|
modelName: "MigrationDemo",
|
||||||
migrationChain: [
|
migrationChain: [
|
||||||
"MigrationDemo": "MigrationDemoV2",
|
"MigrationDemo": "MigrationDemoV2",
|
||||||
"MigrationDemoV3": "MigrationDemoV2"
|
"MigrationDemoV3": "MigrationDemoV2"
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
migrationChain: [
|
||||||
|
"MigrationDemo": "MigrationDemoV2",
|
||||||
|
"MigrationDemoV3": "MigrationDemoV2"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
(
|
(
|
||||||
label: "Model V3",
|
label: "Model V3",
|
||||||
version: "MigrationDemoV3",
|
|
||||||
entityType: OrganismV3.self,
|
entityType: OrganismV3.self,
|
||||||
|
schemaHistory: SchemaHistory(
|
||||||
|
XcodeDataModelSchema.from(
|
||||||
|
modelName: "MigrationDemo",
|
||||||
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
||||||
|
),
|
||||||
|
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -209,21 +233,44 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
|
|
||||||
private func selectModelVersion(_ model: ModelMetadata) {
|
private func selectModelVersion(_ model: ModelMetadata) {
|
||||||
|
|
||||||
if self.dataStack?.modelVersion == model.version {
|
if self.dataStack?.modelVersion == model.schemaHistory.currentModelVersion {
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set(dataStack: nil, model: nil, scrollToSelection: false) // explicitly trigger NSPersistentStore cleanup by deallocating the stack
|
self.set(dataStack: nil, model: nil, scrollToSelection: false) // explicitly trigger NSPersistentStore cleanup by deallocating the stack
|
||||||
|
|
||||||
let dataStack = DataStack(
|
let dataStack = DataStack(schemaHistory: model.schemaHistory)
|
||||||
modelName: "MigrationDemo",
|
|
||||||
migrationChain: model.migrationChain
|
|
||||||
)
|
|
||||||
|
|
||||||
self.setEnabled(false)
|
self.setEnabled(false)
|
||||||
let progress = dataStack.addStorage(
|
let progress = dataStack.addStorage(
|
||||||
SQLiteStore(fileName: "MigrationDemo.sqlite"),
|
SQLiteStore(
|
||||||
|
fileName: "MigrationDemo.sqlite",
|
||||||
|
migrationMappingProviders: [
|
||||||
|
CustomSchemaMappingProvider(
|
||||||
|
from: "MigrationDemoV3",
|
||||||
|
to: "MigrationDemoV2",
|
||||||
|
entityMappings: [
|
||||||
|
.transformEntity(
|
||||||
|
sourceEntity: "Organism",
|
||||||
|
destinationEntity: "Organism",
|
||||||
|
transformer: { (source, createDestination) in
|
||||||
|
|
||||||
|
let destination = createDestination()
|
||||||
|
destination.enumerateAttributes { (attribute, sourceAttribute) in
|
||||||
|
|
||||||
|
if let sourceAttribute = sourceAttribute {
|
||||||
|
|
||||||
|
destination[attribute] = source[sourceAttribute]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destination["numberOfFlippers"] = source["numberOfLimbs"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
completion: { [weak self] (result) -> Void in
|
completion: { [weak self] (result) -> Void in
|
||||||
|
|
||||||
guard let `self` = self else {
|
guard let `self` = self else {
|
||||||
@@ -250,7 +297,8 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
|
|
||||||
for i: Int64 in 0 ..< 20 {
|
for i: Int64 in 0 ..< 20 {
|
||||||
|
|
||||||
dataStack.beginAsynchronous { (transaction) -> Void in
|
dataStack.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
for j: Int64 in 0 ..< 500 {
|
for j: Int64 in 0 ..< 500 {
|
||||||
|
|
||||||
@@ -258,17 +306,17 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
organism.dna = (i * 500) + j + 1
|
organism.dna = (i * 500) + j + 1
|
||||||
organism.mutate()
|
organism.mutate()
|
||||||
}
|
}
|
||||||
|
},
|
||||||
transaction.commit()
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
dataStack.perform(
|
||||||
dataStack.beginAsynchronous { [weak self] (transaction) -> Void in
|
asynchronous: { _ in },
|
||||||
|
completion: { [weak self] _ in
|
||||||
transaction.commit { _ in
|
|
||||||
|
|
||||||
self?.setEnabled(true)
|
self?.setEnabled(true)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -311,7 +359,13 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
|||||||
|
|
||||||
if let dataStack = dataStack, let model = model {
|
if let dataStack = dataStack, let model = model {
|
||||||
|
|
||||||
self.segmentedControl?.selectedSegmentIndex = self.models.map { $0.version }.index(of: model.version)!
|
self.segmentedControl?.selectedSegmentIndex = self.models
|
||||||
|
.index(
|
||||||
|
where: { (_, _, schemaHistory) -> Bool in
|
||||||
|
|
||||||
|
schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
|
||||||
|
}
|
||||||
|
)!
|
||||||
|
|
||||||
self._dataStack = dataStack
|
self._dataStack = dataStack
|
||||||
let listMonitor = dataStack.monitorList(From(model.entityType), OrderBy(.descending("dna")))
|
let listMonitor = dataStack.monitorList(From(model.entityType), OrderBy(.descending("dna")))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" standalone="no"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE database SYSTEM "file:///System/Library/DTDs/CoreData.dtd">
|
<!DOCTYPE database SYSTEM "file:///System/Library/DTDs/CoreData.dtd">
|
||||||
|
|
||||||
<database>
|
<database>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSPersistenceFrameworkVersion</key>
|
<key>NSPersistenceFrameworkVersion</key>
|
||||||
<integer>526</integer>
|
<integer>754</integer>
|
||||||
<key>NSStoreModelVersionHashes</key>
|
<key>NSStoreModelVersionHashes</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>XDDevAttributeMapping</key>
|
<key>XDDevAttributeMapping</key>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11198.3" systemVersion="15F34" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16E195" minimumToolsVersion="Xcode 4.3" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||||
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV3" syncable="YES">
|
<entity name="Organism" representedClassName="CoreStoreDemo.OrganismV3" syncable="YES">
|
||||||
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="dna" optional="YES" attributeType="Integer 64" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="hasHead" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="hasHead" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="hasTail" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="hasTail" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="hasVertebrae" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="hasVertebrae" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="numberOfLimbs" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
<attribute name="numberOfLimbs" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" elementID="numberOfFlippers" syncable="YES"/>
|
||||||
</entity>
|
</entity>
|
||||||
<elements>
|
<elements>
|
||||||
<element name="Organism" positionX="-36" positionY="9" width="128" height="120"/>
|
<element name="Organism" positionX="-36" positionY="9" width="128" height="120"/>
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ private struct Static {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
_ = dataStack.beginSynchronous { (transaction) -> Void in
|
_ = try? dataStack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
transaction.deleteAll(From<UserAccount>())
|
transaction.deleteAll(From<UserAccount>())
|
||||||
|
|
||||||
@@ -46,9 +47,8 @@ private struct Static {
|
|||||||
account2.accountType = "Facebook"
|
account2.accountType = "Facebook"
|
||||||
account2.name = "Jane Doe HCD"
|
account2.name = "Jane Doe HCD"
|
||||||
account2.friends = 314
|
account2.friends = 314
|
||||||
|
|
||||||
_ = transaction.commitAndWait()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return dataStack
|
return dataStack
|
||||||
}()
|
}()
|
||||||
@@ -71,7 +71,8 @@ private struct Static {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
_ = dataStack.beginSynchronous { (transaction) -> Void in
|
_ = try? dataStack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
transaction.deleteAll(From<UserAccount>())
|
transaction.deleteAll(From<UserAccount>())
|
||||||
|
|
||||||
@@ -84,10 +85,8 @@ private struct Static {
|
|||||||
account2.accountType = "Twitter"
|
account2.accountType = "Twitter"
|
||||||
account2.name = "#janedoe_hcd"
|
account2.name = "#janedoe_hcd"
|
||||||
account2.friends = 100
|
account2.friends = 100
|
||||||
|
|
||||||
_ = transaction.commitAndWait()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
return dataStack
|
return dataStack
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ private struct Static {
|
|||||||
var place = CoreStore.fetchOne(From<Place>())
|
var place = CoreStore.fetchOne(From<Place>())
|
||||||
if place == nil {
|
if place == nil {
|
||||||
|
|
||||||
_ = CoreStore.beginSynchronous { (transaction) -> Void in
|
_ = try? CoreStore.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let place = transaction.create(Into<Place>())
|
let place = transaction.create(Into<Place>())
|
||||||
place.setInitialValues()
|
place.setInitialValues()
|
||||||
|
|
||||||
_ = transaction.commitAndWait()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
place = CoreStore.fetchOne(From<Place>())
|
place = CoreStore.fetchOne(From<Place>())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,23 +169,26 @@ class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, Objec
|
|||||||
gesture.location(in: mapView),
|
gesture.location(in: mapView),
|
||||||
toCoordinateFrom: mapView
|
toCoordinateFrom: mapView
|
||||||
)
|
)
|
||||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
CoreStore.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
let place = transaction.edit(Static.placeController.object)
|
let place = transaction.edit(Static.placeController.object)
|
||||||
place?.coordinate = coordinate
|
place?.coordinate = coordinate
|
||||||
transaction.commit { (_) -> Void in }
|
},
|
||||||
}
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction dynamic func refreshButtonTapped(_ sender: AnyObject?) {
|
@IBAction dynamic func refreshButtonTapped(_ sender: AnyObject?) {
|
||||||
|
|
||||||
_ = CoreStore.beginSynchronous { (transaction) -> Void in
|
_ = try? CoreStore.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let place = transaction.edit(Static.placeController.object)
|
let place = transaction.edit(Static.placeController.object)
|
||||||
place?.setInitialValues()
|
place?.setInitialValues()
|
||||||
_ = transaction.commitAndWait()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func geocode(place: Place) {
|
func geocode(place: Place) {
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ class BaseTestCase: XCTestCase {
|
|||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func prepareStack<T>(configurations: [String?] = [nil], _ closure: (_ dataStack: DataStack) -> T) -> T {
|
func prepareStack<T>(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> T) -> T {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import CoreStore
|
|||||||
class BaseTestDataTestCase: BaseTestCase {
|
class BaseTestDataTestCase: BaseTestCase {
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
let dateFormatter: DateFormatter = {
|
let dateFormatter: DateFormatter = cs_lazy {
|
||||||
|
|
||||||
let formatter = DateFormatter()
|
let formatter = DateFormatter()
|
||||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||||
@@ -25,12 +25,13 @@ class BaseTestDataTestCase: BaseTestCase {
|
|||||||
formatter.calendar = Calendar(identifier: Calendar.Identifier.gregorian)
|
formatter.calendar = Calendar(identifier: Calendar.Identifier.gregorian)
|
||||||
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"
|
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"
|
||||||
return formatter
|
return formatter
|
||||||
}()
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
func prepareTestDataForStack(_ stack: DataStack, configurations: [String?] = [nil]) {
|
func prepareTestDataForStack(_ stack: DataStack, configurations: [ModelConfiguration] = [nil]) {
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
try! stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
for (configurationIndex, configuration) in configurations.enumerated() {
|
for (configurationIndex, configuration) in configurations.enumerated() {
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ class BaseTestDataTestCase: BaseTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = transaction.commitAndWait()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,7 +163,7 @@
|
|||||||
- (void)test_ThatDataStacks_BridgeCorrectly {
|
- (void)test_ThatDataStacks_BridgeCorrectly {
|
||||||
|
|
||||||
CSDataStack *dataStack = [[CSDataStack alloc]
|
CSDataStack *dataStack = [[CSDataStack alloc]
|
||||||
initWithModelName:@"Model"
|
initWithXcodeModelName:@"Model"
|
||||||
bundle:[NSBundle bundleForClass:[self class]]
|
bundle:[NSBundle bundleForClass:[self class]]
|
||||||
versionChain:nil];
|
versionChain:nil];
|
||||||
XCTAssertNotNil(dataStack);
|
XCTAssertNotNil(dataStack);
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
|
|
||||||
[CSCoreStore
|
[CSCoreStore
|
||||||
setDefaultStack:[[CSDataStack alloc]
|
setDefaultStack:[[CSDataStack alloc]
|
||||||
initWithModelName:@"Model"
|
initWithXcodeModelName:@"Model"
|
||||||
bundle:[NSBundle bundleForClass:[self class]]
|
bundle:[NSBundle bundleForClass:[self class]]
|
||||||
versionChain:nil]];
|
versionChain:nil]];
|
||||||
[CSCoreStore
|
[CSCoreStore
|
||||||
@@ -212,15 +212,27 @@
|
|||||||
CSUnsafeDataTransaction *transaction = [CSCoreStore beginUnsafe];
|
CSUnsafeDataTransaction *transaction = [CSCoreStore beginUnsafe];
|
||||||
XCTAssertNotNil(transaction);
|
XCTAssertNotNil(transaction);
|
||||||
XCTAssert([transaction isKindOfClass:[CSUnsafeDataTransaction class]]);
|
XCTAssert([transaction isKindOfClass:[CSUnsafeDataTransaction class]]);
|
||||||
|
NSError *error;
|
||||||
|
BOOL result = [transaction commitAndWaitWithError:&error];
|
||||||
|
XCTAssertTrue(result);
|
||||||
|
XCTAssertNil(error);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"sync"];
|
XCTestExpectation *expectation = [self expectationWithDescription:@"sync"];
|
||||||
[CSCoreStore beginSynchronous:^(CSSynchronousDataTransaction * _Nonnull transaction) {
|
NSError *error;
|
||||||
|
BOOL result = [CSCoreStore
|
||||||
|
beginSynchronous:^(CSSynchronousDataTransaction * _Nonnull transaction) {
|
||||||
|
|
||||||
XCTAssertNotNil(transaction);
|
XCTAssertNotNil(transaction);
|
||||||
XCTAssert([transaction isKindOfClass:[CSSynchronousDataTransaction class]]);
|
XCTAssert([transaction isKindOfClass:[CSSynchronousDataTransaction class]]);
|
||||||
|
NSError *error;
|
||||||
|
XCTAssertTrue([transaction commitAndWaitWithError:&error]);
|
||||||
|
XCTAssertNil(error);
|
||||||
[expectation fulfill];
|
[expectation fulfill];
|
||||||
}];
|
}
|
||||||
|
error:&error];
|
||||||
|
XCTAssertTrue(result);
|
||||||
|
XCTAssertNil(error);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
XCTestExpectation *expectation = [self expectationWithDescription:@"async"];
|
XCTestExpectation *expectation = [self expectationWithDescription:@"async"];
|
||||||
@@ -228,42 +240,18 @@
|
|||||||
|
|
||||||
XCTAssertNotNil(transaction);
|
XCTAssertNotNil(transaction);
|
||||||
XCTAssert([transaction isKindOfClass:[CSAsynchronousDataTransaction class]]);
|
XCTAssert([transaction isKindOfClass:[CSAsynchronousDataTransaction class]]);
|
||||||
|
[transaction
|
||||||
|
commitWithSuccess:^{
|
||||||
|
|
||||||
[expectation fulfill];
|
[expectation fulfill];
|
||||||
|
}
|
||||||
|
failure:^(CSError *error){
|
||||||
|
|
||||||
|
XCTFail();
|
||||||
|
}];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
[self waitForExpectationsWithTimeout:10 handler:nil];
|
[self waitForExpectationsWithTimeout:10 handler:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TARGET_OS_IOS || TARGET_OS_WATCHOS || TARGET_OS_TV
|
|
||||||
|
|
||||||
- (void)test_ThatDataStacks_CanCreateCustomFetchedResultsControllers {
|
|
||||||
|
|
||||||
[CSCoreStore
|
|
||||||
setDefaultStack:[[CSDataStack alloc]
|
|
||||||
initWithModelName:@"Model"
|
|
||||||
bundle:[NSBundle bundleForClass:[self class]]
|
|
||||||
versionChain:nil]];
|
|
||||||
[CSCoreStore
|
|
||||||
addInMemoryStorageAndWait:[CSInMemoryStore new]
|
|
||||||
error:nil];
|
|
||||||
NSFetchedResultsController *controller =
|
|
||||||
[[CSCoreStore defaultStack]
|
|
||||||
createFetchedResultsControllerFrom:CSFromClass([TestEntity1 class])
|
|
||||||
sectionBy:[CSSectionBy keyPath:CSKeyPath(TestEntity1, testString)]
|
|
||||||
fetchClauses:@[CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100),
|
|
||||||
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil),
|
|
||||||
CSTweakRequest(^(NSFetchRequest *fetchRequest) { fetchRequest.fetchLimit = 10; })]];
|
|
||||||
|
|
||||||
XCTAssertNotNil(controller);
|
|
||||||
XCTAssertEqualObjects(controller.fetchRequest.entity.managedObjectClassName, [[TestEntity1 class] description]);
|
|
||||||
XCTAssertEqualObjects(controller.sectionNameKeyPath, CSKeyPath(TestEntity1, testString));
|
|
||||||
XCTAssertEqualObjects(controller.fetchRequest.predicate,
|
|
||||||
CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100).predicate);
|
|
||||||
XCTAssertEqualObjects(controller.fetchRequest.sortDescriptors,
|
|
||||||
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil).sortDescriptors);
|
|
||||||
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -27,10 +27,9 @@
|
|||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - ConvenienceTests
|
// MARK: - ConvenienceTests
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
class ConvenienceTests: BaseTestCase {
|
class ConvenienceTests: BaseTestCase {
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -90,5 +89,3 @@ class ConvenienceTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
211
CoreStoreTests/DynamicModelTests.swift
Normal file
211
CoreStoreTests/DynamicModelTests.swift
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
//
|
||||||
|
// DynamicModelTests.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable
|
||||||
|
import CoreStore
|
||||||
|
|
||||||
|
#if os(OSX)
|
||||||
|
typealias Color = NSColor
|
||||||
|
#else
|
||||||
|
|
||||||
|
typealias Color = UIColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Animal: CoreStoreObject {
|
||||||
|
|
||||||
|
let species = Value.Required<String>("species", default: "Swift")
|
||||||
|
let master = Relationship.ToOne<Person>("master")
|
||||||
|
let color = Transformable.Optional<Color>("color")
|
||||||
|
}
|
||||||
|
|
||||||
|
class Dog: Animal {
|
||||||
|
|
||||||
|
let nickname = Value.Optional<String>("nickname")
|
||||||
|
let age = Value.Required<Int>("age", default: 1)
|
||||||
|
let friends = Relationship.ToManyOrdered<Dog>("friends")
|
||||||
|
let friendedBy = Relationship.ToManyUnordered<Dog>("friendedBy", inverse: { $0.friends })
|
||||||
|
}
|
||||||
|
|
||||||
|
class Person: CoreStoreObject {
|
||||||
|
let title = Value.Required<String>("title", default: "Mr.")
|
||||||
|
let name = Value.Required<String>(
|
||||||
|
"name",
|
||||||
|
customGetter: { (`self`, getValue) in
|
||||||
|
|
||||||
|
return "\(self.title.value) \(getValue())"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - DynamicModelTests
|
||||||
|
|
||||||
|
class DynamicModelTests: BaseTestDataTestCase {
|
||||||
|
|
||||||
|
func testDynamicModels_CanBeDeclaredCorrectly() {
|
||||||
|
|
||||||
|
let dataStack = DataStack(
|
||||||
|
CoreStoreSchema(
|
||||||
|
modelVersion: "V1",
|
||||||
|
entities: [
|
||||||
|
Entity<Animal>("Animal"),
|
||||||
|
Entity<Dog>("Dog"),
|
||||||
|
Entity<Person>("Person")
|
||||||
|
],
|
||||||
|
versionLock: [
|
||||||
|
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
|
||||||
|
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
|
||||||
|
"Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.prepareStack(dataStack, configurations: [nil]) { (stack) in
|
||||||
|
|
||||||
|
let k1 = Animal.keyPath({ $0.species })
|
||||||
|
XCTAssertEqual(k1, "species")
|
||||||
|
|
||||||
|
let k2 = Dog.keyPath({ $0.species })
|
||||||
|
XCTAssertEqual(k2, "species")
|
||||||
|
|
||||||
|
let k3 = Dog.keyPath({ $0.nickname })
|
||||||
|
XCTAssertEqual(k3, "nickname")
|
||||||
|
|
||||||
|
let updateDone = self.expectation(description: "update-done")
|
||||||
|
let fetchDone = self.expectation(description: "fetch-done")
|
||||||
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
|
let animal = transaction.create(Into<Animal>())
|
||||||
|
XCTAssertEqual(animal.species.value, "Swift")
|
||||||
|
XCTAssertTrue(type(of: animal.species.value) == String.self)
|
||||||
|
|
||||||
|
animal.species .= "Sparrow"
|
||||||
|
XCTAssertEqual(animal.species.value, "Sparrow")
|
||||||
|
|
||||||
|
animal.color .= .yellow
|
||||||
|
XCTAssertEqual(animal.color.value, Color.yellow)
|
||||||
|
|
||||||
|
let dog = transaction.create(Into<Dog>())
|
||||||
|
XCTAssertEqual(dog.species.value, "Swift")
|
||||||
|
XCTAssertEqual(dog.nickname.value, nil)
|
||||||
|
XCTAssertEqual(dog.age.value, 1)
|
||||||
|
|
||||||
|
dog.species .= "Dog"
|
||||||
|
XCTAssertEqual(dog.species.value, "Dog")
|
||||||
|
|
||||||
|
dog.nickname .= "Spot"
|
||||||
|
XCTAssertEqual(dog.nickname.value, "Spot")
|
||||||
|
|
||||||
|
let person = transaction.create(Into<Person>())
|
||||||
|
XCTAssertTrue(person.pets.value.isEmpty)
|
||||||
|
|
||||||
|
person.name .= "John"
|
||||||
|
XCTAssertEqual(person.name.value, "Mr. John") // Custom getter
|
||||||
|
|
||||||
|
person.title .= "Sir"
|
||||||
|
XCTAssertEqual(person.name.value, "Sir John")
|
||||||
|
|
||||||
|
person.pets.value.insert(dog)
|
||||||
|
XCTAssertEqual(person.pets.count, 1)
|
||||||
|
XCTAssertEqual(person.pets.value.first, dog)
|
||||||
|
XCTAssertEqual(person.pets.value.first?.master.value, person)
|
||||||
|
XCTAssertEqual(dog.master.value, person)
|
||||||
|
XCTAssertEqual(dog.master.value?.pets.value.first, dog)
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
|
||||||
|
updateDone.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
|
let p1 = Animal.where({ $0.species == "Sparrow" })
|
||||||
|
XCTAssertEqual(p1.predicate, NSPredicate(format: "%K == %@", "species", "Sparrow"))
|
||||||
|
|
||||||
|
let bird = transaction.fetchOne(From<Animal>(), p1)
|
||||||
|
XCTAssertNotNil(bird)
|
||||||
|
XCTAssertEqual(bird!.species.value, "Sparrow")
|
||||||
|
|
||||||
|
let p2 = Dog.where({ $0.nickname == "Spot" })
|
||||||
|
XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot"))
|
||||||
|
|
||||||
|
let dog = transaction.fetchOne(From<Dog>(), p2)
|
||||||
|
XCTAssertNotNil(dog)
|
||||||
|
XCTAssertEqual(dog!.nickname.value, "Spot")
|
||||||
|
XCTAssertEqual(dog!.species.value, "Dog")
|
||||||
|
|
||||||
|
let person = transaction.fetchOne(From<Person>())
|
||||||
|
XCTAssertNotNil(person)
|
||||||
|
XCTAssertEqual(person!.pets.value.first, dog)
|
||||||
|
|
||||||
|
let p3 = Dog.where({ $0.age == 10 })
|
||||||
|
XCTAssertEqual(p3.predicate, NSPredicate(format: "%K == %d", "age", 10))
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
|
||||||
|
fetchDone.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.waitAndCheckExpectations()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@nonobjc
|
||||||
|
func prepareStack(_ dataStack: DataStack, configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> Void) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
try configurations.forEach { (configuration) in
|
||||||
|
|
||||||
|
try dataStack.addStorageAndWait(
|
||||||
|
SQLiteStore(
|
||||||
|
fileURL: SQLiteStore.defaultRootDirectory
|
||||||
|
.appendingPathComponent(UUID().uuidString)
|
||||||
|
.appendingPathComponent("\(type(of: self))_\((configuration ?? "-null-")).sqlite"),
|
||||||
|
configuration: configuration,
|
||||||
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch let error as NSError {
|
||||||
|
|
||||||
|
XCTFail(error.coreStoreDumpString)
|
||||||
|
}
|
||||||
|
closure(dataStack)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -85,16 +85,21 @@ final class ErrorTests: XCTestCase {
|
|||||||
|
|
||||||
let dummyURL = URL(string: "file:///test1/test2.sqlite")!
|
let dummyURL = URL(string: "file:///test1/test2.sqlite")!
|
||||||
|
|
||||||
let model = NSManagedObjectModel.fromBundle(Bundle(for: type(of: self)), modelName: "Model")
|
let schemaHistory = SchemaHistory(
|
||||||
|
XcodeDataModelSchema.from(
|
||||||
|
modelName: "Model",
|
||||||
|
bundle: Bundle(for: type(of: self))
|
||||||
|
)
|
||||||
|
)
|
||||||
let version = "1.0.0"
|
let version = "1.0.0"
|
||||||
|
|
||||||
let error = CoreStoreError.mappingModelNotFound(localStoreURL: dummyURL, targetModel: model, targetModelVersion: version)
|
let error = CoreStoreError.mappingModelNotFound(localStoreURL: dummyURL, targetModel: schemaHistory.rawModel, targetModelVersion: version)
|
||||||
XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain)
|
XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain)
|
||||||
XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
|
XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.mappingModelNotFound.rawValue)
|
||||||
|
|
||||||
let userInfo: NSDictionary = [
|
let userInfo: NSDictionary = [
|
||||||
"localStoreURL": dummyURL,
|
"localStoreURL": dummyURL,
|
||||||
"targetModel": model,
|
"targetModel": schemaHistory.rawModel,
|
||||||
"targetModelVersion": version
|
"targetModelVersion": version
|
||||||
]
|
]
|
||||||
let objcError = error.bridgeToObjectiveC
|
let objcError = error.bridgeToObjectiveC
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacksAndTransactions_CanFetchOneExisting() {
|
dynamic func test_ThatDataStacksAndTransactions_CanFetchOneExisting() {
|
||||||
|
|
||||||
let configurations: [String?] = ["Config1"]
|
let configurations: [ModelConfiguration] = ["Config1"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -72,15 +72,30 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let fetchExpectation = self.expectation(description: "fetch")
|
let fetchExpectation = self.expectation(description: "fetch")
|
||||||
|
|
||||||
var existing1: TestEntity1?
|
var existing1: TestEntity1?
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
existing1 = transaction.fetchExisting(object)
|
existing1 = transaction.fetchExisting(object)
|
||||||
XCTAssertNotNil(existing1)
|
XCTAssertNotNil(existing1)
|
||||||
XCTAssertEqual(existing1!.objectID, object.objectID)
|
XCTAssertEqual(existing1!.objectID, object.objectID)
|
||||||
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
||||||
|
|
||||||
|
try transaction.cancel()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
|
catch CoreStoreError.userCancelled {
|
||||||
|
|
||||||
fetchExpectation.fulfill()
|
fetchExpectation.fulfill()
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
|
|
||||||
let existing2 = stack.fetchExisting(existing1!)
|
let existing2 = stack.fetchExisting(existing1!)
|
||||||
XCTAssertNotNil(existing2)
|
XCTAssertNotNil(existing2)
|
||||||
XCTAssertEqual(existing2!.objectID, object.objectID)
|
XCTAssertEqual(existing2!.objectID, object.objectID)
|
||||||
@@ -89,14 +104,24 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let fetchExpectation = self.expectation(description: "fetch")
|
let fetchExpectation = self.expectation(description: "fetch")
|
||||||
stack.beginAsynchronous { (transaction) in
|
var existing1: TestEntity1?
|
||||||
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
let existing1 = transaction.fetchExisting(object)
|
existing1 = transaction.fetchExisting(object)
|
||||||
XCTAssertNotNil(existing1)
|
XCTAssertNotNil(existing1)
|
||||||
XCTAssertEqual(existing1!.objectID, object.objectID)
|
XCTAssertEqual(existing1!.objectID, object.objectID)
|
||||||
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
XCTAssertEqual(existing1!.managedObjectContext, transaction.context)
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
try transaction.cancel()
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
},
|
||||||
|
failure: { (error) in
|
||||||
|
|
||||||
|
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||||
|
|
||||||
let existing2 = stack.fetchExisting(existing1!)
|
let existing2 = stack.fetchExisting(existing1!)
|
||||||
XCTAssertNotNil(existing2)
|
XCTAssertNotNil(existing2)
|
||||||
@@ -105,7 +130,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
fetchExpectation.fulfill()
|
fetchExpectation.fulfill()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
@@ -114,7 +139,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacksAndTransactions_CanFetchAllExisting() {
|
dynamic func test_ThatDataStacksAndTransactions_CanFetchAllExisting() {
|
||||||
|
|
||||||
let configurations: [String?] = ["Config1"]
|
let configurations: [ModelConfiguration] = ["Config1"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -165,7 +190,10 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let fetchExpectation = self.expectation(description: "fetch")
|
let fetchExpectation = self.expectation(description: "fetch")
|
||||||
|
|
||||||
var existing1 = [TestEntity1]()
|
var existing1 = [TestEntity1]()
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
existing1 = transaction.fetchExisting(objects)
|
existing1 = transaction.fetchExisting(objects)
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
@@ -177,8 +205,19 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object.managedObjectContext, transaction.context)
|
XCTAssertEqual(object.managedObjectContext, transaction.context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try transaction.cancel()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
|
catch CoreStoreError.userCancelled {
|
||||||
|
|
||||||
fetchExpectation.fulfill()
|
fetchExpectation.fulfill()
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
}
|
||||||
let existing2 = stack.fetchExisting(existing1)
|
let existing2 = stack.fetchExisting(existing1)
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
existing2.map { $0.objectID },
|
existing2.map { $0.objectID },
|
||||||
@@ -192,9 +231,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let fetchExpectation = self.expectation(description: "fetch")
|
let fetchExpectation = self.expectation(description: "fetch")
|
||||||
stack.beginAsynchronous { (transaction) in
|
var existing1 = [TestEntity1]()
|
||||||
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
let existing1 = transaction.fetchExisting(objects)
|
existing1 = transaction.fetchExisting(objects)
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
existing1.map { $0.objectID },
|
existing1.map { $0.objectID },
|
||||||
objects.map { $0.objectID }
|
objects.map { $0.objectID }
|
||||||
@@ -203,7 +244,15 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
XCTAssertEqual(object.managedObjectContext, transaction.context)
|
XCTAssertEqual(object.managedObjectContext, transaction.context)
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async {
|
try transaction.cancel()
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
},
|
||||||
|
failure: { (error) in
|
||||||
|
|
||||||
|
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||||
|
|
||||||
let existing2 = stack.fetchExisting(existing1)
|
let existing2 = stack.fetchExisting(existing1)
|
||||||
XCTAssertEqual(
|
XCTAssertEqual(
|
||||||
@@ -216,7 +265,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
fetchExpectation.fulfill()
|
fetchExpectation.fulfill()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
@@ -225,7 +274,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchOneFromDefaultConfiguration() {
|
dynamic func test_ThatDataStacks_CanFetchOneFromDefaultConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -364,7 +413,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchOneFromSingleConfiguration() {
|
dynamic func test_ThatDataStacks_CanFetchOneFromSingleConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -380,11 +429,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
let object = stack.fetchOne(from, fetchClauses)
|
let object = stack.fetchOne(from, fetchClauses)
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 2) // configuration ambiguous
|
|
||||||
|
|
||||||
let objectID = stack.fetchObjectID(from, fetchClauses)
|
let objectID = stack.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectID)
|
XCTAssertNotNil(objectID)
|
||||||
XCTAssertEqual(objectID, object?.objectID)
|
|
||||||
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -394,11 +443,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
let object = stack.fetchOne(from, fetchClauses)
|
let object = stack.fetchOne(from, fetchClauses)
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 3) // configuration
|
|
||||||
|
|
||||||
let objectID = stack.fetchObjectID(from, fetchClauses)
|
let objectID = stack.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectID)
|
XCTAssertNotNil(objectID)
|
||||||
XCTAssertEqual(objectID, object?.objectID)
|
|
||||||
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -547,7 +596,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchOneFromMultipleConfigurations() {
|
dynamic func test_ThatDataStacks_CanFetchOneFromMultipleConfigurations() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -563,11 +612,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
let object = stack.fetchOne(from, fetchClauses)
|
let object = stack.fetchOne(from, fetchClauses)
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 2) // configuration is ambiguous
|
|
||||||
|
|
||||||
let objectID = stack.fetchObjectID(from, fetchClauses)
|
let objectID = stack.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectID)
|
XCTAssertNotNil(objectID)
|
||||||
XCTAssertEqual(objectID, object?.objectID)
|
|
||||||
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -577,11 +626,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
]
|
]
|
||||||
let object = stack.fetchOne(from, fetchClauses)
|
let object = stack.fetchOne(from, fetchClauses)
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.testNumber, 3) // configuration is ambiguous
|
|
||||||
|
|
||||||
let objectID = stack.fetchObjectID(from, fetchClauses)
|
let objectID = stack.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectID)
|
XCTAssertNotNil(objectID)
|
||||||
XCTAssertEqual(objectID, object?.objectID)
|
|
||||||
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -690,7 +739,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchAllFromDefaultConfiguration() {
|
dynamic func test_ThatDataStacks_CanFetchAllFromDefaultConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -899,7 +948,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchAllFromSingleConfiguration() {
|
dynamic func test_ThatDataStacks_CanFetchAllFromSingleConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -917,18 +966,12 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objects = stack.fetchAll(from, fetchClauses)
|
let objects = stack.fetchAll(from, fetchClauses)
|
||||||
XCTAssertNotNil(objects)
|
XCTAssertNotNil(objects)
|
||||||
XCTAssertEqual(objects?.count, 3)
|
XCTAssertEqual(objects?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
Set((objects ?? []).map { $0.testNumber!.intValue }),
|
|
||||||
[4, 5] as Set<Int>
|
|
||||||
) // configuration is ambiguous
|
|
||||||
|
|
||||||
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 3)
|
XCTAssertEqual(objectIDs?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
(objectIDs ?? []),
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
(objects ?? []).map { $0.objectID }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -940,18 +983,12 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objects = stack.fetchAll(from, fetchClauses)
|
let objects = stack.fetchAll(from, fetchClauses)
|
||||||
XCTAssertNotNil(objects)
|
XCTAssertNotNil(objects)
|
||||||
XCTAssertEqual(objects?.count, 3)
|
XCTAssertEqual(objects?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
Set((objects ?? []).map { $0.testNumber!.intValue }),
|
|
||||||
[1, 2] as Set<Int>
|
|
||||||
) // configuration is ambiguous
|
|
||||||
|
|
||||||
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 3)
|
XCTAssertEqual(objectIDs?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
(objectIDs ?? []),
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
(objects ?? []).map { $0.objectID }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -1148,7 +1185,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchAllFromMultipleConfigurations() {
|
dynamic func test_ThatDataStacks_CanFetchAllFromMultipleConfigurations() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -1166,18 +1203,12 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objects = stack.fetchAll(from, fetchClauses)
|
let objects = stack.fetchAll(from, fetchClauses)
|
||||||
XCTAssertNotNil(objects)
|
XCTAssertNotNil(objects)
|
||||||
XCTAssertEqual(objects?.count, 3)
|
XCTAssertEqual(objects?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
Set((objects ?? []).map { $0.testNumber!.intValue }),
|
|
||||||
[4, 5] as Set<Int>
|
|
||||||
) // configuration is ambiguous
|
|
||||||
|
|
||||||
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 3)
|
XCTAssertEqual(objectIDs?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
(objectIDs ?? []),
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
(objects ?? []).map { $0.objectID }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -1189,18 +1220,12 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objects = stack.fetchAll(from, fetchClauses)
|
let objects = stack.fetchAll(from, fetchClauses)
|
||||||
XCTAssertNotNil(objects)
|
XCTAssertNotNil(objects)
|
||||||
XCTAssertEqual(objects?.count, 3)
|
XCTAssertEqual(objects?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
Set((objects ?? []).map { $0.testNumber!.intValue }),
|
|
||||||
[1, 2] as Set<Int>
|
|
||||||
) // configuration is ambiguous
|
|
||||||
|
|
||||||
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
let objectIDs = stack.fetchObjectIDs(from, fetchClauses)
|
||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 3)
|
XCTAssertEqual(objectIDs?.count, 3)
|
||||||
XCTAssertEqual(
|
|
||||||
(objectIDs ?? []),
|
// configuration ambiguous, no other behavior should be relied on
|
||||||
(objects ?? []).map { $0.objectID }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -1359,7 +1384,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchCountFromDefaultConfiguration() {
|
dynamic func test_ThatDataStacks_CanFetchCountFromDefaultConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -1482,7 +1507,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchCountFromSingleConfiguration() {
|
dynamic func test_ThatDataStacks_CanFetchCountFromSingleConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -1641,7 +1666,7 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanFetchCountFromMultipleConfigurations() {
|
dynamic func test_ThatDataStacks_CanFetchCountFromMultipleConfigurations() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -1760,12 +1785,12 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchOneFromDefaultConfiguration() {
|
dynamic func test_ThatTransactions_CanFetchOneFromDefaultConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>()
|
let from = From<TestEntity1>()
|
||||||
do {
|
do {
|
||||||
@@ -1808,8 +1833,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil)
|
let from = From<TestEntity1>(nil)
|
||||||
do {
|
do {
|
||||||
@@ -1852,8 +1880,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1")
|
let from = From<TestEntity1>("Config1")
|
||||||
do {
|
do {
|
||||||
@@ -1892,19 +1923,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchOneFromSingleConfiguration() {
|
dynamic func test_ThatTransactions_CanFetchOneFromSingleConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>()
|
let from = From<TestEntity1>()
|
||||||
do {
|
do {
|
||||||
@@ -1947,8 +1980,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil)
|
let from = From<TestEntity1>(nil)
|
||||||
do {
|
do {
|
||||||
@@ -1991,8 +2027,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1")
|
let from = From<TestEntity1>("Config1")
|
||||||
do {
|
do {
|
||||||
@@ -2035,8 +2074,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config2")
|
let from = From<TestEntity1>("Config2")
|
||||||
do {
|
do {
|
||||||
@@ -2075,19 +2117,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchOneFromMultipleConfigurations() {
|
dynamic func test_ThatTransactions_CanFetchOneFromMultipleConfigurations() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil, "Config1")
|
let from = From<TestEntity1>(nil, "Config1")
|
||||||
do {
|
do {
|
||||||
@@ -2130,8 +2174,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil, "Config2")
|
let from = From<TestEntity1>(nil, "Config2")
|
||||||
do {
|
do {
|
||||||
@@ -2174,8 +2221,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1", "Config2")
|
let from = From<TestEntity1>("Config1", "Config2")
|
||||||
do {
|
do {
|
||||||
@@ -2218,19 +2268,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
let objectID = transaction.fetchObjectID(from, fetchClauses)
|
||||||
XCTAssertNil(objectID)
|
XCTAssertNil(objectID)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchAllFromDefaultConfiguration() {
|
dynamic func test_ThatTransactions_CanFetchAllFromDefaultConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>()
|
let from = From<TestEntity1>()
|
||||||
do {
|
do {
|
||||||
@@ -2299,8 +2351,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil)
|
let from = From<TestEntity1>(nil)
|
||||||
do {
|
do {
|
||||||
@@ -2369,8 +2424,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1")
|
let from = From<TestEntity1>("Config1")
|
||||||
do {
|
do {
|
||||||
@@ -2427,19 +2485,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertNil(objectIDs)
|
XCTAssertNil(objectIDs)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchAllFromSingleConfiguration() {
|
dynamic func test_ThatTransactions_CanFetchAllFromSingleConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>()
|
let from = From<TestEntity1>()
|
||||||
do {
|
do {
|
||||||
@@ -2502,8 +2562,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil)
|
let from = From<TestEntity1>(nil)
|
||||||
do {
|
do {
|
||||||
@@ -2570,8 +2633,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1")
|
let from = From<TestEntity1>("Config1")
|
||||||
do {
|
do {
|
||||||
@@ -2638,8 +2704,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config2")
|
let from = From<TestEntity1>("Config2")
|
||||||
do {
|
do {
|
||||||
@@ -2676,19 +2745,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertNil(objectIDs)
|
XCTAssertNil(objectIDs)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchAllFromMultipleConfigurations() {
|
dynamic func test_ThatTransactions_CanFetchAllFromMultipleConfigurations() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil, "Config1")
|
let from = From<TestEntity1>(nil, "Config1")
|
||||||
do {
|
do {
|
||||||
@@ -2751,8 +2822,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil, "Config2")
|
let from = From<TestEntity1>(nil, "Config2")
|
||||||
do {
|
do {
|
||||||
@@ -2819,8 +2893,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1", "Config2")
|
let from = From<TestEntity1>("Config1", "Config2")
|
||||||
do {
|
do {
|
||||||
@@ -2887,19 +2964,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(objectIDs)
|
XCTAssertNotNil(objectIDs)
|
||||||
XCTAssertEqual(objectIDs?.count, 0)
|
XCTAssertEqual(objectIDs?.count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchCountFromDefaultConfiguration() {
|
dynamic func test_ThatTransactions_CanFetchCountFromDefaultConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>()
|
let from = From<TestEntity1>()
|
||||||
do {
|
do {
|
||||||
@@ -2934,8 +3013,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil)
|
let from = From<TestEntity1>(nil)
|
||||||
do {
|
do {
|
||||||
@@ -2970,8 +3052,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1")
|
let from = From<TestEntity1>("Config1")
|
||||||
do {
|
do {
|
||||||
@@ -3010,19 +3095,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertNil(count)
|
XCTAssertNil(count)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchCountFromSingleConfiguration() {
|
dynamic func test_ThatTransactions_CanFetchCountFromSingleConfiguration() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>()
|
let from = From<TestEntity1>()
|
||||||
do {
|
do {
|
||||||
@@ -3057,8 +3144,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil)
|
let from = From<TestEntity1>(nil)
|
||||||
do {
|
do {
|
||||||
@@ -3093,8 +3183,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1")
|
let from = From<TestEntity1>("Config1")
|
||||||
do {
|
do {
|
||||||
@@ -3129,8 +3222,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config2")
|
let from = From<TestEntity1>("Config2")
|
||||||
do {
|
do {
|
||||||
@@ -3169,19 +3265,21 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
XCTAssertNil(count)
|
XCTAssertNil(count)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatTransactions_CanFetchCountFromMultipleConfigurations() {
|
dynamic func test_ThatTransactions_CanFetchCountFromMultipleConfigurations() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil, "Config1", "Config2"]
|
let configurations: [ModelConfiguration] = [nil, "Config1", "Config2"]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil, "Config1")
|
let from = From<TestEntity1>(nil, "Config1")
|
||||||
do {
|
do {
|
||||||
@@ -3216,8 +3314,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>(nil, "Config2")
|
let from = From<TestEntity1>(nil, "Config2")
|
||||||
do {
|
do {
|
||||||
@@ -3252,8 +3353,11 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
_ = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let from = From<TestEntity1>("Config1", "Config2")
|
let from = From<TestEntity1>("Config1", "Config2")
|
||||||
do {
|
do {
|
||||||
@@ -3288,7 +3392,9 @@ final class FetchTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNotNil(count)
|
XCTAssertNotNil(count)
|
||||||
XCTAssertEqual(count, 0)
|
XCTAssertEqual(count, 0)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ final class FromTests: BaseTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let from = From()
|
let from = From<NSManagedObject>()
|
||||||
XCTAssert(from.entityClass === NSManagedObject.self)
|
XCTAssert(from.entityClass === NSManagedObject.self)
|
||||||
XCTAssertNil(from.configurations)
|
XCTAssertNil(from.configurations)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,10 +77,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let object = try transaction.importObject(
|
let object = try transaction.importObject(
|
||||||
Into<TestEntity1>(),
|
Into<TestEntity1>(),
|
||||||
source: [
|
source: [
|
||||||
@@ -96,11 +97,13 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,12 +112,15 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
let errorExpectation = self.expectation(description: "error")
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let _ = try transaction.importObject(
|
let errorExpectation = self.expectation(description: "error")
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
_ = try transaction.importObject(
|
||||||
Into<TestEntity1>(),
|
Into<TestEntity1>(),
|
||||||
source: [
|
source: [
|
||||||
#keyPath(TestEntity1.testBoolean): NSNumber(value: true),
|
#keyPath(TestEntity1.testBoolean): NSNumber(value: true),
|
||||||
@@ -143,13 +149,14 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNil(object?.testData)
|
XCTAssertNil(object?.testData)
|
||||||
XCTAssertNil(object?.testDate)
|
XCTAssertNil(object?.testDate)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.checkExpectationsImmediately()
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,10 +165,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let object = try transaction.importObject(
|
let object = try transaction.importObject(
|
||||||
Into<TestEntity1>(),
|
Into<TestEntity1>(),
|
||||||
source: [
|
source: [
|
||||||
@@ -203,12 +211,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:2" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(object?.testData, ("nil:TestEntity1:2" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-02T00:00:00Z")!)
|
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-02T00:00:00Z")!)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,10 +225,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let sourceArray: [TestEntity1.ImportSource] = [
|
let sourceArray: [TestEntity1.ImportSource] = [
|
||||||
[
|
[
|
||||||
#keyPath(TestEntity1.testBoolean): NSNumber(value: true),
|
#keyPath(TestEntity1.testBoolean): NSNumber(value: true),
|
||||||
@@ -257,12 +266,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
||||||
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,9 +280,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
let errorExpectation = self.expectation(description: "error")
|
let errorExpectation = self.expectation(description: "error")
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sourceArray: [TestEntity1.ImportSource] = [
|
let sourceArray: [TestEntity1.ImportSource] = [
|
||||||
@@ -316,13 +328,14 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNil(object?.testData)
|
XCTAssertNil(object?.testData)
|
||||||
XCTAssertNil(object?.testDate)
|
XCTAssertNil(object?.testDate)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.checkExpectationsImmediately()
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,10 +344,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let sourceArray: [TestEntity1.ImportSource] = [
|
let sourceArray: [TestEntity1.ImportSource] = [
|
||||||
[
|
[
|
||||||
#keyPath(TestEntity1.testBoolean): NSNumber(value: true),
|
#keyPath(TestEntity1.testBoolean): NSNumber(value: true),
|
||||||
@@ -374,12 +388,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,8 +403,10 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
do {
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -410,10 +426,6 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let object = try transaction.importUniqueObject(
|
let object = try transaction.importUniqueObject(
|
||||||
@@ -445,13 +457,15 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatImportUniqueObjects_ImportsLastOfImportSourcesWithSameIDs() {
|
dynamic func test_ThatImportUniqueObjects_ImportsLastOfImportSourcesWithSameIDs() {
|
||||||
@@ -459,11 +473,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let sourceArray: [TestEntity1.ImportSource] = [
|
let sourceArray: [TestEntity1.ImportSource] = [
|
||||||
[
|
[
|
||||||
#keyPath(TestEntity1.testEntityID): NSNumber(value: 106),
|
#keyPath(TestEntity1.testEntityID): NSNumber(value: 106),
|
||||||
@@ -502,12 +516,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
||||||
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,11 +531,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let sourceArray: [TestEntity1.ImportSource] = [
|
let sourceArray: [TestEntity1.ImportSource] = [
|
||||||
[
|
[
|
||||||
#keyPath(TestEntity1.testEntityID): NSNumber(value: 106),
|
#keyPath(TestEntity1.testEntityID): NSNumber(value: 106),
|
||||||
@@ -561,12 +575,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,11 +590,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let errorExpectation = self.expectation(description: "error")
|
let errorExpectation = self.expectation(description: "error")
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -614,13 +628,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNil(object?.testData)
|
XCTAssertNil(object?.testData)
|
||||||
XCTAssertNil(object?.testDate)
|
XCTAssertNil(object?.testDate)
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
}
|
}
|
||||||
do {
|
)
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let errorExpectation = self.expectation(description: "error")
|
let errorExpectation = self.expectation(description: "error")
|
||||||
do {
|
do {
|
||||||
@@ -659,14 +671,14 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
||||||
}
|
}
|
||||||
|
self.checkExpectationsImmediately()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
|
||||||
}
|
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,8 +688,10 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
do {
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
@@ -704,10 +718,6 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:6" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
XCTAssertEqual(object?.testData, ("nil:TestEntity1:6" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-06T00:00:00Z")!)
|
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-06T00:00:00Z")!)
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let object = try transaction.importUniqueObject(
|
let object = try transaction.importUniqueObject(
|
||||||
@@ -740,12 +750,13 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects?[0]
|
||||||
XCTAssertEqual(existingObject, object)
|
XCTAssertEqual(existingObject, object)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -755,11 +766,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let sourceArray: [TestEntity1.ImportSource] = [
|
let sourceArray: [TestEntity1.ImportSource] = [
|
||||||
[
|
[
|
||||||
#keyPath(TestEntity1.testEntityID): NSNumber(value: 106),
|
#keyPath(TestEntity1.testEntityID): NSNumber(value: 106),
|
||||||
@@ -798,12 +809,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
||||||
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,8 +824,10 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
do {
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let errorExpectation = self.expectation(description: "error")
|
let errorExpectation = self.expectation(description: "error")
|
||||||
do {
|
do {
|
||||||
@@ -854,14 +867,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
|
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
|
||||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
|
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
|
||||||
}
|
}
|
||||||
catch {
|
transaction.unsafeContext().reset()
|
||||||
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
transaction.context.reset()
|
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let errorExpectation = self.expectation(description: "error")
|
let errorExpectation = self.expectation(description: "error")
|
||||||
do {
|
do {
|
||||||
@@ -907,14 +918,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
XCTAssertNil(object?.testData)
|
XCTAssertNil(object?.testData)
|
||||||
XCTAssertNil(object?.testDate)
|
XCTAssertNil(object?.testDate)
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
self.checkExpectationsImmediately()
|
|
||||||
transaction.context.reset()
|
transaction.context.reset()
|
||||||
|
self.checkExpectationsImmediately()
|
||||||
}
|
}
|
||||||
stack.beginSynchronous { (transaction) in
|
)
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let errorExpectation = self.expectation(description: "error")
|
let errorExpectation = self.expectation(description: "error")
|
||||||
do {
|
do {
|
||||||
@@ -959,13 +968,15 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects?[0]
|
||||||
XCTAssertEqual(existingObject, object)
|
XCTAssertEqual(existingObject, object)
|
||||||
}
|
}
|
||||||
|
transaction.context.reset()
|
||||||
|
self.checkExpectationsImmediately()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,11 +986,11 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
|
|
||||||
stack.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let sourceArray: [TestEntity1.ImportSource] = [
|
let sourceArray: [TestEntity1.ImportSource] = [
|
||||||
[
|
[
|
||||||
#keyPath(TestEntity1.testEntityID): NSNumber(value: 105),
|
#keyPath(TestEntity1.testEntityID): NSNumber(value: 105),
|
||||||
@@ -1026,12 +1037,12 @@ class ImportTests: BaseTestDataTestCase {
|
|||||||
let existingObject = existingObjects?[0]
|
let existingObject = existingObjects?[0]
|
||||||
XCTAssertEqual(existingObject, objects[0])
|
XCTAssertEqual(existingObject, objects[0])
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.context.reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ final class IntoTests: XCTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatIntoClauseConstants_AreCorrect() {
|
dynamic func test_ThatIntoClauseConstants_AreCorrect() {
|
||||||
|
|
||||||
XCTAssertEqual(Into<NSManagedObject>.defaultConfigurationName, "PF_DEFAULT_CONFIGURATION_NAME")
|
XCTAssertEqual(DataStack.defaultConfigurationName, "PF_DEFAULT_CONFIGURATION_NAME")
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -44,7 +44,7 @@ final class IntoTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into()
|
let into = Into<NSManagedObject>()
|
||||||
XCTAssert(into.entityClass === NSManagedObject.self)
|
XCTAssert(into.entityClass === NSManagedObject.self)
|
||||||
XCTAssertNil(into.configuration)
|
XCTAssertNil(into.configuration)
|
||||||
XCTAssertTrue(into.inferStoreIfPossible)
|
XCTAssertTrue(into.inferStoreIfPossible)
|
||||||
@@ -58,14 +58,7 @@ final class IntoTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into<TestEntity1>()
|
let into = Into(TestEntity1.self)
|
||||||
XCTAssert(into.entityClass === TestEntity1.self)
|
|
||||||
XCTAssertNil(into.configuration)
|
|
||||||
XCTAssertTrue(into.inferStoreIfPossible)
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into(TestEntity1.self as AnyClass)
|
|
||||||
XCTAssert(into.entityClass === TestEntity1.self)
|
XCTAssert(into.entityClass === TestEntity1.self)
|
||||||
XCTAssertNil(into.configuration)
|
XCTAssertNil(into.configuration)
|
||||||
XCTAssertTrue(into.inferStoreIfPossible)
|
XCTAssertTrue(into.inferStoreIfPossible)
|
||||||
@@ -84,13 +77,6 @@ final class IntoTests: XCTestCase {
|
|||||||
XCTAssertEqual(into.configuration, "Config1")
|
XCTAssertEqual(into.configuration, "Config1")
|
||||||
XCTAssertFalse(into.inferStoreIfPossible)
|
XCTAssertFalse(into.inferStoreIfPossible)
|
||||||
}
|
}
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into(TestEntity1.self as AnyClass, "Config1")
|
|
||||||
XCTAssert(into.entityClass === TestEntity1.self)
|
|
||||||
XCTAssertEqual(into.configuration, "Config1")
|
|
||||||
XCTAssertFalse(into.inferStoreIfPossible)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -98,43 +84,30 @@ final class IntoTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into()
|
let into = Into<NSManagedObject>()
|
||||||
XCTAssertEqual(into, Into())
|
|
||||||
XCTAssertEqual(into, Into<NSManagedObject>())
|
XCTAssertEqual(into, Into<NSManagedObject>())
|
||||||
XCTAssertEqual(into, Into(NSManagedObject.self as AnyClass))
|
XCTAssertEqual(into, Into(NSManagedObject.self))
|
||||||
XCTAssertFalse(into == Into<TestEntity1>())
|
XCTAssertNotEqual(into, Into<NSManagedObject>(TestEntity1.self))
|
||||||
XCTAssertNotEqual(into, Into<NSManagedObject>("Config1"))
|
XCTAssertNotEqual(into, Into<NSManagedObject>("Config1"))
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into<TestEntity1>()
|
let into = Into<TestEntity1>()
|
||||||
XCTAssertEqual(into, Into<TestEntity1>())
|
XCTAssertEqual(into, Into<TestEntity1>())
|
||||||
XCTAssertEqual(into, Into(TestEntity1.self as AnyClass))
|
XCTAssertEqual(into, Into(TestEntity1.self))
|
||||||
XCTAssertFalse(into == Into<TestEntity2>())
|
|
||||||
XCTAssertNotEqual(into, Into<TestEntity1>("Config1"))
|
XCTAssertNotEqual(into, Into<TestEntity1>("Config1"))
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into<TestEntity1>()
|
let into = Into(TestEntity1.self)
|
||||||
XCTAssertEqual(into, Into<TestEntity1>())
|
|
||||||
XCTAssertEqual(into, Into(TestEntity1.self as AnyClass))
|
|
||||||
XCTAssertFalse(into == Into<TestEntity2>())
|
|
||||||
XCTAssertNotEqual(into, Into<TestEntity1>("Config1"))
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into(TestEntity1.self as AnyClass)
|
|
||||||
XCTAssert(into == Into<TestEntity1>())
|
XCTAssert(into == Into<TestEntity1>())
|
||||||
XCTAssertEqual(into, Into(TestEntity1.self))
|
XCTAssertEqual(into, Into(TestEntity1.self))
|
||||||
XCTAssertFalse(into == Into<TestEntity2>())
|
|
||||||
XCTAssertFalse(into == Into<TestEntity1>("Config1"))
|
XCTAssertFalse(into == Into<TestEntity1>("Config1"))
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into<TestEntity1>("Config1")
|
let into = Into<TestEntity1>("Config1")
|
||||||
XCTAssertEqual(into, Into(TestEntity1.self, "Config1"))
|
XCTAssertEqual(into, Into(TestEntity1.self, "Config1"))
|
||||||
XCTAssertEqual(into, Into(TestEntity1.self as AnyClass, "Config1"))
|
|
||||||
XCTAssertFalse(into == Into<TestEntity2>("Config1"))
|
|
||||||
XCTAssertNotEqual(into, Into<TestEntity1>("Config2"))
|
XCTAssertNotEqual(into, Into<TestEntity1>("Config2"))
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
@@ -142,16 +115,14 @@ final class IntoTests: XCTestCase {
|
|||||||
let into = Into(TestEntity1.self, "Config1")
|
let into = Into(TestEntity1.self, "Config1")
|
||||||
XCTAssertEqual(into, Into(TestEntity1.self, "Config1"))
|
XCTAssertEqual(into, Into(TestEntity1.self, "Config1"))
|
||||||
XCTAssertEqual(into, Into<TestEntity1>("Config1"))
|
XCTAssertEqual(into, Into<TestEntity1>("Config1"))
|
||||||
XCTAssertFalse(into == Into<TestEntity2>("Config1"))
|
|
||||||
XCTAssertNotEqual(into, Into<TestEntity1>("Config2"))
|
XCTAssertNotEqual(into, Into<TestEntity1>("Config2"))
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into(TestEntity1.self as AnyClass, "Config1")
|
let into = Into(TestEntity1.self, "Config1")
|
||||||
XCTAssert(into == Into<TestEntity1>("Config1"))
|
XCTAssertEqual(into, Into<TestEntity1>("Config1"))
|
||||||
XCTAssertEqual(into, Into(TestEntity1.self, "Config1"))
|
XCTAssertEqual(into, Into(TestEntity1.self, "Config1"))
|
||||||
XCTAssertFalse(into == Into<TestEntity2>("Config1"))
|
XCTAssertNotEqual(into, Into<TestEntity1>("Config2"))
|
||||||
XCTAssertFalse(into == Into<TestEntity1>("Config2"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,45 +131,9 @@ final class IntoTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let into = Into()
|
let into = Into<NSManagedObject>()
|
||||||
let objcInto = into.bridgeToObjectiveC
|
let objcInto = into.bridgeToObjectiveC
|
||||||
XCTAssertEqual(into, objcInto.bridgeToSwift)
|
XCTAssertEqual(into, objcInto.bridgeToSwift)
|
||||||
}
|
}
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into<TestEntity1>()
|
|
||||||
let objcInto = into.bridgeToObjectiveC
|
|
||||||
XCTAssertTrue(into == objcInto.bridgeToSwift)
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into(TestEntity1.self as AnyClass)
|
|
||||||
let objcInto = into.bridgeToObjectiveC
|
|
||||||
XCTAssertEqual(into, objcInto.bridgeToSwift)
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into(TestEntity1.self as AnyClass)
|
|
||||||
let objcInto = into.bridgeToObjectiveC
|
|
||||||
XCTAssertEqual(into, objcInto.bridgeToSwift)
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into<TestEntity1>("Config1")
|
|
||||||
let objcInto = into.bridgeToObjectiveC
|
|
||||||
XCTAssertTrue(into == objcInto.bridgeToSwift)
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into(TestEntity1.self, "Config1")
|
|
||||||
let objcInto = into.bridgeToObjectiveC
|
|
||||||
XCTAssertTrue(into == objcInto.bridgeToSwift)
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
|
|
||||||
let into = Into(TestEntity1.self as AnyClass, "Config1")
|
|
||||||
let objcInto = into.bridgeToObjectiveC
|
|
||||||
XCTAssertTrue(into == objcInto.bridgeToSwift)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,27 +29,11 @@ import XCTest
|
|||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - ListObserverTests
|
// MARK: - ListObserverTests
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
class ListObserverTests: BaseTestDataTestCase {
|
class ListObserverTests: BaseTestDataTestCase {
|
||||||
|
|
||||||
@objc
|
|
||||||
dynamic func test_ThatListObservers_CanDowncast() {
|
|
||||||
|
|
||||||
self.prepareStack { (stack) in
|
|
||||||
|
|
||||||
let monitor = stack.monitorSectionedList(
|
|
||||||
From<TestEntity1>(),
|
|
||||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
|
||||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
|
||||||
)
|
|
||||||
let downcast = monitor.downcast()
|
|
||||||
XCTAssertTrue(monitor == downcast)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatListObservers_CanReceiveInsertNotifications() {
|
dynamic func test_ThatListObservers_CanReceiveInsertNotifications() {
|
||||||
|
|
||||||
@@ -118,8 +102,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||||
XCTAssertEqual(indexPath?.section, 0)
|
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
||||||
XCTAssertEqual(indexPath?.row, 0)
|
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
@@ -149,7 +133,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
let saveExpectation = self.expectation(description: "save")
|
let saveExpectation = self.expectation(description: "save")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
object.testBoolean = NSNumber(value: true)
|
object.testBoolean = NSNumber(value: true)
|
||||||
@@ -159,19 +144,18 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
object.testData = ("nil:TestEntity1:1" as NSString).data(using: String.Encoding.utf8.rawValue)!
|
object.testData = ("nil:TestEntity1:1" as NSString).data(using: String.Encoding.utf8.rawValue)!
|
||||||
object.testDate = self.dateFormatter.date(from: "2000-01-01T00:00:00Z")!
|
object.testDate = self.dateFormatter.date(from: "2000-01-01T00:00:00Z")!
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
saveExpectation.fulfill()
|
saveExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
case .failure:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,8 +220,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
switch object?.testEntityID {
|
switch object?.testEntityID {
|
||||||
|
|
||||||
case NSNumber(value: 101)?:
|
case NSNumber(value: 101)?:
|
||||||
XCTAssertEqual(indexPath?.section, 1)
|
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
|
||||||
XCTAssertEqual(indexPath?.row, 0)
|
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||||
|
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||||
@@ -247,8 +231,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||||
|
|
||||||
case NSNumber(value: 102)?:
|
case NSNumber(value: 102)?:
|
||||||
XCTAssertEqual(indexPath?.section, 0)
|
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
||||||
XCTAssertEqual(indexPath?.row, 0)
|
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||||
|
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||||
@@ -283,7 +267,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
let saveExpectation = self.expectation(description: "save")
|
let saveExpectation = self.expectation(description: "save")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
if let object = transaction.fetchOne(
|
if let object = transaction.fetchOne(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
@@ -313,19 +298,18 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
saveExpectation.fulfill()
|
saveExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
case .failure:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,12 +360,12 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath
|
let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath
|
||||||
XCTAssertEqual(fromIndexPath?.section, 0)
|
XCTAssertEqual(fromIndexPath?.index(atPosition: 0), 0)
|
||||||
XCTAssertEqual(fromIndexPath?.row, 0)
|
XCTAssertEqual(fromIndexPath?.index(atPosition: 1), 0)
|
||||||
|
|
||||||
let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath
|
let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath
|
||||||
XCTAssertEqual(toIndexPath?.section, 1)
|
XCTAssertEqual(toIndexPath?.index(atPosition: 0), 1)
|
||||||
XCTAssertEqual(toIndexPath?.row, 1)
|
XCTAssertEqual(toIndexPath?.index(atPosition: 1), 1)
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 102))
|
||||||
@@ -409,7 +393,8 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
let saveExpectation = self.expectation(description: "save")
|
let saveExpectation = self.expectation(description: "save")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
if let object = transaction.fetchOne(
|
if let object = transaction.fetchOne(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
@@ -421,19 +406,18 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
saveExpectation.fulfill()
|
saveExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
case .failure:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -488,7 +472,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||||
|
|
||||||
XCTAssertEqual(indexPath?.section, 0)
|
XCTAssertEqual(indexPath?.section, 0)
|
||||||
XCTAssert(indexPath?.row == 0 || indexPath?.row == 1)
|
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
XCTAssertEqual(object?.isDeleted, true)
|
XCTAssertEqual(object?.isDeleted, true)
|
||||||
@@ -544,25 +528,25 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
let saveExpectation = self.expectation(description: "save")
|
let saveExpectation = self.expectation(description: "save")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
transaction.deleteAll(
|
transaction.deleteAll(
|
||||||
From<TestEntity1>(),
|
From<TestEntity1>(),
|
||||||
Where(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
|
Where(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
|
||||||
)
|
)
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
saveExpectation.fulfill()
|
saveExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
case .failure:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -571,6 +555,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
// MARK: TestListObserver
|
// MARK: TestListObserver
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
class TestListObserver: ListSectionObserver {
|
class TestListObserver: ListSectionObserver {
|
||||||
|
|
||||||
// MARK: ListObserver
|
// MARK: ListObserver
|
||||||
@@ -693,5 +678,3 @@ class TestListObserver: ListSectionObserver {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ final class MigrationChainTests: XCTestCase {
|
|||||||
dynamic func test_ThatNilMigrationChains_HaveNoVersions() {
|
dynamic func test_ThatNilMigrationChains_HaveNoVersions() {
|
||||||
|
|
||||||
let chain: MigrationChain = nil
|
let chain: MigrationChain = nil
|
||||||
XCTAssertTrue(chain.valid)
|
XCTAssertTrue(chain.isValid)
|
||||||
XCTAssertTrue(chain.empty)
|
XCTAssertTrue(chain.isEmpty)
|
||||||
|
|
||||||
XCTAssertFalse(chain.contains("version1"))
|
XCTAssertFalse(chain.contains("version1"))
|
||||||
XCTAssertNil(chain.nextVersionFrom("version1"))
|
XCTAssertNil(chain.nextVersionFrom("version1"))
|
||||||
@@ -48,8 +48,8 @@ final class MigrationChainTests: XCTestCase {
|
|||||||
dynamic func test_ThatStringMigrationChains_HaveOneVersion() {
|
dynamic func test_ThatStringMigrationChains_HaveOneVersion() {
|
||||||
|
|
||||||
let chain: MigrationChain = "version1"
|
let chain: MigrationChain = "version1"
|
||||||
XCTAssertTrue(chain.valid)
|
XCTAssertTrue(chain.isValid)
|
||||||
XCTAssertTrue(chain.empty)
|
XCTAssertTrue(chain.isEmpty)
|
||||||
|
|
||||||
XCTAssertTrue(chain.contains("version1"))
|
XCTAssertTrue(chain.contains("version1"))
|
||||||
XCTAssertFalse(chain.contains("version2"))
|
XCTAssertFalse(chain.contains("version2"))
|
||||||
@@ -62,8 +62,8 @@ final class MigrationChainTests: XCTestCase {
|
|||||||
dynamic func test_ThatArrayMigrationChains_HaveLinearVersions() {
|
dynamic func test_ThatArrayMigrationChains_HaveLinearVersions() {
|
||||||
|
|
||||||
let chain: MigrationChain = ["version1", "version2", "version3", "version4"]
|
let chain: MigrationChain = ["version1", "version2", "version3", "version4"]
|
||||||
XCTAssertTrue(chain.valid)
|
XCTAssertTrue(chain.isValid)
|
||||||
XCTAssertFalse(chain.empty)
|
XCTAssertFalse(chain.isEmpty)
|
||||||
|
|
||||||
XCTAssertTrue(chain.contains("version1"))
|
XCTAssertTrue(chain.contains("version1"))
|
||||||
XCTAssertTrue(chain.contains("version2"))
|
XCTAssertTrue(chain.contains("version2"))
|
||||||
@@ -86,8 +86,8 @@ final class MigrationChainTests: XCTestCase {
|
|||||||
"version2": "version3",
|
"version2": "version3",
|
||||||
"version3": "version4"
|
"version3": "version4"
|
||||||
]
|
]
|
||||||
XCTAssertTrue(chain.valid)
|
XCTAssertTrue(chain.isValid)
|
||||||
XCTAssertFalse(chain.empty)
|
XCTAssertFalse(chain.isEmpty)
|
||||||
|
|
||||||
XCTAssertTrue(chain.contains("version1"))
|
XCTAssertTrue(chain.contains("version1"))
|
||||||
XCTAssertTrue(chain.contains("version2"))
|
XCTAssertTrue(chain.contains("version2"))
|
||||||
|
|||||||
@@ -29,31 +29,10 @@ import XCTest
|
|||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - ObjectObserverTests
|
// MARK: - ObjectObserverTests
|
||||||
|
|
||||||
class ObjectObserverTests: BaseTestDataTestCase {
|
@available(OSX 10.12, *)
|
||||||
|
class ObjectObserverTests: BaseTestDataTestCase {
|
||||||
@objc
|
|
||||||
dynamic func test_ThatObjectObservers_CanDowncast() {
|
|
||||||
|
|
||||||
self.prepareStack { (stack) in
|
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack)
|
|
||||||
|
|
||||||
guard let object = stack.fetchOne(
|
|
||||||
From<TestEntity1>(),
|
|
||||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
|
||||||
|
|
||||||
XCTFail()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let monitor = stack.monitorObject(object)
|
|
||||||
let downcast = monitor.downcast()
|
|
||||||
XCTAssertTrue(monitor == downcast)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatObjectObservers_CanReceiveUpdateNotifications() {
|
dynamic func test_ThatObjectObservers_CanReceiveUpdateNotifications() {
|
||||||
@@ -125,29 +104,29 @@ import CoreStore
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
let saveExpectation = self.expectation(description: "save")
|
let saveExpectation = self.expectation(description: "save")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
guard let object = transaction.edit(object) else {
|
guard let object = transaction.edit(object) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
object.testNumber = NSNumber(value: 10)
|
object.testNumber = NSNumber(value: 10)
|
||||||
object.testString = "nil:TestEntity1:10"
|
object.testString = "nil:TestEntity1:10"
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
saveExpectation.fulfill()
|
saveExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
case .failure:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,29 +172,29 @@ import CoreStore
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
let saveExpectation = self.expectation(description: "save")
|
let saveExpectation = self.expectation(description: "save")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
guard let object = transaction.edit(object) else {
|
guard let object = transaction.edit(object) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
XCTAssertTrue(monitor.isObjectDeleted)
|
XCTAssertTrue(monitor.isObjectDeleted)
|
||||||
saveExpectation.fulfill()
|
saveExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
case .failure:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,6 +203,7 @@ import CoreStore
|
|||||||
|
|
||||||
// MARK: TestObjectObserver
|
// MARK: TestObjectObserver
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
class TestObjectObserver: ObjectObserver {
|
class TestObjectObserver: ObjectObserver {
|
||||||
|
|
||||||
typealias ObjectEntityType = TestEntity1
|
typealias ObjectEntityType = TestEntity1
|
||||||
@@ -262,5 +242,3 @@ class TestObjectObserver: ObjectObserver {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryAttributeValue() {
|
dynamic func test_ThatDataStacks_CanQueryAttributeValue() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -220,7 +220,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryAverageValue() {
|
dynamic func test_ThatDataStacks_CanQueryAverageValue() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -399,7 +399,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryCountValue() {
|
dynamic func test_ThatDataStacks_CanQueryCountValue() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -576,7 +576,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryMaximumValue() {
|
dynamic func test_ThatDataStacks_CanQueryMaximumValue() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -760,7 +760,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryMinimumValue() {
|
dynamic func test_ThatDataStacks_CanQueryMinimumValue() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -944,7 +944,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQuerySumValue() {
|
dynamic func test_ThatDataStacks_CanQuerySumValue() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -1122,7 +1122,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryObjectIDValue() {
|
dynamic func test_ThatDataStacks_CanQueryObjectIDValue() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -1290,7 +1290,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryAttributes() {
|
dynamic func test_ThatDataStacks_CanQueryAttributes() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
@@ -1344,7 +1344,7 @@ class QueryTests: BaseTestDataTestCase {
|
|||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDataStacks_CanQueryAggregates() {
|
dynamic func test_ThatDataStacks_CanQueryAggregates() {
|
||||||
|
|
||||||
let configurations: [String?] = [nil]
|
let configurations: [ModelConfiguration] = [nil]
|
||||||
self.prepareStack(configurations: configurations) { (stack) in
|
self.prepareStack(configurations: configurations) { (stack) in
|
||||||
|
|
||||||
self.prepareTestDataForStack(stack, configurations: configurations)
|
self.prepareTestDataForStack(stack, configurations: configurations)
|
||||||
|
|||||||
@@ -29,10 +29,9 @@ import XCTest
|
|||||||
import CoreStore
|
import CoreStore
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
//MARK: - SectionByTests
|
//MARK: - SectionByTests
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
final class SectionByTests: XCTestCase {
|
final class SectionByTests: XCTestCase {
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
@@ -53,5 +52,3 @@ final class SectionByTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -36,10 +36,14 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let model = NSManagedObjectModel.mergedModel(from: [Bundle(for: type(of: self))])!
|
let schemaHistory = SchemaHistory(
|
||||||
|
XcodeDataModelSchema.from(
|
||||||
let stack = DataStack(model: model, migrationChain: nil)
|
modelName: "Model",
|
||||||
XCTAssertEqual(stack.coordinator.managedObjectModel, model)
|
bundle: Bundle(for: type(of: self))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
let stack = DataStack(schemaHistory: schemaHistory)
|
||||||
|
XCTAssertEqual(stack.coordinator.managedObjectModel, schemaHistory.rawModel)
|
||||||
XCTAssertEqual(stack.rootSavingContext.persistentStoreCoordinator, stack.coordinator)
|
XCTAssertEqual(stack.rootSavingContext.persistentStoreCoordinator, stack.coordinator)
|
||||||
XCTAssertNil(stack.rootSavingContext.parent)
|
XCTAssertNil(stack.rootSavingContext.parent)
|
||||||
XCTAssertFalse(stack.rootSavingContext.isDataStackContext)
|
XCTAssertFalse(stack.rootSavingContext.isDataStackContext)
|
||||||
@@ -47,29 +51,29 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
XCTAssertEqual(stack.mainContext.parent, stack.rootSavingContext)
|
XCTAssertEqual(stack.mainContext.parent, stack.rootSavingContext)
|
||||||
XCTAssertTrue(stack.mainContext.isDataStackContext)
|
XCTAssertTrue(stack.mainContext.isDataStackContext)
|
||||||
XCTAssertFalse(stack.mainContext.isTransactionContext)
|
XCTAssertFalse(stack.mainContext.isTransactionContext)
|
||||||
XCTAssertEqual(stack.model, model)
|
XCTAssertEqual(stack.schemaHistory.rawModel, schemaHistory.rawModel)
|
||||||
XCTAssertTrue(stack.migrationChain.valid)
|
XCTAssertTrue(stack.schemaHistory.migrationChain.isValid)
|
||||||
XCTAssertTrue(stack.migrationChain.empty)
|
XCTAssertTrue(stack.schemaHistory.migrationChain.isEmpty)
|
||||||
XCTAssertTrue(stack.migrationChain.rootVersions.isEmpty)
|
XCTAssertTrue(stack.schemaHistory.migrationChain.rootVersions.isEmpty)
|
||||||
XCTAssertTrue(stack.migrationChain.leafVersions.isEmpty)
|
XCTAssertTrue(stack.schemaHistory.migrationChain.leafVersions.isEmpty)
|
||||||
|
|
||||||
CoreStore.defaultStack = stack
|
CoreStore.defaultStack = stack
|
||||||
XCTAssertEqual(CoreStore.defaultStack, stack)
|
XCTAssertEqual(CoreStore.defaultStack, stack)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let migrationChain: MigrationChain = ["version1", "version2", "version3"]
|
let migrationChain: MigrationChain = ["version1", "version2", "version3", "Model"]
|
||||||
|
|
||||||
let stack = self.expectLogger([.logWarning]) {
|
let stack = self.expectLogger([.logWarning]) {
|
||||||
|
|
||||||
DataStack(
|
DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self)),
|
bundle: Bundle(for: type(of: self)),
|
||||||
migrationChain: migrationChain
|
migrationChain: migrationChain
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
XCTAssertEqual(stack.modelVersion, "Model")
|
XCTAssertEqual(stack.modelVersion, "Model")
|
||||||
XCTAssertEqual(stack.migrationChain, migrationChain)
|
XCTAssertEqual(stack.schemaHistory.migrationChain, migrationChain)
|
||||||
|
|
||||||
CoreStore.defaultStack = stack
|
CoreStore.defaultStack = stack
|
||||||
XCTAssertEqual(CoreStore.defaultStack, stack)
|
XCTAssertEqual(CoreStore.defaultStack, stack)
|
||||||
@@ -80,7 +84,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
dynamic func test_ThatInMemoryStores_SetupCorrectly() {
|
dynamic func test_ThatInMemoryStores_SetupCorrectly() {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
@@ -135,7 +139,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
dynamic func test_ThatSQLiteStores_SetupCorrectly() {
|
dynamic func test_ThatSQLiteStores_SetupCorrectly() {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
@@ -203,14 +207,13 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
try! stack.addStorageAndWait(sqliteStore)
|
try! stack.addStorageAndWait(sqliteStore)
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
}
|
}
|
||||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
|
||||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
|
|
||||||
return try NSPersistentStoreCoordinator.metadataForPersistentStore(
|
return try NSPersistentStoreCoordinator.metadataForPersistentStore(
|
||||||
@@ -223,10 +226,13 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: stack.model[metadata])
|
try sqliteStore.cs_eraseStorageAndWait(
|
||||||
|
metadata: metadata,
|
||||||
|
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
||||||
|
)
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
@@ -238,7 +244,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
try sqliteStore.cs_eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
@@ -253,12 +259,12 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() {
|
dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sqliteStore = LegacySQLiteStore()
|
let sqliteStore = SQLiteStore.legacy()
|
||||||
do {
|
do {
|
||||||
|
|
||||||
try stack.addStorageAndWait(sqliteStore)
|
try stack.addStorageAndWait(sqliteStore)
|
||||||
@@ -273,7 +279,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sqliteStore = LegacySQLiteStore(
|
let sqliteStore = SQLiteStore.legacy(
|
||||||
fileName: "ConfigStore1.sqlite",
|
fileName: "ConfigStore1.sqlite",
|
||||||
configuration: "Config1",
|
configuration: "Config1",
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
@@ -292,7 +298,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let sqliteStore = LegacySQLiteStore(
|
let sqliteStore = SQLiteStore.legacy(
|
||||||
fileName: "ConfigStore2.sqlite",
|
fileName: "ConfigStore2.sqlite",
|
||||||
configuration: "Config2",
|
configuration: "Config2",
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
@@ -315,20 +321,19 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
dynamic func test_ThatLegacySQLiteStores_DeleteFilesCorrectly() {
|
dynamic func test_ThatLegacySQLiteStores_DeleteFilesCorrectly() {
|
||||||
|
|
||||||
let fileManager = FileManager.default
|
let fileManager = FileManager.default
|
||||||
let sqliteStore = LegacySQLiteStore()
|
let sqliteStore = SQLiteStore.legacy()
|
||||||
func createStore() throws -> [String: Any] {
|
func createStore() throws -> [String: Any] {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
try! stack.addStorageAndWait(sqliteStore)
|
try! stack.addStorageAndWait(sqliteStore)
|
||||||
self.prepareTestDataForStack(stack)
|
self.prepareTestDataForStack(stack)
|
||||||
}
|
}
|
||||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
|
||||||
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
|
|
||||||
return try NSPersistentStoreCoordinator.metadataForPersistentStore(
|
return try NSPersistentStoreCoordinator.metadataForPersistentStore(
|
||||||
@@ -341,10 +346,13 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
let stack = DataStack(
|
let stack = DataStack(
|
||||||
modelName: "Model",
|
xcodeModelName: "Model",
|
||||||
bundle: Bundle(for: type(of: self))
|
bundle: Bundle(for: type(of: self))
|
||||||
)
|
)
|
||||||
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: stack.model[metadata])
|
try sqliteStore.cs_eraseStorageAndWait(
|
||||||
|
metadata: metadata,
|
||||||
|
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
||||||
|
)
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
@@ -356,7 +364,7 @@ class SetupTests: BaseTestDataTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let metadata = try createStore()
|
let metadata = try createStore()
|
||||||
try sqliteStore.eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
try sqliteStore.cs_eraseStorageAndWait(metadata: metadata, soureModelHint: nil)
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-wal")))
|
||||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ final class StorageInterfaceTests: XCTestCase {
|
|||||||
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
||||||
|
|
||||||
XCTAssertEqual(store.fileURL, SQLiteStore.defaultFileURL)
|
XCTAssertEqual(store.fileURL, SQLiteStore.defaultFileURL)
|
||||||
XCTAssertEqual(store.mappingModelBundles, Bundle.allBundles)
|
XCTAssertTrue(store.migrationMappingProviders.isEmpty)
|
||||||
XCTAssertEqual(store.localStorageOptions, .none)
|
XCTAssertEqual(store.localStorageOptions, .none)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,12 +96,15 @@ final class StorageInterfaceTests: XCTestCase {
|
|||||||
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
|
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
|
||||||
.appendingPathComponent(NSUUID().uuidString, isDirectory: false)!
|
.appendingPathComponent(NSUUID().uuidString, isDirectory: false)!
|
||||||
.appendingPathExtension("db")
|
.appendingPathExtension("db")
|
||||||
let bundles = [Bundle(for: type(of: self))]
|
let mappingProvider = XcodeSchemaMappingProvider(
|
||||||
|
from: "V1", to: "V2",
|
||||||
|
mappingModelBundle: Bundle(for: type(of: self))
|
||||||
|
)
|
||||||
|
|
||||||
let store = SQLiteStore(
|
let store = SQLiteStore(
|
||||||
fileURL: fileURL,
|
fileURL: fileURL,
|
||||||
configuration: "config1",
|
configuration: "config1",
|
||||||
mappingModelBundles: bundles,
|
migrationMappingProviders: [mappingProvider],
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
)
|
)
|
||||||
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
||||||
@@ -109,7 +112,7 @@ final class StorageInterfaceTests: XCTestCase {
|
|||||||
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
||||||
|
|
||||||
XCTAssertEqual(store.fileURL, fileURL)
|
XCTAssertEqual(store.fileURL, fileURL)
|
||||||
XCTAssertEqual(store.mappingModelBundles, bundles)
|
XCTAssertEqual(store.migrationMappingProviders as! [XcodeSchemaMappingProvider], [mappingProvider])
|
||||||
XCTAssertEqual(store.localStorageOptions, [.recreateStoreOnModelMismatch])
|
XCTAssertEqual(store.localStorageOptions, [.recreateStoreOnModelMismatch])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,12 +120,14 @@ final class StorageInterfaceTests: XCTestCase {
|
|||||||
dynamic func test_ThatFileNameSQLiteStores_ConfigureCorrectly() {
|
dynamic func test_ThatFileNameSQLiteStores_ConfigureCorrectly() {
|
||||||
|
|
||||||
let fileName = UUID().uuidString + ".db"
|
let fileName = UUID().uuidString + ".db"
|
||||||
let bundles = [Bundle(for: type(of: self))]
|
let mappingProvider = XcodeSchemaMappingProvider(
|
||||||
|
from: "V1", to: "V2",
|
||||||
|
mappingModelBundle: Bundle(for: type(of: self))
|
||||||
|
)
|
||||||
let store = SQLiteStore(
|
let store = SQLiteStore(
|
||||||
fileName: fileName,
|
fileName: fileName,
|
||||||
configuration: "config1",
|
configuration: "config1",
|
||||||
mappingModelBundles: bundles,
|
migrationMappingProviders: [mappingProvider],
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
)
|
)
|
||||||
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
||||||
@@ -131,7 +136,7 @@ final class StorageInterfaceTests: XCTestCase {
|
|||||||
|
|
||||||
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.defaultRootDirectory)
|
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.defaultRootDirectory)
|
||||||
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)
|
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)
|
||||||
XCTAssertEqual(store.mappingModelBundles, bundles)
|
XCTAssertEqual(store.migrationMappingProviders as! [XcodeSchemaMappingProvider], [mappingProvider])
|
||||||
XCTAssertEqual(store.localStorageOptions, [.recreateStoreOnModelMismatch])
|
XCTAssertEqual(store.localStorageOptions, [.recreateStoreOnModelMismatch])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,65 +157,44 @@ final class StorageInterfaceTests: XCTestCase {
|
|||||||
.appendingPathComponent(DataStack.applicationName, isDirectory: false)
|
.appendingPathComponent(DataStack.applicationName, isDirectory: false)
|
||||||
.appendingPathExtension("sqlite")
|
.appendingPathExtension("sqlite")
|
||||||
|
|
||||||
XCTAssertEqual(LegacySQLiteStore.defaultRootDirectory, legacyDefaultRootDirectory)
|
XCTAssertEqual(SQLiteStore.legacyDefaultRootDirectory, legacyDefaultRootDirectory)
|
||||||
XCTAssertEqual(LegacySQLiteStore.defaultFileURL, legacyDefaultFileURL)
|
XCTAssertEqual(SQLiteStore.legacyDefaultFileURL, legacyDefaultFileURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatDefaultLegacySQLiteStores_ConfigureCorrectly() {
|
dynamic func test_ThatDefaultLegacySQLiteStores_ConfigureCorrectly() {
|
||||||
|
|
||||||
let store = LegacySQLiteStore()
|
let store = SQLiteStore.legacy()
|
||||||
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
||||||
XCTAssertNil(store.configuration)
|
XCTAssertNil(store.configuration)
|
||||||
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
||||||
|
|
||||||
XCTAssertEqual(store.fileURL, LegacySQLiteStore.defaultFileURL)
|
XCTAssertEqual(store.fileURL, SQLiteStore.legacyDefaultFileURL)
|
||||||
XCTAssertEqual(store.mappingModelBundles, Bundle.allBundles)
|
XCTAssertTrue(store.migrationMappingProviders.isEmpty)
|
||||||
XCTAssertEqual(store.localStorageOptions, .none)
|
XCTAssertEqual(store.localStorageOptions, .none)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
|
||||||
dynamic func test_ThatFileURLLegacySQLiteStores_ConfigureCorrectly() {
|
|
||||||
|
|
||||||
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
|
|
||||||
.appendingPathComponent(NSUUID().uuidString, isDirectory: false)!
|
|
||||||
.appendingPathExtension("db")
|
|
||||||
let bundles = [Bundle(for: type(of: self))]
|
|
||||||
|
|
||||||
let store = LegacySQLiteStore(
|
|
||||||
fileURL: fileURL,
|
|
||||||
configuration: "config1",
|
|
||||||
mappingModelBundles: bundles,
|
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
|
||||||
)
|
|
||||||
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
|
||||||
XCTAssertEqual(store.configuration, "config1")
|
|
||||||
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
|
||||||
|
|
||||||
XCTAssertEqual(store.fileURL, fileURL)
|
|
||||||
XCTAssertEqual(store.mappingModelBundles, bundles)
|
|
||||||
XCTAssertEqual(store.localStorageOptions, [.recreateStoreOnModelMismatch])
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatFileNameLegacySQLiteStores_ConfigureCorrectly() {
|
dynamic func test_ThatFileNameLegacySQLiteStores_ConfigureCorrectly() {
|
||||||
|
|
||||||
let fileName = UUID().uuidString + ".db"
|
let fileName = UUID().uuidString + ".db"
|
||||||
let bundles = [Bundle(for: type(of: self))]
|
let mappingProvider = XcodeSchemaMappingProvider(
|
||||||
|
from: "V1", to: "V2",
|
||||||
let store = LegacySQLiteStore(
|
mappingModelBundle: Bundle(for: type(of: self))
|
||||||
|
)
|
||||||
|
let store = SQLiteStore.legacy(
|
||||||
fileName: fileName,
|
fileName: fileName,
|
||||||
configuration: "config1",
|
configuration: "config1",
|
||||||
mappingModelBundles: bundles,
|
migrationMappingProviders: [mappingProvider],
|
||||||
localStorageOptions: .recreateStoreOnModelMismatch
|
localStorageOptions: .recreateStoreOnModelMismatch
|
||||||
)
|
)
|
||||||
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
|
||||||
XCTAssertEqual(store.configuration, "config1")
|
XCTAssertEqual(store.configuration, "config1")
|
||||||
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
|
||||||
|
|
||||||
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), LegacySQLiteStore.defaultRootDirectory)
|
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.legacyDefaultRootDirectory)
|
||||||
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)
|
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)
|
||||||
XCTAssertEqual(store.mappingModelBundles, bundles)
|
XCTAssertEqual(store.migrationMappingProviders as! [XcodeSchemaMappingProvider], [mappingProvider])
|
||||||
XCTAssertEqual(store.localStorageOptions, [.recreateStoreOnModelMismatch])
|
XCTAssertEqual(store.localStorageOptions, [.recreateStoreOnModelMismatch])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,40 +42,39 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let createExpectation = self.expectation(description: "create")
|
let createExpectation = self.expectation(description: "create")
|
||||||
stack.beginSynchronous { (transaction) in
|
let hasChanges: Bool = try! stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
XCTAssertEqual(transaction.context, transaction.internalContext())
|
defer {
|
||||||
|
|
||||||
|
createExpectation.fulfill()
|
||||||
|
}
|
||||||
|
XCTAssertEqual(transaction.context, transaction.unsafeContext())
|
||||||
XCTAssertTrue(transaction.context.isTransactionContext)
|
XCTAssertTrue(transaction.context.isTransactionContext)
|
||||||
XCTAssertFalse(transaction.context.isDataStackContext)
|
XCTAssertFalse(transaction.context.isDataStackContext)
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
XCTAssertEqual(object.fetchSource()?.internalContext(), transaction.context)
|
XCTAssertEqual(object.fetchSource()?.unsafeContext(), transaction.context)
|
||||||
XCTAssertEqual(object.querySource()?.internalContext(), transaction.context)
|
XCTAssertEqual(object.querySource()?.unsafeContext(), transaction.context)
|
||||||
|
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
object.testString = "string1"
|
object.testString = "string1"
|
||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
|
return transaction.hasChanges
|
||||||
switch transaction.commitAndWait() {
|
},
|
||||||
|
waitForAllObservers: true
|
||||||
case .success(let hasChanges):
|
)
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
createExpectation.fulfill()
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.fetchSource()?.internalContext(), stack.mainContext)
|
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
||||||
XCTAssertEqual(object?.querySource()?.internalContext(), stack.mainContext)
|
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
||||||
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
@@ -85,28 +84,28 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let updateExpectation = self.expectation(description: "update")
|
let updateExpectation = self.expectation(description: "update")
|
||||||
stack.beginSynchronous { (transaction) in
|
let hasChanges: Bool = try! stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
updateExpectation.fulfill()
|
||||||
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
// TODO: convert fetch methods to throwing methods
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
object.testString = "string1_edit"
|
object.testString = "string1_edit"
|
||||||
object.testNumber = 200
|
object.testNumber = 200
|
||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
case .success(let hasChanges):
|
waitForAllObservers: true
|
||||||
XCTAssertTrue(hasChanges)
|
)
|
||||||
updateExpectation.fulfill()
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
@@ -120,20 +119,25 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let deleteExpectation = self.expectation(description: "delete")
|
let deleteExpectation = self.expectation(description: "delete")
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
|
let hasChanges: Bool = try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
deleteExpectation.fulfill()
|
||||||
|
}
|
||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = transaction.fetchOne(From<TestEntity1>())
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
return transaction.hasChanges
|
||||||
switch transaction.commitAndWait() {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
deleteExpectation.fulfill()
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
XCTAssertTrue(hasChanges)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
@@ -154,23 +158,29 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let createExpectation = self.expectation(description: "create")
|
let createExpectation = self.expectation(description: "create")
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
|
let hasChanges: Bool = try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
createExpectation.fulfill()
|
||||||
|
}
|
||||||
let object = transaction.create(Into<TestEntity1>("Config1"))
|
let object = transaction.create(Into<TestEntity1>("Config1"))
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
object.testString = "string1"
|
object.testString = "string1"
|
||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
return transaction.hasChanges
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
createExpectation.fulfill()
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
XCTAssertTrue(hasChanges)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
@@ -187,26 +197,32 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let updateExpectation = self.expectation(description: "update")
|
let updateExpectation = self.expectation(description: "update")
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
|
let hasChanges: Bool = try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
updateExpectation.fulfill()
|
||||||
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
object.testString = "string1_edit"
|
object.testString = "string1_edit"
|
||||||
object.testNumber = 200
|
object.testNumber = 200
|
||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
return transaction.hasChanges
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
updateExpectation.fulfill()
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
XCTAssertTrue(hasChanges)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
@@ -223,20 +239,26 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let deleteExpectation = self.expectation(description: "delete")
|
let deleteExpectation = self.expectation(description: "delete")
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
|
let hasChanges: Bool = try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
deleteExpectation.fulfill()
|
||||||
|
}
|
||||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
return transaction.hasChanges
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
deleteExpectation.fulfill()
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
XCTAssertTrue(hasChanges)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
@@ -254,18 +276,22 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let createDiscardExpectation = self.expectation(description: "create-discard")
|
let createDiscardExpectation = self.expectation(description: "create-discard")
|
||||||
let loggerExpectations = self.prepareLoggerExpectations([.logWarning])
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
createDiscardExpectation.fulfill()
|
||||||
|
}
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
object.testString = "string1"
|
object.testString = "string1"
|
||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = Date()
|
object.testDate = Date()
|
||||||
|
|
||||||
createDiscardExpectation.fulfill()
|
try transaction.cancel()
|
||||||
self.expectLogger(loggerExpectations)
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
@@ -277,43 +303,44 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let createExpectation = self.expectation(description: "create")
|
let createExpectation = self.expectation(description: "create")
|
||||||
stack.beginSynchronous { (transaction) in
|
let dataPrepared: Void? = try? stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
object.testString = "string1"
|
object.testString = "string1"
|
||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
|
||||||
|
|
||||||
case .success(true):
|
|
||||||
createExpectation.fulfill()
|
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
if dataPrepared != nil {
|
||||||
|
|
||||||
|
createExpectation.fulfill()
|
||||||
}
|
}
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let updateDiscardExpectation = self.expectation(description: "update-discard")
|
let updateDiscardExpectation = self.expectation(description: "update-discard")
|
||||||
let loggerExpectations = self.prepareLoggerExpectations([.logWarning])
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
updateDiscardExpectation.fulfill()
|
||||||
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
object.testString = "string1_edit"
|
object.testString = "string1_edit"
|
||||||
object.testNumber = 200
|
object.testNumber = 200
|
||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
updateDiscardExpectation.fulfill()
|
try transaction.cancel()
|
||||||
self.expectLogger(loggerExpectations)
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
@@ -328,19 +355,23 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let deleteDiscardExpectation = self.expectation(description: "delete-discard")
|
let deleteDiscardExpectation = self.expectation(description: "delete-discard")
|
||||||
let loggerExpectations = self.prepareLoggerExpectations([.logWarning])
|
_ = try? stack.perform(
|
||||||
stack.beginSynchronous { (transaction) in
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
deleteDiscardExpectation.fulfill()
|
||||||
|
}
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
deleteDiscardExpectation.fulfill()
|
try transaction.cancel()
|
||||||
self.expectLogger(loggerExpectations)
|
|
||||||
}
|
}
|
||||||
|
)
|
||||||
self.checkExpectationsImmediately()
|
self.checkExpectationsImmediately()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
@@ -355,8 +386,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
|
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
|
||||||
|
|
||||||
@@ -401,8 +432,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||||
XCTAssertEqual(indexPath?.section, 0)
|
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
||||||
XCTAssertEqual(indexPath?.row, 0)
|
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||||
|
|
||||||
let object = userInfo?["object"] as? TestEntity1
|
let object = userInfo?["object"] as? TestEntity1
|
||||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||||
@@ -430,7 +461,10 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
let saveExpectation = self.expectation(description: "save")
|
let saveExpectation = self.expectation(description: "save")
|
||||||
stack.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
|
let hasChanges: Bool = try stack.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
object.testBoolean = NSNumber(value: true)
|
object.testBoolean = NSNumber(value: true)
|
||||||
@@ -438,15 +472,16 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testDecimal = NSDecimalNumber(string: "1")
|
object.testDecimal = NSDecimalNumber(string: "1")
|
||||||
object.testString = "nil:TestEntity1:1"
|
object.testString = "nil:TestEntity1:1"
|
||||||
|
|
||||||
switch transaction.commit() {
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
case .success(let hasChanges):
|
waitForAllObservers: false
|
||||||
|
)
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
saveExpectation.fulfill()
|
saveExpectation.fulfill()
|
||||||
|
|
||||||
case .failure:
|
|
||||||
XCTFail()
|
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
}
|
}
|
||||||
XCTAssertEqual(events, 0)
|
XCTAssertEqual(events, 0)
|
||||||
XCTAssertEqual(monitor.numberOfObjects(), 0)
|
XCTAssertEqual(monitor.numberOfObjects(), 0)
|
||||||
@@ -454,7 +489,6 @@ final class TransactionTests: BaseTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
dynamic func test_ThatAsynchronousTransactions_CanPerformCRUDs() {
|
dynamic func test_ThatAsynchronousTransactions_CanPerformCRUDs() {
|
||||||
@@ -465,66 +499,66 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let createExpectation = self.expectation(description: "create")
|
let createExpectation = self.expectation(description: "create")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
XCTAssertEqual(transaction.context, transaction.internalContext())
|
XCTAssertEqual(transaction.context, transaction.unsafeContext())
|
||||||
XCTAssertTrue(transaction.context.isTransactionContext)
|
XCTAssertTrue(transaction.context.isTransactionContext)
|
||||||
XCTAssertFalse(transaction.context.isDataStackContext)
|
XCTAssertFalse(transaction.context.isDataStackContext)
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
XCTAssertEqual(object.fetchSource()?.internalContext(), transaction.context)
|
XCTAssertEqual(object.fetchSource()?.unsafeContext(), transaction.context)
|
||||||
XCTAssertEqual(object.querySource()?.internalContext(), transaction.context)
|
XCTAssertEqual(object.querySource()?.unsafeContext(), transaction.context)
|
||||||
|
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
object.testString = "string1"
|
object.testString = "string1"
|
||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.fetchSource()?.internalContext(), stack.mainContext)
|
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
||||||
XCTAssertEqual(object?.querySource()?.internalContext(), stack.mainContext)
|
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
||||||
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
XCTAssertEqual(object?.testNumber, 100)
|
XCTAssertEqual(object?.testNumber, 100)
|
||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
createExpectation.fulfill()
|
createExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let updateExpectation = self.expectation(description: "update")
|
let updateExpectation = self.expectation(description: "update")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
object.testString = "string1_edit"
|
object.testString = "string1_edit"
|
||||||
object.testNumber = 200
|
object.testNumber = 200
|
||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
@@ -536,26 +570,26 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertEqual(object?.testNumber, 200)
|
XCTAssertEqual(object?.testNumber, 200)
|
||||||
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
||||||
updateExpectation.fulfill()
|
updateExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let deleteExpectation = self.expectation(description: "delete")
|
let deleteExpectation = self.expectation(description: "delete")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = transaction.fetchOne(From<TestEntity1>())
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
@@ -563,12 +597,12 @@ final class TransactionTests: BaseTestCase {
|
|||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNil(object)
|
XCTAssertNil(object)
|
||||||
deleteExpectation.fulfill()
|
deleteExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
@@ -583,7 +617,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let createExpectation = self.expectation(description: "create")
|
let createExpectation = self.expectation(description: "create")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>("Config1"))
|
let object = transaction.create(Into<TestEntity1>("Config1"))
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
@@ -591,11 +626,10 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
@@ -608,32 +642,32 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertEqual(object?.testNumber, 100)
|
XCTAssertEqual(object?.testNumber, 100)
|
||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
createExpectation.fulfill()
|
createExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let updateExpectation = self.expectation(description: "update")
|
let updateExpectation = self.expectation(description: "update")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
object.testString = "string1_edit"
|
object.testString = "string1_edit"
|
||||||
object.testNumber = 200
|
object.testNumber = 200
|
||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
@@ -646,38 +680,38 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertEqual(object?.testNumber, 200)
|
XCTAssertEqual(object?.testNumber, 200)
|
||||||
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
||||||
updateExpectation.fulfill()
|
updateExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let deleteExpectation = self.expectation(description: "delete")
|
let deleteExpectation = self.expectation(description: "delete")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
|
||||||
deleteExpectation.fulfill()
|
deleteExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
@@ -691,8 +725,8 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let createDiscardExpectation = self.expectation(description: "create-discard")
|
let createDiscardExpectation = self.expectation(description: "create-discard")
|
||||||
let loggerExpectations = self.prepareLoggerExpectations([.logWarning])
|
stack.perform(
|
||||||
stack.beginAsynchronous { (transaction) in
|
asynchronous: { (transaction) -> Void in
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
@@ -701,14 +735,24 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testDate = Date()
|
object.testDate = Date()
|
||||||
|
|
||||||
createDiscardExpectation.fulfill()
|
createDiscardExpectation.fulfill()
|
||||||
self.expectLogger(loggerExpectations)
|
try transaction.cancel()
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
},
|
||||||
|
failure: { (error) in
|
||||||
|
|
||||||
|
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
let testDate = Date()
|
let testDate = Date()
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let createExpectation = self.expectation(description: "create")
|
let createExpectation = self.expectation(description: "create")
|
||||||
stack.beginAsynchronous { (transaction) in
|
stack.perform(
|
||||||
|
asynchronous: { (transaction) -> Bool in
|
||||||
|
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
|
||||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>()))
|
XCTAssertNil(transaction.fetchOne(From<TestEntity1>()))
|
||||||
@@ -719,24 +763,24 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
transaction.commit { (result) in
|
return transaction.hasChanges
|
||||||
|
},
|
||||||
|
success: { (hasChanges) in
|
||||||
|
|
||||||
switch result {
|
XCTAssertTrue(hasChanges)
|
||||||
|
|
||||||
case .success(true):
|
|
||||||
createExpectation.fulfill()
|
createExpectation.fulfill()
|
||||||
|
},
|
||||||
|
failure: { _ in
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let updateDiscardExpectation = self.expectation(description: "update-discard")
|
let updateDiscardExpectation = self.expectation(description: "update-discard")
|
||||||
let loggerExpectations = self.prepareLoggerExpectations([.logWarning])
|
stack.perform(
|
||||||
stack.beginAsynchronous { (transaction) in
|
asynchronous: { (transaction) -> Void in
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
@@ -748,21 +792,31 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
updateDiscardExpectation.fulfill()
|
updateDiscardExpectation.fulfill()
|
||||||
self.expectLogger(loggerExpectations)
|
|
||||||
|
try transaction.cancel()
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
},
|
||||||
|
failure: { (error) in
|
||||||
|
|
||||||
|
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
|
||||||
let deleteDiscardExpectation = self.expectation(description: "delete-discard")
|
let deleteDiscardExpectation = self.expectation(description: "delete-discard")
|
||||||
let loggerExpectations = self.prepareLoggerExpectations([.logWarning])
|
stack.perform(
|
||||||
stack.beginAsynchronous { (transaction) in
|
asynchronous: { (transaction) -> Void in
|
||||||
|
|
||||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
|
||||||
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
return
|
try transaction.cancel()
|
||||||
}
|
}
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
|
||||||
@@ -772,8 +826,15 @@ final class TransactionTests: BaseTestCase {
|
|||||||
|
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
try transaction.cancel()
|
||||||
|
},
|
||||||
|
success: {
|
||||||
|
|
||||||
|
XCTFail()
|
||||||
|
},
|
||||||
|
failure: { (error) in
|
||||||
|
|
||||||
|
XCTAssertEqual(error, CoreStoreError.userCancelled)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = stack.fetchOne(From<TestEntity1>())
|
||||||
@@ -784,8 +845,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
deleteDiscardExpectation.fulfill()
|
deleteDiscardExpectation.fulfill()
|
||||||
}
|
}
|
||||||
self.expectLogger(loggerExpectations)
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.waitAndCheckExpectations()
|
self.waitAndCheckExpectations()
|
||||||
@@ -797,7 +857,7 @@ final class TransactionTests: BaseTestCase {
|
|||||||
self.prepareStack { (stack) in
|
self.prepareStack { (stack) in
|
||||||
|
|
||||||
let transaction = stack.beginUnsafe()
|
let transaction = stack.beginUnsafe()
|
||||||
XCTAssertEqual(transaction.context, transaction.internalContext())
|
XCTAssertEqual(transaction.context, transaction.unsafeContext())
|
||||||
XCTAssertTrue(transaction.context.isTransactionContext)
|
XCTAssertTrue(transaction.context.isTransactionContext)
|
||||||
XCTAssertFalse(transaction.context.isDataStackContext)
|
XCTAssertFalse(transaction.context.isDataStackContext)
|
||||||
|
|
||||||
@@ -805,31 +865,33 @@ final class TransactionTests: BaseTestCase {
|
|||||||
do {
|
do {
|
||||||
|
|
||||||
let object = transaction.create(Into<TestEntity1>())
|
let object = transaction.create(Into<TestEntity1>())
|
||||||
XCTAssertEqual(object.fetchSource()?.internalContext(), transaction.context)
|
XCTAssertEqual(object.fetchSource()?.unsafeContext(), transaction.context)
|
||||||
XCTAssertEqual(object.querySource()?.internalContext(), transaction.context)
|
XCTAssertEqual(object.querySource()?.unsafeContext(), transaction.context)
|
||||||
|
|
||||||
object.testEntityID = NSNumber(value: 1)
|
object.testEntityID = NSNumber(value: 1)
|
||||||
object.testString = "string1"
|
object.testString = "string1"
|
||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
do {
|
||||||
|
|
||||||
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = stack.fetchOne(From<TestEntity1>())
|
||||||
XCTAssertNotNil(object)
|
XCTAssertNotNil(object)
|
||||||
XCTAssertEqual(object?.fetchSource()?.internalContext(), stack.mainContext)
|
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
|
||||||
XCTAssertEqual(object?.querySource()?.internalContext(), stack.mainContext)
|
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
|
||||||
|
|
||||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
|
||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
XCTAssertEqual(object?.testNumber, 100)
|
XCTAssertEqual(object?.testNumber, 100)
|
||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -844,10 +906,11 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testNumber = 200
|
object.testNumber = 200
|
||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
do {
|
||||||
|
|
||||||
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
|
||||||
|
|
||||||
let object = stack.fetchOne(From<TestEntity1>())
|
let object = stack.fetchOne(From<TestEntity1>())
|
||||||
@@ -856,8 +919,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
XCTAssertEqual(object?.testNumber, 200)
|
XCTAssertEqual(object?.testNumber, 200)
|
||||||
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -866,15 +930,16 @@ final class TransactionTests: BaseTestCase {
|
|||||||
let object = transaction.fetchOne(From<TestEntity1>())
|
let object = transaction.fetchOne(From<TestEntity1>())
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
do {
|
||||||
|
|
||||||
case .success(let hasChanges):
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
XCTAssertTrue(hasChanges)
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
|
||||||
XCTAssertNil(stack.fetchOne(From<TestEntity1>()))
|
XCTAssertNil(stack.fetchOne(From<TestEntity1>()))
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -897,10 +962,11 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
do {
|
||||||
|
|
||||||
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
|
||||||
@@ -910,8 +976,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertEqual(object?.testString, "string1")
|
XCTAssertEqual(object?.testString, "string1")
|
||||||
XCTAssertEqual(object?.testNumber, 100)
|
XCTAssertEqual(object?.testNumber, 100)
|
||||||
XCTAssertEqual(object?.testDate, testDate)
|
XCTAssertEqual(object?.testDate, testDate)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -926,10 +993,11 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testNumber = 200
|
object.testNumber = 200
|
||||||
object.testDate = Date.distantFuture
|
object.testDate = Date.distantFuture
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
do {
|
||||||
|
|
||||||
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
case .success(let hasChanges):
|
|
||||||
XCTAssertTrue(hasChanges)
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
|
||||||
@@ -939,8 +1007,9 @@ final class TransactionTests: BaseTestCase {
|
|||||||
XCTAssertEqual(object?.testString, "string1_edit")
|
XCTAssertEqual(object?.testString, "string1_edit")
|
||||||
XCTAssertEqual(object?.testNumber, 200)
|
XCTAssertEqual(object?.testNumber, 200)
|
||||||
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
XCTAssertEqual(object?.testDate, Date.distantFuture)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -949,15 +1018,16 @@ final class TransactionTests: BaseTestCase {
|
|||||||
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
|
||||||
transaction.delete(object)
|
transaction.delete(object)
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
do {
|
||||||
|
|
||||||
case .success(let hasChanges):
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
XCTAssertTrue(hasChanges)
|
try transaction.commitAndWait()
|
||||||
|
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
|
||||||
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -996,12 +1066,13 @@ final class TransactionTests: BaseTestCase {
|
|||||||
object.testNumber = 100
|
object.testNumber = 100
|
||||||
object.testDate = testDate
|
object.testDate = testDate
|
||||||
|
|
||||||
switch transaction.commitAndWait() {
|
do {
|
||||||
|
|
||||||
case .success(true):
|
XCTAssertTrue(transaction.hasChanges)
|
||||||
break
|
try transaction.commitAndWait()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
|
||||||
default:
|
|
||||||
XCTFail()
|
XCTFail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,72 +30,77 @@ import CoreData
|
|||||||
// MARK: - AsynchronousDataTransaction
|
// MARK: - AsynchronousDataTransaction
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The `AsynchronousDataTransaction` provides an interface for `NSManagedObject` creates, updates, and deletes. A transaction object should typically be only used from within a transaction block initiated from `DataStack.beginAsynchronous(_:)`, or from `CoreStore.beginAsynchronous(_:)`.
|
The `AsynchronousDataTransaction` provides an interface for `DynamicObject` creates, updates, and deletes. A transaction object should typically be only used from within a transaction block initiated from `DataStack.perform(asynchronous:...)`, or from `CoreStore.perform(synchronous:...)`.
|
||||||
*/
|
*/
|
||||||
public final class AsynchronousDataTransaction: BaseDataTransaction {
|
public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Saves the transaction changes. This method should not be used after the `commit()` method was already called once.
|
Cancels a transaction by throwing `CoreStoreError.userCancelled`.
|
||||||
|
```
|
||||||
- parameter completion: the block executed after the save completes. Success or failure is reported by the `SaveResult` argument of the block.
|
try transaction.cancel()
|
||||||
|
```
|
||||||
|
- Important: Never use `try?` or `try!` on a `cancel()` call. Always use `try`. Using `try?` will swallow the cancellation and the transaction will proceed to commit as normal. Using `try!` will crash the app as `cancel()` will *always* throw an error.
|
||||||
*/
|
*/
|
||||||
public func commit(_ completion: @escaping (_ result: SaveResult) -> Void = { _ in }) {
|
public func cancel() throws -> Never {
|
||||||
|
|
||||||
CoreStore.assert(
|
throw CoreStoreError.userCancelled
|
||||||
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.isCommitted = true
|
|
||||||
let group = DispatchGroup()
|
|
||||||
group.enter()
|
|
||||||
self.context.saveAsynchronouslyWithCompletion { (result) -> Void in
|
|
||||||
|
|
||||||
self.result = result
|
|
||||||
completion(result)
|
|
||||||
group.leave()
|
|
||||||
}
|
|
||||||
group.wait()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - Result
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begins a child transaction synchronously where NSManagedObject creates, updates, and deletes can be made. This method should not be used after the `commit()` method was already called once.
|
The `Result` contains the success or failure information for a completed transaction
|
||||||
|
|
||||||
- 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 `SaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
public enum Result<T> {
|
||||||
public func beginSynchronous(_ closure: @escaping (_ transaction: SynchronousDataTransaction) -> Void) -> SaveResult? {
|
|
||||||
|
|
||||||
CoreStore.assert(
|
/**
|
||||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
`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.
|
||||||
"Attempted to begin a child transaction from a \(cs_typeName(self)) outside its designated queue."
|
*/
|
||||||
)
|
case success(userInfo: T)
|
||||||
CoreStore.assert(
|
|
||||||
!self.isCommitted,
|
|
||||||
"Attempted to begin a child transaction from an already committed \(cs_typeName(self))."
|
|
||||||
)
|
|
||||||
|
|
||||||
return SynchronousDataTransaction(
|
/**
|
||||||
mainContext: self.context,
|
`Result<T>.failure` indicates that the transaction either failed or was cancelled. The associated object for this value is a `CoreStoreError` enum value.
|
||||||
queue: self.childTransactionQueue,
|
*/
|
||||||
closure: closure).performAndWait()
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
// MARK: BaseDataTransaction
|
// MARK: BaseDataTransaction
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a new `NSManagedObject` with the specified entity type.
|
Creates a new `NSManagedObject` or `CoreStoreObject` with the specified entity type.
|
||||||
|
|
||||||
- parameter into: the `Into` clause indicating the destination `NSManagedObject` entity type and the destination configuration
|
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
|
||||||
- returns: a new `NSManagedObject` instance of the specified entity type.
|
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
|
||||||
*/
|
*/
|
||||||
public override func create<T: NSManagedObject>(_ into: Into<T>) -> T {
|
public override func create<T: DynamicObject>(_ into: Into<T>) -> T {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
@@ -106,12 +111,12 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns an editable proxy of a specified `NSManagedObject`. This method should not be used after the `commit()` method was already called once.
|
Returns an editable proxy of a specified `NSManagedObject` or `CoreStoreObject`.
|
||||||
|
|
||||||
- parameter object: the `NSManagedObject` type to be edited
|
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be edited
|
||||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
|
||||||
*/
|
*/
|
||||||
public override func edit<T: NSManagedObject>(_ object: T?) -> T? {
|
public override func edit<T: DynamicObject>(_ object: T?) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
@@ -122,13 +127,13 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns an editable proxy of the object with the specified `NSManagedObjectID`. This method should not be used after the `commit()` method was already called once.
|
Returns an editable proxy of the object with the specified `NSManagedObjectID`.
|
||||||
|
|
||||||
- parameter into: an `Into` clause specifying the entity type
|
- parameter into: an `Into` clause specifying the entity type
|
||||||
- parameter objectID: the `NSManagedObjectID` for the object to be edited
|
- parameter objectID: the `NSManagedObjectID` for the object to be edited
|
||||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
|
||||||
*/
|
*/
|
||||||
public override func edit<T: NSManagedObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
public override func edit<T: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
@@ -139,11 +144,11 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Deletes a specified `NSManagedObject`. This method should not be used after the `commit()` method was already called once.
|
Deletes a specified `NSManagedObject` or `CoreStoreObject`.
|
||||||
|
|
||||||
- parameter object: the `NSManagedObject` type to be deleted
|
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be deleted
|
||||||
*/
|
*/
|
||||||
public override func delete(_ object: NSManagedObject?) {
|
public override func delete<T: DynamicObject>(_ object: T?) {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
@@ -154,13 +159,13 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Deletes the specified `NSManagedObject`s.
|
Deletes the specified `DynamicObject`s.
|
||||||
|
|
||||||
- parameter object1: the `NSManagedObject` type to be deleted
|
- parameter object1: the `DynamicObject` to be deleted
|
||||||
- parameter object2: another `NSManagedObject` type to be deleted
|
- parameter object2: another `DynamicObject` to be deleted
|
||||||
- parameter objects: other `NSManagedObject`s type to be deleted
|
- parameter objects: other `DynamicObject`s to be deleted
|
||||||
*/
|
*/
|
||||||
public override func delete(_ object1: NSManagedObject?, _ object2: NSManagedObject?, _ objects: NSManagedObject?...) {
|
public override func delete<T: DynamicObject>(_ object1: T?, _ object2: T?, _ objects: T?...) {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
@@ -171,11 +176,11 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Deletes the specified `NSManagedObject`s.
|
Deletes the specified `DynamicObject`s.
|
||||||
|
|
||||||
- parameter objects: the `NSManagedObject`s type to be deleted
|
- parameter objects: the `DynamicObject`s to be deleted
|
||||||
*/
|
*/
|
||||||
public override func delete<S: Sequence>(_ objects: S) where S.Iterator.Element: NSManagedObject {
|
public override func delete<S: Sequence>(_ objects: S) where S.Iterator.Element: DynamicObject {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
@@ -188,47 +193,82 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
|||||||
|
|
||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
internal init(mainContext: NSManagedObjectContext, queue: DispatchQueue, closure: @escaping (_ transaction: AsynchronousDataTransaction) -> Void) {
|
internal init(mainContext: NSManagedObjectContext, queue: DispatchQueue) {
|
||||||
|
|
||||||
self.closure = closure
|
|
||||||
|
|
||||||
super.init(mainContext: mainContext, queue: queue, supportsUndo: false, bypassesQueueing: false)
|
super.init(mainContext: mainContext, queue: queue, supportsUndo: false, bypassesQueueing: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func perform() {
|
internal func autoCommit(_ completion: @escaping (_ hasChanges: Bool, _ error: CoreStoreError?) -> Void) {
|
||||||
|
|
||||||
self.transactionQueue.async {
|
self.isCommitted = true
|
||||||
|
let group = DispatchGroup()
|
||||||
|
group.enter()
|
||||||
|
self.context.saveAsynchronouslyWithCompletion { (result) -> Void in
|
||||||
|
|
||||||
self.closure(self)
|
completion(result.0, result.1)
|
||||||
if !self.isCommitted && self.hasChanges {
|
self.result = result
|
||||||
|
group.leave()
|
||||||
|
}
|
||||||
|
group.wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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 { (result) in
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
|
||||||
|
case (let hasChanges, nil): completion(SaveResult(hasChanges: hasChanges))
|
||||||
|
case (_, let error?): completion(SaveResult(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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(
|
CoreStore.log(
|
||||||
.warning,
|
.warning,
|
||||||
message: "The closure for the \(cs_typeName(self)) completed without being committed. All changes made within the transaction were discarded."
|
message: "The closure for the \(cs_typeName(childTransaction)) completed without being committed. All changes made within the transaction were discarded."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
switch childTransaction.result {
|
||||||
|
|
||||||
internal func performAndWait() -> SaveResult? {
|
case nil: return nil
|
||||||
|
case (let hasChanges, nil)?: return SaveResult(hasChanges: hasChanges)
|
||||||
self.transactionQueue.sync {
|
case (_, let error?)?: return SaveResult(error)
|
||||||
|
|
||||||
self.closure(self)
|
|
||||||
|
|
||||||
if !self.isCommitted && self.hasChanges {
|
|
||||||
|
|
||||||
CoreStore.log(
|
|
||||||
.warning,
|
|
||||||
message: "The closure for the \(cs_typeName(self)) completed without being committed. All changes made within the transaction were discarded."
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self.result
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
|
||||||
|
|
||||||
private let closure: (_ transaction: AsynchronousDataTransaction) -> Void
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ public extension BaseDataTransaction {
|
|||||||
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
||||||
- returns: the created `ImportableObject` instance, or `nil` if the import was ignored
|
- returns: the created `ImportableObject` instance, or `nil` if the import was ignored
|
||||||
*/
|
*/
|
||||||
public func importObject<T>(
|
public func importObject<T: DynamicObject & ImportableObject>(
|
||||||
_ into: Into<T>,
|
_ into: Into<T>,
|
||||||
source: T.ImportSource) throws -> T? where T: NSManagedObject, T: ImportableObject {
|
source: T.ImportSource) throws -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -50,8 +50,7 @@ public extension BaseDataTransaction {
|
|||||||
|
|
||||||
return try autoreleasepool {
|
return try autoreleasepool {
|
||||||
|
|
||||||
let entityType = into.entityClass as! T.Type
|
let entityType = into.entityClass
|
||||||
|
|
||||||
guard entityType.shouldInsert(from: source, in: self) else {
|
guard entityType.shouldInsert(from: source, in: self) else {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -70,9 +69,9 @@ public extension BaseDataTransaction {
|
|||||||
- parameter source: the object to import values from
|
- parameter source: the object to import values from
|
||||||
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
||||||
*/
|
*/
|
||||||
public func importObject<T>(
|
public func importObject<T: DynamicObject & ImportableObject>(
|
||||||
_ object: T,
|
_ object: T,
|
||||||
source: T.ImportSource) throws where T: NSManagedObject, T: ImportableObject {
|
source: T.ImportSource) throws {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -98,9 +97,9 @@ public extension BaseDataTransaction {
|
|||||||
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
||||||
- returns: the array of created `ImportableObject` instances
|
- returns: the array of created `ImportableObject` instances
|
||||||
*/
|
*/
|
||||||
public func importObjects<T, S: Sequence>(
|
public func importObjects<T: DynamicObject & ImportableObject, S: Sequence>(
|
||||||
_ into: Into<T>,
|
_ into: Into<T>,
|
||||||
sourceArray: S) throws -> [T] where T: NSManagedObject, T: ImportableObject, S.Iterator.Element == T.ImportSource {
|
sourceArray: S) throws -> [T] where S.Iterator.Element == T.ImportSource {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -111,7 +110,7 @@ public extension BaseDataTransaction {
|
|||||||
|
|
||||||
return try sourceArray.flatMap { (source) -> T? in
|
return try sourceArray.flatMap { (source) -> T? in
|
||||||
|
|
||||||
let entityType = into.entityClass as! T.Type
|
let entityType = into.entityClass
|
||||||
guard entityType.shouldInsert(from: source, in: self) else {
|
guard entityType.shouldInsert(from: source, in: self) else {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -134,9 +133,9 @@ public extension BaseDataTransaction {
|
|||||||
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
|
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
|
||||||
- returns: the created/updated `ImportableUniqueObject` instance, or `nil` if the import was ignored
|
- returns: the created/updated `ImportableUniqueObject` instance, or `nil` if the import was ignored
|
||||||
*/
|
*/
|
||||||
public func importUniqueObject<T>(
|
public func importUniqueObject<T: DynamicObject & ImportableUniqueObject>(
|
||||||
_ into: Into<T>,
|
_ into: Into<T>,
|
||||||
source: T.ImportSource) throws -> T? where T: NSManagedObject, T: ImportableUniqueObject {
|
source: T.ImportSource) throws -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -145,7 +144,7 @@ public extension BaseDataTransaction {
|
|||||||
|
|
||||||
return try autoreleasepool {
|
return try autoreleasepool {
|
||||||
|
|
||||||
let entityType = into.entityClass as! T.Type
|
let entityType = into.entityClass
|
||||||
let uniqueIDKeyPath = entityType.uniqueIDKeyPath
|
let uniqueIDKeyPath = entityType.uniqueIDKeyPath
|
||||||
guard let uniqueIDValue = try entityType.uniqueID(from: source, in: self) else {
|
guard let uniqueIDValue = try entityType.uniqueID(from: source, in: self) else {
|
||||||
|
|
||||||
@@ -178,7 +177,7 @@ public extension BaseDataTransaction {
|
|||||||
/**
|
/**
|
||||||
Updates existing `ImportableUniqueObject`s or creates them by importing from the specified array of import sources.
|
Updates existing `ImportableUniqueObject`s or creates them by importing from the specified array of import sources.
|
||||||
`ImportableUniqueObject` methods are called on the objects in the same order as they are in the `sourceArray`, and are returned in an array with that same order.
|
`ImportableUniqueObject` methods are called on the objects in the same order as they are in the `sourceArray`, and are returned in an array with that same order.
|
||||||
- Warning: If `sourceArray` contains multiple import sources with same ID, no merging will occur and ONLY THE LAST duplicate will be imported.
|
- Warning: If `sourceArray` contains multiple import sources with same ID, only the last `ImportSource` of the duplicates will be imported.
|
||||||
|
|
||||||
- parameter into: an `Into` clause specifying the entity type
|
- parameter into: an `Into` clause specifying the entity type
|
||||||
- parameter sourceArray: the array of objects to import values from
|
- parameter sourceArray: the array of objects to import values from
|
||||||
@@ -186,10 +185,10 @@ public extension BaseDataTransaction {
|
|||||||
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
|
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
|
||||||
- returns: the array of created/updated `ImportableUniqueObject` instances
|
- returns: the array of created/updated `ImportableUniqueObject` instances
|
||||||
*/
|
*/
|
||||||
public func importUniqueObjects<T, S: Sequence>(
|
public func importUniqueObjects<T: DynamicObject & ImportableUniqueObject, S: Sequence>(
|
||||||
_ into: Into<T>,
|
_ into: Into<T>,
|
||||||
sourceArray: S,
|
sourceArray: S,
|
||||||
preProcess: @escaping (_ mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws -> [T] where T: NSManagedObject, T: ImportableUniqueObject, S.Iterator.Element == T.ImportSource {
|
preProcess: @escaping (_ mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws -> [T] where S.Iterator.Element == T.ImportSource {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -198,7 +197,7 @@ public extension BaseDataTransaction {
|
|||||||
|
|
||||||
return try autoreleasepool {
|
return try autoreleasepool {
|
||||||
|
|
||||||
let entityType = into.entityClass as! T.Type
|
let entityType = into.entityClass
|
||||||
var importSourceByID = Dictionary<T.UniqueIDType, T.ImportSource>()
|
var importSourceByID = Dictionary<T.UniqueIDType, T.ImportSource>()
|
||||||
let sortedIDs = try autoreleasepool {
|
let sortedIDs = try autoreleasepool {
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ import CoreData
|
|||||||
extension BaseDataTransaction: FetchableSource, QueryableSource {
|
extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Deletes all `NSManagedObject`s that satisfy the specified `DeleteClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Deletes all `DynamicObject`s that satisfy the specified `DeleteClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter deleteClauses: a series of `DeleteClause` instances for the delete request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter deleteClauses: a series of `DeleteClause` instances for the delete request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number of `NSManagedObject`s deleted
|
- returns: the number of `DynamicObject`s deleted
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func deleteAll<T: NSManagedObject>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
|
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -50,14 +50,14 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Deletes all `NSManagedObject`s that satisfy the specified `DeleteClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Deletes all `DynamicObject`s that satisfy the specified `DeleteClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter deleteClauses: a series of `DeleteClause` instances for the delete request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter deleteClauses: a series of `DeleteClause` instances for the delete request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number of `NSManagedObject`s deleted
|
- returns: the number of `DynamicObject`s deleted
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func deleteAll<T: NSManagedObject>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
|
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -71,57 +71,57 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
// MARK: FetchableSource
|
// MARK: FetchableSource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
|
Fetches the `DynamicObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
|
||||||
|
|
||||||
- parameter object: a reference to the object created/fetched outside the transaction
|
- parameter object: a reference to the object created/fetched outside the transaction
|
||||||
- returns: the `NSManagedObject` instance if the object exists in the transaction, or `nil` if not found.
|
- returns: the `DynamicObject` instance if the object exists in the transaction, or `nil` if not found.
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject>(_ object: T) -> T? {
|
public func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
|
||||||
|
|
||||||
return self.context.fetchExisting(object)
|
return self.context.fetchExisting(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instance in the transaction's context from an `NSManagedObjectID`.
|
Fetches the `DynamicObject` instance in the transaction's context from an `NSManagedObjectID`.
|
||||||
|
|
||||||
- parameter objectID: the `NSManagedObjectID` for the object
|
- parameter objectID: the `NSManagedObjectID` for the object
|
||||||
- returns: the `NSManagedObject` instance if the object exists in the transaction, or `nil` if not found.
|
- returns: the `DynamicObject` instance if the object exists in the transaction, or `nil` if not found.
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject>(_ objectID: NSManagedObjectID) -> T? {
|
public func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||||
|
|
||||||
return self.context.fetchExisting(objectID)
|
return self.context.fetchExisting(objectID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instances in the transaction's context from references created from a transaction or from a different managed object context.
|
Fetches the `DynamicObject` instances in the transaction's context from references created from a transaction or from a different managed object context.
|
||||||
|
|
||||||
- parameter objects: an array of `NSManagedObject`s created/fetched outside the transaction
|
- parameter objects: an array of `DynamicObject`s created/fetched outside the transaction
|
||||||
- returns: the `NSManagedObject` array for objects that exists in the transaction
|
- returns: the `DynamicObject` array for objects that exists in the transaction
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||||
|
|
||||||
return self.context.fetchExisting(objects)
|
return self.context.fetchExisting(objects)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instances in the transaction's context from a list of `NSManagedObjectID`.
|
Fetches the `DynamicObject` instances in the transaction's context from a list of `NSManagedObjectID`.
|
||||||
|
|
||||||
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
||||||
- returns: the `NSManagedObject` array for objects that exists in the transaction
|
- returns: the `DynamicObject` array for objects that exists in the transaction
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||||
|
|
||||||
return self.context.fetchExisting(objectIDs)
|
return self.context.fetchExisting(objectIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the first `DynamicObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s
|
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -131,13 +131,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the first `DynamicObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s
|
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -147,13 +147,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s
|
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -163,13 +163,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s
|
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -179,13 +179,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -195,13 +195,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -211,13 +211,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -227,13 +227,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -243,13 +243,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -259,13 +259,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -287,7 +287,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -306,7 +306,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -325,7 +325,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -344,7 +344,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -359,8 +359,17 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
|||||||
/**
|
/**
|
||||||
The internal `NSManagedObjectContext` managed by this instance. Using this context directly should typically be avoided, and is provided by CoreStore only for extremely specialized cases.
|
The internal `NSManagedObjectContext` managed by this instance. Using this context directly should typically be avoided, and is provided by CoreStore only for extremely specialized cases.
|
||||||
*/
|
*/
|
||||||
public func internalContext() -> NSManagedObjectContext {
|
public func unsafeContext() -> NSManagedObjectContext {
|
||||||
|
|
||||||
return self.context
|
return self.context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Obsoleted
|
||||||
|
|
||||||
|
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
|
||||||
|
public func internalContext() -> NSManagedObjectContext {
|
||||||
|
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,32 +45,36 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a new `NSManagedObject` with the specified entity type.
|
Creates a new `NSManagedObject` or `CoreStoreObject` with the specified entity type.
|
||||||
|
|
||||||
- parameter into: the `Into` clause indicating the destination `NSManagedObject` entity type and the destination configuration
|
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
|
||||||
- returns: a new `NSManagedObject` instance of the specified entity type.
|
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
|
||||||
*/
|
*/
|
||||||
public func create<T: NSManagedObject>(_ into: Into<T>) -> T {
|
public func create<T: DynamicObject>(_ into: Into<T>) -> T {
|
||||||
|
|
||||||
let entityClass = (into.entityClass as! T.Type)
|
let entityClass = into.entityClass
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
"Attempted to create an entity of type \(cs_typeName(entityClass)) outside its designated queue."
|
"Attempted to create an entity of type \(cs_typeName(entityClass)) outside its designated queue."
|
||||||
)
|
)
|
||||||
|
|
||||||
let context = self.context
|
let context = self.context
|
||||||
|
let dataStack = context.parentStack!
|
||||||
|
let entityIdentifier = EntityIdentifier(entityClass)
|
||||||
if into.inferStoreIfPossible {
|
if into.inferStoreIfPossible {
|
||||||
|
|
||||||
switch context.parentStack!.persistentStoreForEntityClass(
|
switch dataStack.persistentStore(
|
||||||
entityClass,
|
for: entityIdentifier,
|
||||||
configuration: nil,
|
configuration: nil,
|
||||||
inferStoreIfPossible: true
|
inferStoreIfPossible: true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
case (let persistentStore?, _):
|
case (let persistentStore?, _):
|
||||||
let object = entityClass.createInContext(context)
|
return entityClass.cs_forceCreate(
|
||||||
context.assign(object, to: persistentStore)
|
entityDescription: dataStack.entityDescription(for: entityIdentifier)!,
|
||||||
return object
|
into: context,
|
||||||
|
assignTo: persistentStore
|
||||||
|
)
|
||||||
|
|
||||||
case (nil, true):
|
case (nil, true):
|
||||||
CoreStore.abort("Attempted to create an entity of type \(cs_typeName(entityClass)) with ambiguous destination persistent store, but the configuration name was not specified.")
|
CoreStore.abort("Attempted to create an entity of type \(cs_typeName(entityClass)) with ambiguous destination persistent store, but the configuration name was not specified.")
|
||||||
@@ -81,17 +85,19 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
switch context.parentStack!.persistentStoreForEntityClass(
|
switch dataStack.persistentStore(
|
||||||
entityClass,
|
for: entityIdentifier,
|
||||||
configuration: into.configuration
|
configuration: into.configuration
|
||||||
?? type(of: into).defaultConfigurationName,
|
?? DataStack.defaultConfigurationName,
|
||||||
inferStoreIfPossible: false
|
inferStoreIfPossible: false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
case (let persistentStore?, _):
|
case (let persistentStore?, _):
|
||||||
let object = entityClass.createInContext(context)
|
return entityClass.cs_forceCreate(
|
||||||
context.assign(object, to: persistentStore)
|
entityDescription: dataStack.entityDescription(for: entityIdentifier)!,
|
||||||
return object
|
into: context,
|
||||||
|
assignTo: persistentStore
|
||||||
|
)
|
||||||
|
|
||||||
case (nil, true):
|
case (nil, true):
|
||||||
CoreStore.abort("Attempted to create an entity of type \(cs_typeName(entityClass)) with ambiguous destination persistent store, but the configuration name was not specified.")
|
CoreStore.abort("Attempted to create an entity of type \(cs_typeName(entityClass)) with ambiguous destination persistent store, but the configuration name was not specified.")
|
||||||
@@ -115,7 +121,7 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
- parameter object: the `NSManagedObject` type to be edited
|
- parameter object: the `NSManagedObject` type to be edited
|
||||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
- returns: an editable proxy for the specified `NSManagedObject`.
|
||||||
*/
|
*/
|
||||||
public func edit<T: NSManagedObject>(_ object: T?) -> T? {
|
public func edit<T: DynamicObject>(_ object: T?) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -135,7 +141,7 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
- parameter objectID: the `NSManagedObjectID` for the object to be edited
|
- parameter objectID: the `NSManagedObjectID` for the object to be edited
|
||||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
- returns: an editable proxy for the specified `NSManagedObject`.
|
||||||
*/
|
*/
|
||||||
public func edit<T: NSManagedObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
public func edit<T: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
@@ -143,10 +149,10 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
)
|
)
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
into.inferStoreIfPossible
|
into.inferStoreIfPossible
|
||||||
|| (into.configuration ?? Into.defaultConfigurationName) == objectID.persistentStore?.configurationName,
|
|| (into.configuration ?? DataStack.defaultConfigurationName) == objectID.persistentStore?.configurationName,
|
||||||
"Attempted to update an entity of type \(cs_typeName(into.entityClass)) but the specified persistent store do not match the `NSManagedObjectID`."
|
"Attempted to update an entity of type \(cs_typeName(into.entityClass)) but the specified persistent store do not match the `NSManagedObjectID`."
|
||||||
)
|
)
|
||||||
return self.fetchExisting(objectID) as? T
|
return self.fetchExisting(objectID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,17 +160,16 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
|
|
||||||
- parameter object: the `NSManagedObject` to be deleted
|
- parameter object: the `NSManagedObject` to be deleted
|
||||||
*/
|
*/
|
||||||
public func delete(_ object: NSManagedObject?) {
|
public func delete<T: DynamicObject>(_ object: T?) {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
"Attempted to delete an entity outside its designated queue."
|
"Attempted to delete an entity outside its designated queue."
|
||||||
)
|
)
|
||||||
guard let object = object else {
|
let context = self.context
|
||||||
|
object
|
||||||
return
|
.flatMap(context.fetchExisting)
|
||||||
}
|
.flatMap({ context.delete($0.cs_toRaw()) })
|
||||||
self.context.fetchExisting(object)?.deleteFromContext()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,7 +179,7 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
- parameter object2: another `NSManagedObject` to be deleted
|
- parameter object2: another `NSManagedObject` to be deleted
|
||||||
- parameter objects: other `NSManagedObject`s to be deleted
|
- parameter objects: other `NSManagedObject`s to be deleted
|
||||||
*/
|
*/
|
||||||
public func delete(_ object1: NSManagedObject?, _ object2: NSManagedObject?, _ objects: NSManagedObject?...) {
|
public func delete<T: DynamicObject>(_ object1: T?, _ object2: T?, _ objects: T?...) {
|
||||||
|
|
||||||
self.delete(([object1, object2] + objects).flatMap { $0 })
|
self.delete(([object1, object2] + objects).flatMap { $0 })
|
||||||
}
|
}
|
||||||
@@ -184,15 +189,14 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
|
|
||||||
- parameter objects: the `NSManagedObject`s to be deleted
|
- parameter objects: the `NSManagedObject`s to be deleted
|
||||||
*/
|
*/
|
||||||
public func delete<S: Sequence>(_ objects: S) where S.Iterator.Element: NSManagedObject {
|
public func delete<S: Sequence>(_ objects: S) where S.Iterator.Element: DynamicObject {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
"Attempted to delete entities outside their designated queue."
|
"Attempted to delete entities outside their designated queue."
|
||||||
)
|
)
|
||||||
|
|
||||||
let context = self.context
|
let context = self.context
|
||||||
objects.forEach { context.fetchExisting($0)?.deleteFromContext() }
|
objects.forEach { context.fetchExisting($0).flatMap({ context.delete($0.cs_toRaw()) }) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,7 +208,6 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
self.isRunningInAllowedQueue(),
|
self.isRunningInAllowedQueue(),
|
||||||
"Attempted to refresh entities outside their designated queue."
|
"Attempted to refresh entities outside their designated queue."
|
||||||
)
|
)
|
||||||
|
|
||||||
self.context.refreshAndMergeAllObjects()
|
self.context.refreshAndMergeAllObjects()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,11 +215,12 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
// MARK: Inspecting Pending Objects
|
// MARK: Inspecting Pending Objects
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObject`s that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
Returns all pending `DynamicObject`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
||||||
|
|
||||||
- returns: a `Set` of pending `NSManagedObject`s that were inserted to the transaction.
|
- parameter entity: the `DynamicObject` subclass to filter
|
||||||
|
- returns: a `Set` of pending `DynamicObject`s of the specified type that were inserted to the transaction.
|
||||||
*/
|
*/
|
||||||
public func insertedObjects() -> Set<NSManagedObject> {
|
public func insertedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||||
@@ -226,28 +230,7 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
|
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||||
return self.context.insertedObjects
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns all pending `NSManagedObject`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
|
||||||
- returns: a `Set` of pending `NSManagedObject`s of the specified type that were inserted to the transaction.
|
|
||||||
*/
|
|
||||||
public func insertedObjects<T: NSManagedObject>(_ entity: T.Type) -> Set<T> {
|
|
||||||
|
|
||||||
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 Set(self.context.insertedObjects.flatMap { $0 as? T })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -265,17 +248,16 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))."
|
"Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
|
||||||
return Set(self.context.insertedObjects.map { $0.objectID })
|
return Set(self.context.insertedObjects.map { $0.objectID })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObjectID`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
Returns all pending `NSManagedObjectID`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
- parameter entity: the `DynamicObject` subclass to filter
|
||||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were inserted to the transaction.
|
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were inserted to the transaction.
|
||||||
*/
|
*/
|
||||||
public func insertedObjectIDs<T: NSManagedObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
public func insertedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||||
@@ -285,16 +267,16 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))."
|
"Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||||
return Set(self.context.insertedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObject`s that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
Returns all pending `DynamicObject`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
||||||
|
|
||||||
- returns: a `Set` of pending `NSManagedObject`s that were updated to the transaction.
|
- parameter entity: the `DynamicObject` subclass to filter
|
||||||
|
- returns: a `Set` of pending `DynamicObject`s of the specified type that were updated in the transaction.
|
||||||
*/
|
*/
|
||||||
public func updatedObjects() -> Set<NSManagedObject> {
|
public func updatedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||||
@@ -304,28 +286,7 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access updated objects from an already committed \(cs_typeName(self))."
|
"Attempted to access updated objects from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||||
return self.context.updatedObjects
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns all pending `NSManagedObject`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
|
||||||
- returns: a `Set` of pending `NSManagedObject`s of the specified type that were updated in the transaction.
|
|
||||||
*/
|
|
||||||
public func updatedObjects<T: NSManagedObject>(_ entity: T.Type) -> Set<T> {
|
|
||||||
|
|
||||||
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 Set(self.context.updatedObjects.filter { $0.isKind(of: entity) }.map { $0 as! T })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -343,17 +304,16 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access updated object IDs from an already committed \(cs_typeName(self))."
|
"Attempted to access updated object IDs from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
|
||||||
return Set(self.context.updatedObjects.map { $0.objectID })
|
return Set(self.context.updatedObjects.map { $0.objectID })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObjectID`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
Returns all pending `NSManagedObjectID`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
- parameter entity: the `DynamicObject` subclass to filter
|
||||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were updated in the transaction.
|
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were updated in the transaction.
|
||||||
*/
|
*/
|
||||||
public func updatedObjectIDs<T: NSManagedObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
public func updatedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||||
@@ -363,16 +323,16 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access updated object IDs from an already committed \(cs_typeName(self))."
|
"Attempted to access updated object IDs from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||||
return Set(self.context.updatedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObject`s that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
Returns all pending `DynamicObject`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
||||||
|
|
||||||
- returns: a `Set` of pending `NSManagedObject`s that were deleted from the transaction.
|
- parameter entity: the `DynamicObject` subclass to filter
|
||||||
|
- returns: a `Set` of pending `DynamicObject`s of the specified type that were deleted from the transaction.
|
||||||
*/
|
*/
|
||||||
public func deletedObjects() -> Set<NSManagedObject> {
|
public func deletedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||||
@@ -382,34 +342,13 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access deleted objects from an already committed \(cs_typeName(self))."
|
"Attempted to access deleted objects from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||||
return self.context.deletedObjects
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns all pending `NSManagedObject`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
|
||||||
- returns: a `Set` of pending `NSManagedObject`s of the specified type that were deleted from the transaction.
|
|
||||||
*/
|
|
||||||
public func deletedObjects<T: NSManagedObject>(_ entity: T.Type) -> Set<T> {
|
|
||||||
|
|
||||||
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 Set(self.context.deletedObjects.filter { $0.isKind(of: entity) }.map { $0 as! T })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
- parameter entity: the `DynamicObject` subclass to filter
|
||||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
||||||
*/
|
*/
|
||||||
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
|
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
|
||||||
@@ -422,17 +361,16 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access deleted object IDs from an already committed \(cs_typeName(self))."
|
"Attempted to access deleted object IDs from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
|
||||||
return Set(self.context.deletedObjects.map { $0.objectID })
|
return Set(self.context.deletedObjects.map { $0.objectID })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
- parameter entity: the `DynamicObject` subclass to filter
|
||||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
||||||
*/
|
*/
|
||||||
public func deletedObjectIDs<T: NSManagedObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
public func deletedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||||
@@ -442,20 +380,34 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
!self.isCommitted,
|
!self.isCommitted,
|
||||||
"Attempted to access deleted object IDs from an already committed \(cs_typeName(self))."
|
"Attempted to access deleted object IDs from an already committed \(cs_typeName(self))."
|
||||||
)
|
)
|
||||||
|
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||||
return Set(self.context.deletedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: 3rd Party Utilities
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allow external libraries to store custom data in the transaction. App code should rarely have a need for this.
|
||||||
|
```
|
||||||
|
enum Static {
|
||||||
|
static var myDataKey: Void?
|
||||||
|
}
|
||||||
|
transaction.userInfo[&Static.myDataKey] = myObject
|
||||||
|
```
|
||||||
|
- Important: Do not use this method to store thread-sensitive data.
|
||||||
|
*/
|
||||||
|
public let userInfo = UserInfo()
|
||||||
|
|
||||||
|
|
||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
internal let context: NSManagedObjectContext
|
internal let context: NSManagedObjectContext
|
||||||
internal let transactionQueue: DispatchQueue
|
internal let transactionQueue: DispatchQueue
|
||||||
internal let childTransactionQueue = DispatchQueue.serial("com.corestore.datastack.childtransactionqueue")
|
internal let childTransactionQueue = DispatchQueue.serial("com.corestore.datastack.childTransactionQueue")
|
||||||
internal let supportsUndo: Bool
|
internal let supportsUndo: Bool
|
||||||
internal let bypassesQueueing: Bool
|
internal let bypassesQueueing: Bool
|
||||||
internal var isCommitted = false
|
internal var isCommitted = false
|
||||||
internal var result: SaveResult?
|
internal var result: (hasChanges: Bool, error: CoreStoreError?)?
|
||||||
|
|
||||||
internal init(mainContext: NSManagedObjectContext, queue: DispatchQueue, supportsUndo: Bool, bypassesQueueing: Bool) {
|
internal init(mainContext: NSManagedObjectContext, queue: DispatchQueue, supportsUndo: Bool, bypassesQueueing: Bool) {
|
||||||
|
|
||||||
@@ -485,4 +437,49 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
|
|
||||||
return self.bypassesQueueing || self.transactionQueue.cs_isCurrentExecutionContext()
|
return self.bypassesQueueing || self.transactionQueue.cs_isCurrentExecutionContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,32 +40,26 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
|||||||
/**
|
/**
|
||||||
Saves the transaction changes. This method should not be used after the `-commitWithCompletion:` method was already called once.
|
Saves the transaction changes. This method should not be used after the `-commitWithCompletion:` method was already called once.
|
||||||
|
|
||||||
- parameter completion: the block executed after the save completes. Success or failure is reported by the `CSSaveResult` argument of the block.
|
- parameter success: the block executed if the save succeeds.
|
||||||
|
- parameter failure: the block executed if the save fails. A `CSError` is reported as the argument of the block.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public func commitWithCompletion(_ completion: ((_ result: CSSaveResult) -> Void)?) {
|
public func commitWithSuccess(_ success: (() -> Void)?, failure: ((CSError) -> Void)?) {
|
||||||
|
|
||||||
self.bridgeToSwift.commit { (result) in
|
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.autoCommit { (result) in
|
||||||
|
|
||||||
completion?(result.bridgeToObjectiveC)
|
switch result {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
case (_, nil): success?()
|
||||||
Begins a child transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made. This method should not be used after the `-commitWithCompletion:` method was already called once.
|
case (_, let error?): failure?(error.bridgeToObjectiveC)
|
||||||
|
|
||||||
- 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
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
@discardableResult
|
|
||||||
public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
|
||||||
|
|
||||||
return bridge {
|
|
||||||
|
|
||||||
self.bridgeToSwift.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
closure(transaction.bridgeToObjectiveC)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,6 +153,41 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
|||||||
|
|
||||||
super.init(swiftValue as! AsynchronousDataTransaction)
|
super.init(swiftValue as! AsynchronousDataTransaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public extension CSBaseDataTransaction {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObject(_ object: NSManagedObject) -> Any? {
|
public func fetchExistingObject(_ object: NSManagedObject) -> Any? {
|
||||||
|
|
||||||
return self.bridgeToSwift.context.fetchExisting(object)
|
return self.bridgeToSwift.context.fetchExisting(object) as NSManagedObject?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,7 +52,7 @@ public extension CSBaseDataTransaction {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? {
|
public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? {
|
||||||
|
|
||||||
return self.bridgeToSwift.context.fetchExisting(objectID)
|
return self.bridgeToSwift.context.fetchExisting(objectID) as NSManagedObject?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,7 +64,7 @@ public extension CSBaseDataTransaction {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] {
|
public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] {
|
||||||
|
|
||||||
return self.bridgeToSwift.context.fetchExisting(objects)
|
return self.bridgeToSwift.context.fetchExisting(objects) as [NSManagedObject]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +76,7 @@ public extension CSBaseDataTransaction {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] {
|
public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] {
|
||||||
|
|
||||||
return self.bridgeToSwift.context.fetchExisting(objectIDs)
|
return self.bridgeToSwift.context.fetchExisting(objectIDs) as [NSManagedObject]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -119,17 +119,6 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
// MARK: Inspecting Pending Objects
|
// MARK: Inspecting Pending Objects
|
||||||
|
|
||||||
/**
|
|
||||||
Returns all pending `NSManagedObject`s that were inserted to the transaction. This method should not be called after the `-commit*:` method was called.
|
|
||||||
|
|
||||||
- returns: an `NSSet` of pending `NSManagedObject`s that were inserted to the transaction.
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public func insertedObjects() -> Set<NSManagedObject> {
|
|
||||||
|
|
||||||
return self.bridgeToSwift.insertedObjects()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObject`s of the specified type that were inserted to the transaction. This method should not be called after the `-commit*:` method was called.
|
Returns all pending `NSManagedObject`s of the specified type that were inserted to the transaction. This method should not be called after the `-commit*:` method was called.
|
||||||
|
|
||||||
@@ -165,17 +154,6 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
|||||||
return self.bridgeToSwift.insertedObjectIDs(entity)
|
return self.bridgeToSwift.insertedObjectIDs(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Returns all pending `NSManagedObject`s that were updated in the transaction. This method should not be called after the `-commit*:` method was called.
|
|
||||||
|
|
||||||
- returns: an `NSSet` of pending `NSManagedObject`s that were updated to the transaction.
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public func updatedObjects() -> Set<NSManagedObject> {
|
|
||||||
|
|
||||||
return self.bridgeToSwift.updatedObjects()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObject`s of the specified type that were updated in the transaction. This method should not be called after the `-commit*:` method was called.
|
Returns all pending `NSManagedObject`s of the specified type that were updated in the transaction. This method should not be called after the `-commit*:` method was called.
|
||||||
|
|
||||||
@@ -211,17 +189,6 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
|||||||
return self.bridgeToSwift.updatedObjectIDs(entity)
|
return self.bridgeToSwift.updatedObjectIDs(entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Returns all pending `NSManagedObject`s that were deleted from the transaction. This method should not be called after the `-commit*:` method was called.
|
|
||||||
|
|
||||||
- returns: an `NSSet` of pending `NSManagedObject`s that were deleted from the transaction.
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public func deletedObjects() -> Set<NSManagedObject> {
|
|
||||||
|
|
||||||
return self.bridgeToSwift.deletedObjects()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObject`s of the specified type that were deleted from the transaction. This method should not be called after the `-commit*:` method was called.
|
Returns all pending `NSManagedObject`s of the specified type that were deleted from the transaction. This method should not be called after the `-commit*:` method was called.
|
||||||
|
|
||||||
@@ -237,7 +204,6 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
|||||||
/**
|
/**
|
||||||
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `-commit*:` method was called.
|
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `-commit*:` method was called.
|
||||||
|
|
||||||
- parameter entity: the `NSManagedObject` subclass to filter
|
|
||||||
- returns: an `NSSet` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
- returns: an `NSSet` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
@@ -293,4 +259,28 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
|||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private let swiftTransaction: BaseDataTransaction
|
private let swiftTransaction: BaseDataTransaction
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Deprecated
|
||||||
|
|
||||||
|
@available(*, deprecated, message: "Use -[insertedObjectsOfType:] and pass the specific entity class")
|
||||||
|
@objc
|
||||||
|
public func insertedObjects() -> Set<NSManagedObject> {
|
||||||
|
|
||||||
|
return self.bridgeToSwift.insertedObjects()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, deprecated, message: "Use -[updatedObjectsOfType:] and pass the specific entity class")
|
||||||
|
@objc
|
||||||
|
public func updatedObjects() -> Set<NSManagedObject> {
|
||||||
|
|
||||||
|
return self.bridgeToSwift.updatedObjects()
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(*, deprecated, message: "Use -[deletedObjectsOfType:] and pass the specific entity class")
|
||||||
|
@objc
|
||||||
|
public func deletedObjects() -> Set<NSManagedObject> {
|
||||||
|
|
||||||
|
return self.bridgeToSwift.deletedObjects()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,9 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CSCoreStore
|
// MARK: - CSCoreStore
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
public extension CSCoreStore {
|
public extension CSCoreStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,5 +111,3 @@ public extension CSCoreStore {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -44,21 +44,9 @@ public extension CSCoreStore {
|
|||||||
Returns the entity name-to-class type mapping from the `defaultStack`'s model.
|
Returns the entity name-to-class type mapping from the `defaultStack`'s model.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public static var entityClassesByName: [String: NSManagedObject.Type] {
|
public static func entityTypesByNameForType(_ type: NSManagedObject.Type) -> [EntityName: NSManagedObject.Type] {
|
||||||
|
|
||||||
return CoreStore.entityTypesByName
|
return CoreStore.entityTypesByName(for: type)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the entity class for the given entity name from the `defaultStack`'s model.
|
|
||||||
|
|
||||||
- parameter name: the entity name
|
|
||||||
- returns: the `NSManagedObject` class for the given entity name, or `nil` if not found
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public static func entityClassWithName(_ name: String) -> NSManagedObject.Type? {
|
|
||||||
|
|
||||||
return CoreStore.entityTypesByName[name]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,4 +125,21 @@ public extension CSCoreStore {
|
|||||||
|
|
||||||
return self.defaultStack.addSQLiteStorageAndWait(storage, error: error)
|
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]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,10 +38,7 @@ public extension CSCoreStore {
|
|||||||
@objc
|
@objc
|
||||||
public static func beginAsynchronous(_ closure: @escaping (_ transaction: CSAsynchronousDataTransaction) -> Void) {
|
public static func beginAsynchronous(_ closure: @escaping (_ transaction: CSAsynchronousDataTransaction) -> Void) {
|
||||||
|
|
||||||
return CoreStore.beginAsynchronous { (transaction) in
|
self.defaultStack.beginAsynchronous(closure)
|
||||||
|
|
||||||
closure(transaction.bridgeToObjectiveC)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,16 +48,9 @@ public extension CSCoreStore {
|
|||||||
- returns: a `CSSaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
- returns: a `CSSaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
@discardableResult
|
public static func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void, error: NSErrorPointer) -> Bool {
|
||||||
public static func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
|
||||||
|
|
||||||
return bridge {
|
return self.defaultStack.beginSynchronous(closure, error: error)
|
||||||
|
|
||||||
CoreStore.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
closure(transaction.bridgeToObjectiveC)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,4 +91,15 @@ public extension CSCoreStore {
|
|||||||
|
|
||||||
CoreStore.refreshAndMergeAllObjects()
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,9 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CSDataStack
|
// MARK: - CSDataStack
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
public extension CSDataStack {
|
public extension CSDataStack {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,10 +41,7 @@ public extension CSDataStack {
|
|||||||
@objc
|
@objc
|
||||||
public func monitorObject(_ object: NSManagedObject) -> CSObjectMonitor {
|
public func monitorObject(_ object: NSManagedObject) -> CSObjectMonitor {
|
||||||
|
|
||||||
return bridge {
|
return self.bridgeToSwift.monitorObject(object).bridgeToObjectiveC
|
||||||
|
|
||||||
self.bridgeToSwift.monitorObject(object)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,9 +62,7 @@ public extension CSDataStack {
|
|||||||
fetchClauses.contains { $0 is CSOrderBy },
|
fetchClauses.contains { $0 is CSOrderBy },
|
||||||
"A CSListMonitor requires a CSOrderBy clause."
|
"A CSListMonitor requires a CSOrderBy clause."
|
||||||
)
|
)
|
||||||
return bridge {
|
return ListMonitor(
|
||||||
|
|
||||||
ListMonitor(
|
|
||||||
dataStack: self.bridgeToSwift,
|
dataStack: self.bridgeToSwift,
|
||||||
from: from.bridgeToSwift,
|
from: from.bridgeToSwift,
|
||||||
sectionBy: nil,
|
sectionBy: nil,
|
||||||
@@ -76,8 +70,7 @@ public extension CSDataStack {
|
|||||||
|
|
||||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||||
}
|
}
|
||||||
)
|
).bridgeToObjectiveC
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,9 +125,7 @@ public extension CSDataStack {
|
|||||||
fetchClauses.contains { $0 is CSOrderBy },
|
fetchClauses.contains { $0 is CSOrderBy },
|
||||||
"A CSListMonitor requires an CSOrderBy clause."
|
"A CSListMonitor requires an CSOrderBy clause."
|
||||||
)
|
)
|
||||||
return bridge {
|
return ListMonitor(
|
||||||
|
|
||||||
ListMonitor(
|
|
||||||
dataStack: self.bridgeToSwift,
|
dataStack: self.bridgeToSwift,
|
||||||
from: from.bridgeToSwift,
|
from: from.bridgeToSwift,
|
||||||
sectionBy: sectionBy.bridgeToSwift,
|
sectionBy: sectionBy.bridgeToSwift,
|
||||||
@@ -142,8 +133,7 @@ public extension CSDataStack {
|
|||||||
|
|
||||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||||
}
|
}
|
||||||
)
|
).bridgeToObjectiveC
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,5 +169,3 @@ public extension CSDataStack {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public extension CSDataStack {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObject(_ object: NSManagedObject) -> Any? {
|
public func fetchExistingObject(_ object: NSManagedObject) -> Any? {
|
||||||
|
|
||||||
return self.bridgeToSwift.mainContext.fetchExisting(object)
|
return self.bridgeToSwift.mainContext.fetchExisting(object) as NSManagedObject?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,7 +52,7 @@ public extension CSDataStack {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? {
|
public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? {
|
||||||
|
|
||||||
return self.bridgeToSwift.mainContext.fetchExisting(objectID)
|
return self.bridgeToSwift.mainContext.fetchExisting(objectID) as NSManagedObject?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,7 +64,7 @@ public extension CSDataStack {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] {
|
public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] {
|
||||||
|
|
||||||
return self.bridgeToSwift.mainContext.fetchExisting(objects)
|
return self.bridgeToSwift.mainContext.fetchExisting(objects) as [NSManagedObject]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +76,7 @@ public extension CSDataStack {
|
|||||||
@objc
|
@objc
|
||||||
public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] {
|
public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] {
|
||||||
|
|
||||||
return self.bridgeToSwift.mainContext.fetchExisting(objectIDs)
|
return self.bridgeToSwift.mainContext.fetchExisting(objectIDs) as [NSManagedObject]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,27 +38,57 @@ public extension CSDataStack {
|
|||||||
@objc
|
@objc
|
||||||
public func beginAsynchronous(_ closure: @escaping (_ transaction: CSAsynchronousDataTransaction) -> Void) {
|
public func beginAsynchronous(_ closure: @escaping (_ transaction: CSAsynchronousDataTransaction) -> Void) {
|
||||||
|
|
||||||
return self.bridgeToSwift.beginAsynchronous { (transaction) in
|
self.bridgeToSwift.perform(
|
||||||
|
asynchronous: { (transaction) in
|
||||||
|
|
||||||
closure(transaction.bridgeToObjectiveC)
|
let csTransaction = transaction.bridgeToObjectiveC
|
||||||
|
closure(csTransaction)
|
||||||
|
if !transaction.isCommitted && transaction.hasChanges {
|
||||||
|
|
||||||
|
CoreStore.log(
|
||||||
|
.warning,
|
||||||
|
message: "The closure for the \(cs_typeName(csTransaction)) completed without being committed. All changes made within the transaction were discarded."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
try transaction.cancel()
|
||||||
|
},
|
||||||
|
completion: { _ in }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
Begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||||
|
|
||||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
- parameter 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
|
- parameter error: the `CSError` pointer that indicates the reason in case of an failure
|
||||||
|
- returns: `YES` if the commit succeeded, `NO` if the commit failed. If `NO`, the `error` argument will hold error information.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
@discardableResult
|
public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void, error: NSErrorPointer) -> Bool {
|
||||||
public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
|
||||||
|
|
||||||
return bridge {
|
return bridge(error) {
|
||||||
|
|
||||||
self.bridgeToSwift.beginSynchronous { (transaction) in
|
do {
|
||||||
|
|
||||||
closure(transaction.bridgeToObjectiveC)
|
try self.bridgeToSwift.perform(
|
||||||
|
synchronous: { (transaction) in
|
||||||
|
|
||||||
|
let csTransaction = transaction.bridgeToObjectiveC
|
||||||
|
closure(csTransaction)
|
||||||
|
if !transaction.isCommitted && transaction.hasChanges {
|
||||||
|
|
||||||
|
CoreStore.log(
|
||||||
|
.warning,
|
||||||
|
message: "The closure for the \(cs_typeName(csTransaction)) completed without being committed. All changes made within the transaction were discarded."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
try transaction.cancel()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
catch CoreStoreError.userCancelled {
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,4 +131,21 @@ public extension CSDataStack {
|
|||||||
|
|
||||||
self.bridgeToSwift.refreshAndMergeAllObjects()
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,75 +49,22 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
|||||||
/**
|
/**
|
||||||
Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`.
|
Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`.
|
||||||
|
|
||||||
- parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
|
- parameter xcodeModelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
|
||||||
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
||||||
- parameter versionChain: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
- parameter versionChain: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(modelName: String?, bundle: Bundle?, versionChain: [String]?) {
|
public convenience init(xcodeModelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) {
|
||||||
|
|
||||||
self.init(
|
self.init(
|
||||||
DataStack(
|
DataStack(
|
||||||
modelName: modelName ?? DataStack.applicationName,
|
xcodeModelName: xcodeModelName ?? DataStack.applicationName,
|
||||||
bundle: bundle ?? Bundle.main,
|
bundle: bundle ?? Bundle.main,
|
||||||
migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil
|
migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`.
|
|
||||||
|
|
||||||
- parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
|
|
||||||
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
|
||||||
- parameter versionTree: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public convenience init(modelName: String?, bundle: Bundle?, versionTree: [String: String]?) {
|
|
||||||
|
|
||||||
self.init(
|
|
||||||
DataStack(
|
|
||||||
modelName: modelName ?? DataStack.applicationName,
|
|
||||||
bundle: bundle ?? Bundle.main,
|
|
||||||
migrationChain: versionTree.flatMap { MigrationChain($0) } ?? nil
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initializes a `DataStack` from an `NSManagedObjectModel`.
|
|
||||||
|
|
||||||
- parameter model: the `NSManagedObjectModel` for the stack
|
|
||||||
- parameter versionChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public convenience init(model: NSManagedObjectModel, versionChain: [String]?) {
|
|
||||||
|
|
||||||
self.init(
|
|
||||||
DataStack(
|
|
||||||
model: model,
|
|
||||||
migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initializes a `DataStack` from an `NSManagedObjectModel`.
|
|
||||||
|
|
||||||
- parameter model: the `NSManagedObjectModel` for the stack
|
|
||||||
- parameter versionTree: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public convenience init(model: NSManagedObjectModel, versionTree: [String]?) {
|
|
||||||
|
|
||||||
self.init(
|
|
||||||
DataStack(
|
|
||||||
model: model,
|
|
||||||
migrationChain: versionTree.flatMap { MigrationChain($0) } ?? nil
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the stack's model version. The version string is the same as the name of the version-specific .xcdatamodeld file.
|
Returns the stack's model version. The version string is the same as the name of the version-specific .xcdatamodeld file.
|
||||||
*/
|
*/
|
||||||
@@ -128,23 +75,12 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the entity name-to-class type mapping from the stack's model.
|
Returns the entity name-to-class type mapping from the `CSDataStack`'s model.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public var entityClassesByName: [String: NSManagedObject.Type] {
|
public func entityTypesByNameForType(_ type: NSManagedObject.Type) -> [EntityName: NSManagedObject.Type] {
|
||||||
|
|
||||||
return self.bridgeToSwift.entityTypesByName
|
return self.bridgeToSwift.entityTypesByName(for: type)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the entity class for the given entity name from the stack's's model.
|
|
||||||
- parameter name: the entity name
|
|
||||||
- returns: the `NSManagedObject` class for the given entity name, or `nil` if not found
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
public func entityClassWithName(_ name: String) -> NSManagedObject.Type? {
|
|
||||||
|
|
||||||
return self.bridgeToSwift.entityTypesByName[name]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -170,7 +106,7 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
return bridge(error) {
|
return bridge(error) {
|
||||||
|
|
||||||
try self.bridgeToSwift.addStorageAndWait(InMemoryStore.self)
|
try self.bridgeToSwift.addStorageAndWait(InMemoryStore())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +124,7 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
return bridge(error) {
|
return bridge(error) {
|
||||||
|
|
||||||
try self.bridgeToSwift.addStorageAndWait(SQLiteStore.self)
|
try self.bridgeToSwift.addStorageAndWait(SQLiteStore())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +204,60 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
|||||||
self.bridgeToSwift = swiftValue
|
self.bridgeToSwift = swiftValue
|
||||||
super.init()
|
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]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
51
Sources/CSDynamicSchema.swift
Normal file
51
Sources/CSDynamicSchema.swift
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// CSDynamicSchema.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CSDynamicSchema
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `CSDynamicSchema` serves as the Objective-C bridging type for `DynamicSchema`.
|
||||||
|
|
||||||
|
- SeeAlso: `DynamicSchema`
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
public protocol CSDynamicSchema {
|
||||||
|
|
||||||
|
/**
|
||||||
|
The version string for this model schema.
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
var modelVersion: ModelVersion { get }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do not call this directly. The `NSManagedObjectModel` for this schema may be created lazily and using this method directly may affect the integrity of the model.
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
func rawModel() -> NSManagedObjectModel
|
||||||
|
}
|
||||||
@@ -137,6 +137,16 @@ public enum CSErrorCode: Int {
|
|||||||
An internal SDK call failed with the specified "NSError" userInfo key.
|
An internal SDK call failed with the specified "NSError" userInfo key.
|
||||||
*/
|
*/
|
||||||
case internalError
|
case internalError
|
||||||
|
|
||||||
|
/**
|
||||||
|
The transaction was terminated by a user-thrown error with the specified "Error" userInfo key.
|
||||||
|
*/
|
||||||
|
case userError
|
||||||
|
|
||||||
|
/**
|
||||||
|
The transaction was cancelled by the user.
|
||||||
|
*/
|
||||||
|
case userCancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -209,12 +219,23 @@ extension CoreStoreError: CoreStoreSwiftType, _ObjectiveCBridgeableError {
|
|||||||
self = .progressiveMigrationRequired(localStoreURL: localStoreURL)
|
self = .progressiveMigrationRequired(localStoreURL: localStoreURL)
|
||||||
|
|
||||||
case .internalError:
|
case .internalError:
|
||||||
guard case let NSError as NSError = info["NSError"] else {
|
guard case let nsError as NSError = info["NSError"] else {
|
||||||
|
|
||||||
self = .unknown
|
self = .unknown
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self = .internalError(NSError: NSError)
|
self = .internalError(NSError: nsError)
|
||||||
|
|
||||||
|
case .userError:
|
||||||
|
guard case let error as Error = info["Error"] else {
|
||||||
|
|
||||||
|
self = .unknown
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self = .userError(error: error)
|
||||||
|
|
||||||
|
case .userCancelled:
|
||||||
|
self = .userCancelled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import CoreData
|
|||||||
- SeeAlso: `From`
|
- SeeAlso: `From`
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
public final class CSFrom: NSObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The associated `NSManagedObject` entity class
|
The associated `NSManagedObject` entity class
|
||||||
@@ -71,7 +71,7 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
|||||||
- parameter entityClass: the `NSManagedObject` class type to be created
|
- parameter entityClass: the `NSManagedObject` class type to be created
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(entityClass: AnyClass) {
|
public convenience init(entityClass: NSManagedObject.Type) {
|
||||||
|
|
||||||
self.init(From(entityClass))
|
self.init(From(entityClass))
|
||||||
}
|
}
|
||||||
@@ -82,10 +82,11 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
|||||||
MyPersonEntity *people = [transaction fetchAllFrom:
|
MyPersonEntity *people = [transaction fetchAllFrom:
|
||||||
CSFromClass([MyPersonEntity class], @"Config1")];
|
CSFromClass([MyPersonEntity class], @"Config1")];
|
||||||
```
|
```
|
||||||
|
- parameter entityClass: the associated `NSManagedObject` entity class
|
||||||
- parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration.
|
- parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(entityClass: AnyClass, configuration: Any) {
|
public convenience init(entityClass: NSManagedObject.Type, configuration: Any) {
|
||||||
|
|
||||||
switch configuration {
|
switch configuration {
|
||||||
|
|
||||||
@@ -107,13 +108,13 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
|||||||
CSFromClass([MyPersonEntity class],
|
CSFromClass([MyPersonEntity class],
|
||||||
@[[NSNull null], @"Config1"])];
|
@[[NSNull null], @"Config1"])];
|
||||||
```
|
```
|
||||||
- parameter entity: the associated `NSManagedObject` entity class
|
- parameter entityClass: the associated `NSManagedObject` entity class
|
||||||
- parameter configurations: an array of the `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration.
|
- parameter configurations: an array of the `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(entityClass: AnyClass, configurations: [Any]) {
|
public convenience init(entityClass: NSManagedObject.Type, configurations: [Any]) {
|
||||||
|
|
||||||
var arguments = [String?]()
|
var arguments = [ModelConfiguration]()
|
||||||
for configuration in configurations {
|
for configuration in configurations {
|
||||||
|
|
||||||
switch configuration {
|
switch configuration {
|
||||||
@@ -154,7 +155,7 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
// MARK: - From
|
// MARK: - From
|
||||||
|
|
||||||
extension From: CoreStoreSwiftType {
|
extension From where T: NSManagedObject {
|
||||||
|
|
||||||
// MARK: CoreStoreSwiftType
|
// MARK: CoreStoreSwiftType
|
||||||
|
|
||||||
@@ -162,4 +163,16 @@ extension From: CoreStoreSwiftType {
|
|||||||
|
|
||||||
return CSFrom(self)
|
return CSFrom(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: FilePrivate
|
||||||
|
|
||||||
|
fileprivate func downcast() -> From<NSManagedObject> {
|
||||||
|
|
||||||
|
return From<NSManagedObject>(
|
||||||
|
entityClass: self.entityClass,
|
||||||
|
configurations: self.configurations,
|
||||||
|
findPersistentStores: self.findPersistentStores
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public final class CSInMemoryStore: NSObject, CSStorageInterface, CoreStoreObjec
|
|||||||
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration.
|
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(configuration: String?) {
|
public convenience init(configuration: ModelConfiguration) {
|
||||||
|
|
||||||
self.init(InMemoryStore(configuration: configuration))
|
self.init(InMemoryStore(configuration: configuration))
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ public final class CSInMemoryStore: NSObject, CSStorageInterface, CoreStoreObjec
|
|||||||
The configuration name in the model file
|
The configuration name in the model file
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public var configuration: String? {
|
public var configuration: ModelConfiguration {
|
||||||
|
|
||||||
return self.bridgeToSwift.configuration
|
return self.bridgeToSwift.configuration
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ import CoreData
|
|||||||
- SeeAlso: `Into`
|
- SeeAlso: `Into`
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public final class CSInto: NSObject, CoreStoreObjectiveCType {
|
public final class CSInto: NSObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The associated `NSManagedObject` entity class
|
The associated `NSManagedObject` entity class
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public var entityClass: AnyClass {
|
public var entityClass: NSManagedObject.Type {
|
||||||
|
|
||||||
return self.bridgeToSwift.entityClass
|
return self.bridgeToSwift.entityClass
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ public final class CSInto: NSObject, CoreStoreObjectiveCType {
|
|||||||
May contain a `String` to pertain to a named configuration, or `nil` to pertain to the default configuration
|
May contain a `String` to pertain to a named configuration, or `nil` to pertain to the default configuration
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public var configuration: String? {
|
public var configuration: ModelConfiguration {
|
||||||
|
|
||||||
return self.bridgeToSwift.configuration
|
return self.bridgeToSwift.configuration
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ public final class CSInto: NSObject, CoreStoreObjectiveCType {
|
|||||||
- parameter entityClass: the `NSManagedObject` class type to be created
|
- parameter entityClass: the `NSManagedObject` class type to be created
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(entityClass: AnyClass) {
|
public convenience init(entityClass: NSManagedObject.Type) {
|
||||||
|
|
||||||
self.init(Into(entityClass))
|
self.init(Into(entityClass))
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ public final class CSInto: NSObject, CoreStoreObjectiveCType {
|
|||||||
- parameter configuration: the `NSPersistentStore` configuration name to associate the object to. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration.
|
- parameter configuration: the `NSPersistentStore` configuration name to associate the object to. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(entityClass: AnyClass, configuration: String?) {
|
public convenience init(entityClass: NSManagedObject.Type, configuration: ModelConfiguration) {
|
||||||
|
|
||||||
self.init(Into(entityClass, configuration))
|
self.init(Into(entityClass, configuration))
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ public final class CSInto: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
// MARK: - Into
|
// MARK: - Into
|
||||||
|
|
||||||
extension Into: CoreStoreSwiftType {
|
extension Into where T: NSManagedObject {
|
||||||
|
|
||||||
// MARK: CoreStoreSwiftType
|
// MARK: CoreStoreSwiftType
|
||||||
|
|
||||||
@@ -130,4 +130,16 @@ extension Into: CoreStoreSwiftType {
|
|||||||
|
|
||||||
return CSInto(self)
|
return CSInto(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: FilePrivate
|
||||||
|
|
||||||
|
fileprivate func downcast() -> Into<NSManagedObject> {
|
||||||
|
|
||||||
|
return Into<NSManagedObject>(
|
||||||
|
entityClass: self.entityClass,
|
||||||
|
configuration: self.configuration,
|
||||||
|
inferStoreIfPossible: self.inferStoreIfPossible
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CSListMonitor
|
// MARK: - CSListMonitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,8 +34,9 @@ import CoreData
|
|||||||
|
|
||||||
- SeeAlso: `ListMonitor`
|
- SeeAlso: `ListMonitor`
|
||||||
*/
|
*/
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
public final class CSListMonitor: NSObject, CoreStoreObjectiveCType {
|
public final class CSListMonitor: NSObject {
|
||||||
|
|
||||||
// MARK: Public (Accessors)
|
// MARK: Public (Accessors)
|
||||||
|
|
||||||
@@ -546,7 +545,8 @@ public final class CSListMonitor: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
// MARK: - ListMonitor
|
// MARK: - ListMonitor
|
||||||
|
|
||||||
extension ListMonitor: CoreStoreSwiftType {
|
@available(OSX 10.12, *)
|
||||||
|
extension ListMonitor where ListMonitor.ObjectType: NSManagedObject {
|
||||||
|
|
||||||
// MARK: CoreStoreSwiftType
|
// MARK: CoreStoreSwiftType
|
||||||
|
|
||||||
@@ -554,6 +554,17 @@ extension ListMonitor: CoreStoreSwiftType {
|
|||||||
|
|
||||||
return CSListMonitor(self)
|
return CSListMonitor(self)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
// MARK: FilePrivate
|
||||||
|
|
||||||
|
fileprivate func downcast() -> ListMonitor<NSManagedObject> {
|
||||||
|
|
||||||
|
@inline(__always)
|
||||||
|
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
|
||||||
|
|
||||||
|
return unsafeBitCast(x, to: type)
|
||||||
|
}
|
||||||
|
return noWarnUnsafeBitCast(self, to: ListMonitor<NSManagedObject>.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CSListObserver
|
// MARK: - CSListObserver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +40,7 @@ import CoreData
|
|||||||
|
|
||||||
- SeeAlso: `ListObserver`
|
- SeeAlso: `ListObserver`
|
||||||
*/
|
*/
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
public protocol CSListObserver: class, AnyObject {
|
public protocol CSListObserver: class, AnyObject {
|
||||||
|
|
||||||
@@ -92,6 +91,7 @@ public protocol CSListObserver: class, AnyObject {
|
|||||||
|
|
||||||
- SeeAlso: `ListObjectObserver`
|
- SeeAlso: `ListObjectObserver`
|
||||||
*/
|
*/
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
public protocol CSListObjectObserver: CSListObserver {
|
public protocol CSListObjectObserver: CSListObserver {
|
||||||
|
|
||||||
@@ -152,6 +152,7 @@ public protocol CSListObjectObserver: CSListObserver {
|
|||||||
|
|
||||||
- SeeAlso: `ListSectionObserver`
|
- SeeAlso: `ListSectionObserver`
|
||||||
*/
|
*/
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
public protocol CSListSectionObserver: CSListObjectObserver {
|
public protocol CSListSectionObserver: CSListObjectObserver {
|
||||||
|
|
||||||
@@ -175,5 +176,3 @@ public protocol CSListSectionObserver: CSListObjectObserver {
|
|||||||
@objc
|
@objc
|
||||||
optional func listMonitor(_ monitor: CSListMonitor, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int)
|
optional func listMonitor(_ monitor: CSListMonitor, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CSObjectMonitor
|
// MARK: - CSObjectMonitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,8 +34,9 @@ import CoreData
|
|||||||
|
|
||||||
- SeeAlso: `ObjectMonitor`
|
- SeeAlso: `ObjectMonitor`
|
||||||
*/
|
*/
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
public final class CSObjectMonitor: NSObject, CoreStoreObjectiveCType {
|
public final class CSObjectMonitor: NSObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the `NSManagedObject` instance being observed, or `nil` if the object was already deleted.
|
Returns the `NSManagedObject` instance being observed, or `nil` if the object was already deleted.
|
||||||
@@ -138,7 +137,8 @@ public final class CSObjectMonitor: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
// MARK: - ObjectMonitor
|
// MARK: - ObjectMonitor
|
||||||
|
|
||||||
extension ObjectMonitor: CoreStoreSwiftType {
|
@available(OSX 10.12, *)
|
||||||
|
extension ObjectMonitor where ObjectMonitor.ObjectType: NSManagedObject {
|
||||||
|
|
||||||
// MARK: CoreStoreSwiftType
|
// MARK: CoreStoreSwiftType
|
||||||
|
|
||||||
@@ -146,6 +146,17 @@ extension ObjectMonitor: CoreStoreSwiftType {
|
|||||||
|
|
||||||
return CSObjectMonitor(self)
|
return CSObjectMonitor(self)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
// MARK: FilePrivate
|
||||||
|
|
||||||
|
fileprivate func downcast() -> ObjectMonitor<NSManagedObject> {
|
||||||
|
|
||||||
|
@inline(__always)
|
||||||
|
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
|
||||||
|
|
||||||
|
return unsafeBitCast(x, to: type)
|
||||||
|
}
|
||||||
|
return noWarnUnsafeBitCast(self, to: ObjectMonitor<NSManagedObject>.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CSObjectObserver
|
// MARK: - CSObjectObserver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,6 +38,7 @@ import CoreData
|
|||||||
|
|
||||||
- SeeAlso: `ObjectObserver`
|
- SeeAlso: `ObjectObserver`
|
||||||
*/
|
*/
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
public protocol CSObjectObserver: class, AnyObject {
|
public protocol CSObjectObserver: class, AnyObject {
|
||||||
|
|
||||||
@@ -71,5 +70,3 @@ public protocol CSObjectObserver: class, AnyObject {
|
|||||||
@objc
|
@objc
|
||||||
optional func objectMonitor(_ monitor: CSObjectMonitor, didDeleteObject object: Any)
|
optional func objectMonitor(_ monitor: CSObjectMonitor, didDeleteObject object: Any)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -40,19 +40,18 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
|||||||
/**
|
/**
|
||||||
Initializes an SQLite store interface from the given SQLite file URL. When this instance is passed to the `CSDataStack`'s `-addStorage*:` methods, a new SQLite file will be created if it does not exist.
|
Initializes an SQLite store interface from the given SQLite file URL. When this instance is passed to the `CSDataStack`'s `-addStorage*:` methods, a new SQLite file will be created if it does not exist.
|
||||||
|
|
||||||
|
- Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property.
|
||||||
- parameter fileURL: the local file URL for the target SQLite persistent store. Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them.
|
- parameter fileURL: the local file URL for the target SQLite persistent store. Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them.
|
||||||
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them.
|
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them.
|
||||||
- parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration.
|
|
||||||
- parameter localStorageOptions: When the `CSSQLiteStore` is passed to the `CSDataStack`'s `addStorage()` methods, tells the `CSDataStack` how to setup the persistent store. Defaults to `CSLocalStorageOptionsNone`.
|
- parameter localStorageOptions: When the `CSSQLiteStore` is passed to the `CSDataStack`'s `addStorage()` methods, tells the `CSDataStack` how to setup the persistent store. Defaults to `CSLocalStorageOptionsNone`.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(fileURL: URL, configuration: String?, mappingModelBundles: [Bundle]?, localStorageOptions: Int) {
|
public convenience init(fileURL: URL, configuration: ModelConfiguration, localStorageOptions: Int) {
|
||||||
|
|
||||||
self.init(
|
self.init(
|
||||||
SQLiteStore(
|
SQLiteStore(
|
||||||
fileURL: fileURL,
|
fileURL: fileURL,
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
mappingModelBundles: mappingModelBundles ?? Bundle.allBundles,
|
|
||||||
localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions)
|
localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -61,29 +60,27 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
|||||||
/**
|
/**
|
||||||
Initializes an SQLite store interface from the given SQLite file name. When this instance is passed to the `CSDataStack`'s `-addStorage*:` methods, a new SQLite file will be created if it does not exist.
|
Initializes an SQLite store interface from the given SQLite file name. When this instance is passed to the `CSDataStack`'s `-addStorage*:` methods, a new SQLite file will be created if it does not exist.
|
||||||
|
|
||||||
- Warning: The default SQLite file location for the `CSLegacySQLiteStore` and `CSSQLiteStore` are different. If the app was depending on CoreStore's default directories prior to 2.0.0, make sure to use `CSLegacySQLiteStore` instead of `CSSQLiteStore`.
|
- Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property.
|
||||||
- parameter fileName: the local filename for the SQLite persistent store in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS). Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
|
- parameter fileName: the local filename for the SQLite persistent store in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS). Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
|
||||||
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
|
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
|
||||||
- parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration
|
|
||||||
- parameter localStorageOptions: When the `CSSQLiteStore` is passed to the `CSDataStack`'s `addStorage()` methods, tells the `CSDataStack` how to setup the persistent store. Defaults to `[CSLocalStorageOptions none]`.
|
- parameter localStorageOptions: When the `CSSQLiteStore` is passed to the `CSDataStack`'s `addStorage()` methods, tells the `CSDataStack` how to setup the persistent store. Defaults to `[CSLocalStorageOptions none]`.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience init(fileName: String, configuration: String?, mappingModelBundles: [Bundle]?, localStorageOptions: Int) {
|
public convenience init(fileName: String, configuration: ModelConfiguration, localStorageOptions: Int) {
|
||||||
|
|
||||||
self.init(
|
self.init(
|
||||||
SQLiteStore(
|
SQLiteStore(
|
||||||
fileName: fileName,
|
fileName: fileName,
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
mappingModelBundles: mappingModelBundles ?? Bundle.allBundles,
|
|
||||||
localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions)
|
localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes an `CSSQLiteStore` with an all-default settings: a `fileURL` pointing to a "<Application name>.sqlite" file in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `mappingModelBundles` set to search all `NSBundle`s, and `localStorageOptions` set to `.AllowProgresiveMigration`.
|
Initializes an `CSSQLiteStore` with an all-default settings: a `fileURL` pointing to a "<Application name>.sqlite" file in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, and `localStorageOptions` set to `[CSLocalStorageOptions none]`.
|
||||||
|
|
||||||
- Warning: The default SQLite file location for the `CSLegacySQLiteStore` and `CSSQLiteStore` are different. If the app was depending on CoreStore's default directories prior to 2.0.0, make sure to use `CSLegacySQLiteStore` instead of `CSSQLiteStore`.
|
- Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public convenience override init() {
|
public convenience override init() {
|
||||||
@@ -104,12 +101,12 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The `NSBundle`s from which to search mapping models for migrations
|
An array of `SchemaMappingProvider`s that provides the complete mapping models for custom migrations. This is currently only supported for Swift code.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public var mappingModelBundles: [Bundle] {
|
public var migrationMappingProviders: [Any] {
|
||||||
|
|
||||||
return self.bridgeToSwift.mappingModelBundles
|
return self.bridgeToSwift.migrationMappingProviders
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,7 +130,7 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
|||||||
/**
|
/**
|
||||||
The configuration name in the model file
|
The configuration name in the model file
|
||||||
*/
|
*/
|
||||||
public var configuration: String? {
|
public var configuration: ModelConfiguration {
|
||||||
|
|
||||||
return self.bridgeToSwift.configuration
|
return self.bridgeToSwift.configuration
|
||||||
}
|
}
|
||||||
@@ -154,11 +151,11 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
|||||||
Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `CSSQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
|
Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `CSSQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public func eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool {
|
public func cs_eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool {
|
||||||
|
|
||||||
return bridge(error) {
|
return bridge(error) {
|
||||||
|
|
||||||
try self.bridgeToSwift.eraseStorageAndWait(metadata: metadata as! [String: Any], soureModelHint: soureModelHint)
|
try self.bridgeToSwift.cs_eraseStorageAndWait(metadata: metadata as! [String: Any], soureModelHint: soureModelHint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +191,23 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
|||||||
self.bridgeToSwift = swiftValue
|
self.bridgeToSwift = swiftValue
|
||||||
super.init()
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,35 +29,22 @@ import CoreData
|
|||||||
|
|
||||||
// MARK: - CSSaveResult
|
// MARK: - CSSaveResult
|
||||||
|
|
||||||
/**
|
@available(*, deprecated, message: "Use APIs that report failures with `CSError`s instead.")
|
||||||
The `CSSaveResult` serves as the Objective-C bridging type for `SaveResult`.
|
|
||||||
|
|
||||||
- SeeAlso: `SaveResult`
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
||||||
|
|
||||||
/**
|
|
||||||
`YES` if the `commit` operation for the transaction succeeded, either because the save succeeded or because there were no changes to save. Returns `NO` to indicate failure.
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public var isSuccess: Bool {
|
public var isSuccess: Bool {
|
||||||
|
|
||||||
return self.bridgeToSwift.boolValue
|
return self.bridgeToSwift.boolValue
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
`YES` if the `commit` operation for the transaction failed, or `NO` otherwise. When `YES`, the `error` property returns the actual `NSError` for the failure.
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public var isFailure: Bool {
|
public var isFailure: Bool {
|
||||||
|
|
||||||
return !self.bridgeToSwift.boolValue
|
return !self.bridgeToSwift.boolValue
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
`YES` if the `commit` operation for the transaction succeeded and if there was an actual change made. Returns `NO` otherwise.
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public var hasChanges: Bool {
|
public var hasChanges: Bool {
|
||||||
|
|
||||||
@@ -68,9 +55,6 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
|||||||
return hasChanges
|
return hasChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
The `NSError` for a failed `commit` operation, or `nil` if the `commit` succeeded
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public var error: NSError? {
|
public var error: NSError? {
|
||||||
|
|
||||||
@@ -81,14 +65,6 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
|||||||
return error.bridgeToObjectiveC
|
return error.bridgeToObjectiveC
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
If the result was a success, the `success` block is executed with a `BOOL` argument that indicates if there were any changes made. If the result was a failure, the `failure` block is executed with an `NSError` argument pertaining to the actual error.
|
|
||||||
|
|
||||||
The blocks are executed immediately as `@noescape` and will not be retained.
|
|
||||||
|
|
||||||
- parameter success: the block to execute on success. The block passes a `BOOL` argument that indicates if there were any changes made.
|
|
||||||
- parameter failure: the block to execute on failure. The block passes an `NSError` argument that pertains to the actual error.
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void, failure: (_ error: NSError) -> Void) {
|
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void, failure: (_ error: NSError) -> Void) {
|
||||||
|
|
||||||
@@ -102,13 +78,6 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
If the result was a success, the `success` block is executed with a `BOOL` argument that indicates if there were any changes made. If the result was a failure, this method does nothing.
|
|
||||||
|
|
||||||
The block is executed immediately as `@noescape` and will not be retained.
|
|
||||||
|
|
||||||
- parameter success: the block to execute on success. The block passes a `BOOL` argument that indicates if there were any changes made.
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void) {
|
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void) {
|
||||||
|
|
||||||
@@ -119,13 +88,6 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
|||||||
success(hasChanges)
|
success(hasChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
If the result was a failure, the `failure` block is executed with an `NSError` argument pertaining to the actual error. If the result was a success, this method does nothing.
|
|
||||||
|
|
||||||
The block is executed immediately as `@noescape` and will not be retained.
|
|
||||||
|
|
||||||
- parameter failure: the block to execute on failure. The block passes an `NSError` argument that pertains to the actual error.
|
|
||||||
*/
|
|
||||||
@objc
|
@objc
|
||||||
public func handleFailure(_ failure: (_ error: NSError) -> Void) {
|
public func handleFailure(_ failure: (_ error: NSError) -> Void) {
|
||||||
|
|
||||||
@@ -173,6 +135,7 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
// MARK: - SaveResult
|
// MARK: - SaveResult
|
||||||
|
|
||||||
|
@available(*, deprecated, message: "Use the new DataStack.perform(asynchronous:...) and DataStack.perform(synchronous:...) family of APIs")
|
||||||
extension SaveResult: CoreStoreSwiftType {
|
extension SaveResult: CoreStoreSwiftType {
|
||||||
|
|
||||||
// MARK: CoreStoreSwiftType
|
// MARK: CoreStoreSwiftType
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CSSectionBy
|
// MARK: - CSSectionBy
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,6 +34,7 @@ import CoreData
|
|||||||
|
|
||||||
- SeeAlso: `SectionBy`
|
- SeeAlso: `SectionBy`
|
||||||
*/
|
*/
|
||||||
|
@available(OSX 10.12, *)
|
||||||
@objc
|
@objc
|
||||||
public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||||
|
|
||||||
@@ -87,6 +86,7 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
|||||||
|
|
||||||
// MARK: - SectionBy
|
// MARK: - SectionBy
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
extension SectionBy: CoreStoreSwiftType {
|
extension SectionBy: CoreStoreSwiftType {
|
||||||
|
|
||||||
// MARK: CoreStoreSwiftType
|
// MARK: CoreStoreSwiftType
|
||||||
@@ -96,5 +96,3 @@ extension SectionBy: CoreStoreSwiftType {
|
|||||||
return CSSectionBy(self)
|
return CSSectionBy(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
|||||||
select:[CSSelect objectIDForTerm:[CSSelectTerm objectIDAs:nil]]
|
select:[CSSelect objectIDForTerm:[CSSelectTerm objectIDAs:nil]]
|
||||||
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]];
|
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]];
|
||||||
```
|
```
|
||||||
- parameter keyPath: the attribute name
|
|
||||||
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "objecID" is used
|
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "objecID" is used
|
||||||
- returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute
|
- returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute
|
||||||
*/
|
*/
|
||||||
@@ -217,7 +216,7 @@ public final class CSSelect: NSObject {
|
|||||||
select:CSSelectNumber(CSAggregateMax(@"age"))
|
select:CSSelectNumber(CSAggregateMax(@"age"))
|
||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
- parameter numberTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||||
*/
|
*/
|
||||||
public convenience init(numberTerm: CSSelectTerm) {
|
public convenience init(numberTerm: CSSelectTerm) {
|
||||||
|
|
||||||
@@ -232,7 +231,7 @@ public final class CSSelect: NSObject {
|
|||||||
select:CSSelectDecimal(CSAggregateAverage(@"price"))
|
select:CSSelectDecimal(CSAggregateAverage(@"price"))
|
||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
- parameter decimalTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||||
*/
|
*/
|
||||||
public convenience init(decimalTerm: CSSelectTerm) {
|
public convenience init(decimalTerm: CSSelectTerm) {
|
||||||
|
|
||||||
@@ -247,7 +246,7 @@ public final class CSSelect: NSObject {
|
|||||||
select:CSSelectString(CSAttribute(@"fullname"))
|
select:CSSelectString(CSAttribute(@"fullname"))
|
||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
- parameter stringTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||||
*/
|
*/
|
||||||
public convenience init(stringTerm: CSSelectTerm) {
|
public convenience init(stringTerm: CSSelectTerm) {
|
||||||
|
|
||||||
@@ -262,7 +261,7 @@ public final class CSSelect: NSObject {
|
|||||||
select:CSSelectDate(CSAggregateMax(@"updatedDate"))
|
select:CSSelectDate(CSAggregateMax(@"updatedDate"))
|
||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
- parameter dateTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||||
*/
|
*/
|
||||||
public convenience init(dateTerm: CSSelectTerm) {
|
public convenience init(dateTerm: CSSelectTerm) {
|
||||||
|
|
||||||
@@ -277,7 +276,7 @@ public final class CSSelect: NSObject {
|
|||||||
select:CSSelectData(CSAttribute(@"imageData"))
|
select:CSSelectData(CSAttribute(@"imageData"))
|
||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
- parameter dataTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||||
*/
|
*/
|
||||||
public convenience init(dataTerm: CSSelectTerm) {
|
public convenience init(dataTerm: CSSelectTerm) {
|
||||||
|
|
||||||
@@ -292,7 +291,6 @@ public final class CSSelect: NSObject {
|
|||||||
select:CSSelectObjectID()
|
select:CSSelectObjectID()
|
||||||
// ...
|
// ...
|
||||||
```
|
```
|
||||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
|
||||||
*/
|
*/
|
||||||
public convenience init(objectIDTerm: ()) {
|
public convenience init(objectIDTerm: ()) {
|
||||||
|
|
||||||
@@ -359,9 +357,9 @@ public final class CSSelect: NSObject {
|
|||||||
|
|
||||||
// MARK: CoreStoreObjectiveCType
|
// MARK: CoreStoreObjectiveCType
|
||||||
|
|
||||||
public init<T: SelectValueResultType>(_ swiftValue: Select<T>) {
|
public init<T: QueryableAttributeType>(_ swiftValue: Select<T>) {
|
||||||
|
|
||||||
self.attributeType = T.attributeType
|
self.attributeType = T.cs_rawAttributeType
|
||||||
self.selectTerms = swiftValue.selectTerms
|
self.selectTerms = swiftValue.selectTerms
|
||||||
self.bridgeToSwift = swiftValue
|
self.bridgeToSwift = swiftValue
|
||||||
super.init()
|
super.init()
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public protocol CSStorageInterface {
|
|||||||
The configuration name in the model file
|
The configuration name in the model file
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
var configuration: String? { get }
|
var configuration: ModelConfiguration { get }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The options dictionary for the `NSPersistentStore`
|
The options dictionary for the `NSPersistentStore`
|
||||||
@@ -106,10 +106,10 @@ public protocol CSLocalStorage: CSStorageInterface {
|
|||||||
var fileURL: URL { get }
|
var fileURL: URL { get }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The `NSBundle`s from which to search mapping models for migrations
|
An array of `SchemaMappingProvider`s that provides the complete mapping models for custom migrations. This is currently only supported for Swift code.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
var mappingModelBundles: [Bundle] { get }
|
var migrationMappingProviders: [Any] { get }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Options that tell the `CSDataStack` how to setup the persistent store
|
Options that tell the `CSDataStack` how to setup the persistent store
|
||||||
@@ -121,5 +121,5 @@ public protocol CSLocalStorage: CSStorageInterface {
|
|||||||
Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (SQLite stores for example, can convert WAL journaling mode to DELETE before deleting)
|
Called by the `CSDataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (SQLite stores for example, can convert WAL journaling mode to DELETE before deleting)
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
func eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool
|
func cs_eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,34 +38,19 @@ import CoreData
|
|||||||
public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Saves the transaction changes and waits for completion synchronously. This method should not be used after the `-commitAndWait` method was already called once.
|
Saves the transaction changes and waits for completion synchronously. This method should not be used after the `-commitAndWaitWithError:` method was already called once.
|
||||||
|
|
||||||
- returns: a `CSSaveResult` containing the success or failure information
|
- parameter error: the `CSError` pointer that indicates the reason in case of an failure
|
||||||
|
- returns: `YES` if the commit succeeded, `NO` if the commit failed. If `NO`, the `error` argument will hold error information.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public func commitAndWait() -> CSSaveResult {
|
public func commitAndWait(error: NSErrorPointer) -> Bool {
|
||||||
|
|
||||||
return bridge {
|
return bridge(error) {
|
||||||
|
|
||||||
self.bridgeToSwift.commitAndWait()
|
if case (_, let error?) = self.bridgeToSwift.context.saveSynchronously(waitForMerge: true) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
throw error
|
||||||
Begins a child transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made. This method should not be used after the `-commitAndWait` method was already called once.
|
|
||||||
|
|
||||||
- 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
|
|
||||||
*/
|
|
||||||
@objc
|
|
||||||
@discardableResult
|
|
||||||
public func beginSynchronous(_ closure: @escaping (_ transaction: CSSynchronousDataTransaction) -> Void) -> CSSaveResult? {
|
|
||||||
|
|
||||||
return bridge {
|
|
||||||
|
|
||||||
self.bridgeToSwift.beginSynchronous { (transaction) in
|
|
||||||
|
|
||||||
closure(transaction.bridgeToObjectiveC)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,6 +143,33 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
|||||||
|
|
||||||
super.init(swiftValue as! SynchronousDataTransaction)
|
super.init(swiftValue as! SynchronousDataTransaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
115
Sources/CSUnsafeDataModelSchema.swift
Normal file
115
Sources/CSUnsafeDataModelSchema.swift
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// CSUnsafeDataModelSchema.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CSUnsafeDataModelSchema
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `CSUnsafeDataModelSchema` serves as the Objective-C bridging type for `UnsafeDataModelSchema`.
|
||||||
|
|
||||||
|
- SeeAlso: `UnsafeDataModelSchema`
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
public final class CSUnsafeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes a `CSUnsafeDataModelSchema` from an `NSManagedObjectModel`.
|
||||||
|
|
||||||
|
- parameter modelName: the model version, typically the file name of an *.xcdatamodeld file (without the file extension)
|
||||||
|
- parameter model: the `NSManagedObjectModel`
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
public required init(modelName: ModelVersion, model: NSManagedObjectModel) {
|
||||||
|
|
||||||
|
self.bridgeToSwift = UnsafeDataModelSchema(
|
||||||
|
modelName: modelName,
|
||||||
|
model: model
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: NSObject
|
||||||
|
|
||||||
|
public override var hash: Int {
|
||||||
|
|
||||||
|
return ObjectIdentifier(self.bridgeToSwift).hashValue
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func isEqual(_ object: Any?) -> Bool {
|
||||||
|
|
||||||
|
guard let object = object as? CSUnsafeDataModelSchema else {
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return self.bridgeToSwift === object.bridgeToSwift
|
||||||
|
}
|
||||||
|
|
||||||
|
public override var description: String {
|
||||||
|
|
||||||
|
return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CSDynamicSchema
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public var modelVersion: ModelVersion {
|
||||||
|
|
||||||
|
return self.bridgeToSwift.modelVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public func rawModel() -> NSManagedObjectModel {
|
||||||
|
|
||||||
|
return self.bridgeToSwift.rawModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CoreStoreObjectiveCType
|
||||||
|
|
||||||
|
public let bridgeToSwift: UnsafeDataModelSchema
|
||||||
|
|
||||||
|
public required init(_ swiftValue: UnsafeDataModelSchema) {
|
||||||
|
|
||||||
|
self.bridgeToSwift = swiftValue
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - UnsafeDataModelSchema
|
||||||
|
|
||||||
|
extension UnsafeDataModelSchema: CoreStoreSwiftType {
|
||||||
|
|
||||||
|
// MARK: CoreStoreSwiftType
|
||||||
|
|
||||||
|
public var bridgeToObjectiveC: CSUnsafeDataModelSchema {
|
||||||
|
|
||||||
|
return CSUnsafeDataModelSchema(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,32 +36,47 @@ import CoreData
|
|||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Saves the transaction changes asynchronously. For a `CSUnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread.
|
Saves the transaction changes asynchronously. For a `CSUnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread.
|
||||||
|
|
||||||
- parameter completion: the block executed after the save completes. Success or failure is reported by the `CSSaveResult` argument of the block.
|
- parameter success: the block executed if the save succeeds.
|
||||||
|
- parameter failure: the block executed if the save fails. A `CSError` is reported as the argument of the block.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public func commit(_ completion: ((_ result: CSSaveResult) -> Void)?) {
|
public func commitWithSuccess(_ success: (() -> Void)?, _ failure: ((CSError) -> Void)?) {
|
||||||
|
|
||||||
self.bridgeToSwift.commit { (result) in
|
self.bridgeToSwift.context.saveAsynchronouslyWithCompletion { (_, error) in
|
||||||
|
|
||||||
completion?(result.bridgeToObjectiveC)
|
defer {
|
||||||
|
|
||||||
|
withExtendedLifetime(self, {})
|
||||||
|
}
|
||||||
|
if let error = error {
|
||||||
|
|
||||||
|
failure?(error.bridgeToObjectiveC)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
success?()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Saves the transaction changes and waits for completion synchronously. For a `CSUnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread.
|
Saves the transaction changes and waits for completion synchronously. For a `CSUnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread.
|
||||||
|
|
||||||
- returns: a `CSSaveResult` containing the success or failure information
|
- parameter error: the `CSError` pointer that indicates the reason in case of an failure
|
||||||
|
- returns: `YES` if the commit succeeded, `NO` if the commit failed. If `NO`, the `error` argument will hold error information.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public func commitAndWait() -> CSSaveResult {
|
public func commitAndWait(error: NSErrorPointer) -> Bool {
|
||||||
|
|
||||||
return bridge {
|
return bridge(error) {
|
||||||
|
|
||||||
self.bridgeToSwift.commitAndWait()
|
if case (_, let error?) = self.bridgeToSwift.context.saveSynchronously(waitForMerge: true) {
|
||||||
|
|
||||||
|
throw error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +122,7 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
|||||||
Flushes all pending changes to the transaction's observers at the end of the `closure`'s execution. This is useful in conjunction with `ListMonitor`s and `ObjectMonitor`s created from `UnsafeDataTransaction`s used to manage temporary "scratch" data.
|
Flushes all pending changes to the transaction's observers at the end of the `closure`'s execution. This is useful in conjunction with `ListMonitor`s and `ObjectMonitor`s created from `UnsafeDataTransaction`s used to manage temporary "scratch" data.
|
||||||
|
|
||||||
- Important: Note that unlike `commit()`, `flush()` does not propagate/save updates to the `DataStack` and the persistent store. However, the flushed changes will be seen by children transactions created further from the current transaction (i.e. through `transaction.beginUnsafe()`)
|
- Important: Note that unlike `commit()`, `flush()` does not propagate/save updates to the `DataStack` and the persistent store. However, the flushed changes will be seen by children transactions created further from the current transaction (i.e. through `transaction.beginUnsafe()`)
|
||||||
- parameter closure: the closure where changes can be made prior to the flush
|
- parameter block: the block where changes can be made prior to the flush
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public func flush(_ block: () -> Void) {
|
public func flush(_ block: () -> Void) {
|
||||||
@@ -156,7 +171,7 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
|||||||
- that all saves will be done either through the `CSUnsafeDataTransaction`'s `-commit:` or `-commitAndWait` method, or by calling `-save:` manually on the context, its parent, and all other ancestor contexts if there are any.
|
- that all saves will be done either through the `CSUnsafeDataTransaction`'s `-commit:` or `-commitAndWait` method, or by calling `-save:` manually on the context, its parent, and all other ancestor contexts if there are any.
|
||||||
*/
|
*/
|
||||||
@objc
|
@objc
|
||||||
public var internalContext: NSManagedObjectContext {
|
public func unsafeContext() -> NSManagedObjectContext {
|
||||||
|
|
||||||
return self.bridgeToSwift.context
|
return self.bridgeToSwift.context
|
||||||
}
|
}
|
||||||
@@ -188,6 +203,51 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
|||||||
|
|
||||||
super.init(swiftValue as! UnsafeDataTransaction)
|
super.init(swiftValue as! UnsafeDataTransaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
115
Sources/CSXcodeDataModelSchema.swift
Normal file
115
Sources/CSXcodeDataModelSchema.swift
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// CSXcodeDataModelSchema.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CSXcodeDataModelSchema
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `CSXcodeDataModelSchema` serves as the Objective-C bridging type for `XcodeDataModelSchema`.
|
||||||
|
|
||||||
|
- SeeAlso: `XcodeDataModelSchema`
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
public final class CSXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes an `CSXcodeDataModelSchema` from an *.xcdatamodeld file URL.
|
||||||
|
|
||||||
|
- parameter modelName: the model version, typically the file name of an *.xcdatamodeld file (without the file extension)
|
||||||
|
- parameter modelVersionFileURL: the file URL that points to the .xcdatamodeld's "momd" file.
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
public required init(modelName: ModelVersion, modelVersionFileURL: URL) {
|
||||||
|
|
||||||
|
self.bridgeToSwift = XcodeDataModelSchema(
|
||||||
|
modelName: modelName,
|
||||||
|
modelVersionFileURL: modelVersionFileURL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: NSObject
|
||||||
|
|
||||||
|
public override var hash: Int {
|
||||||
|
|
||||||
|
return ObjectIdentifier(self.bridgeToSwift).hashValue
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func isEqual(_ object: Any?) -> Bool {
|
||||||
|
|
||||||
|
guard let object = object as? CSXcodeDataModelSchema else {
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return self.bridgeToSwift === object.bridgeToSwift
|
||||||
|
}
|
||||||
|
|
||||||
|
public override var description: String {
|
||||||
|
|
||||||
|
return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CSDynamicSchema
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public var modelVersion: ModelVersion {
|
||||||
|
|
||||||
|
return self.bridgeToSwift.modelVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public func rawModel() -> NSManagedObjectModel {
|
||||||
|
|
||||||
|
return self.bridgeToSwift.rawModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CoreStoreObjectiveCType
|
||||||
|
|
||||||
|
public let bridgeToSwift: XcodeDataModelSchema
|
||||||
|
|
||||||
|
public required init(_ swiftValue: XcodeDataModelSchema) {
|
||||||
|
|
||||||
|
self.bridgeToSwift = swiftValue
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - XcodeDataModelSchema
|
||||||
|
|
||||||
|
extension XcodeDataModelSchema: CoreStoreSwiftType {
|
||||||
|
|
||||||
|
// MARK: CoreStoreSwiftType
|
||||||
|
|
||||||
|
public var bridgeToObjectiveC: CSXcodeDataModelSchema {
|
||||||
|
|
||||||
|
return CSXcodeDataModelSchema(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,11 @@ import CoreData
|
|||||||
|
|
||||||
// MARK: - CoreDataNativeType
|
// MARK: - CoreDataNativeType
|
||||||
|
|
||||||
@objc public protocol CoreDataNativeType: class, NSObjectProtocol, AnyObject {}
|
/**
|
||||||
|
Objective-C Foundation types that are natively supported by Core Data managed attributes all conform to `CoreDataNativeType`.
|
||||||
|
*/
|
||||||
|
@objc
|
||||||
|
public protocol CoreDataNativeType: class, NSObjectProtocol, AnyObject {}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSNumber
|
// MARK: - NSNumber
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ extension AsynchronousDataTransaction: CustomDebugStringConvertible, CoreStoreDe
|
|||||||
("context", self.context),
|
("context", self.context),
|
||||||
("supportsUndo", self.supportsUndo),
|
("supportsUndo", self.supportsUndo),
|
||||||
("bypassesQueueing", self.bypassesQueueing),
|
("bypassesQueueing", self.bypassesQueueing),
|
||||||
("isCommitted", self.isCommitted),
|
("isCommitted", self.isCommitted)
|
||||||
("result", self.result as Any)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,6 +141,13 @@ extension CoreStoreError: CustomDebugStringConvertible, CoreStoreDebugStringConv
|
|||||||
case .internalError(let NSError):
|
case .internalError(let NSError):
|
||||||
firstLine = ".internalError"
|
firstLine = ".internalError"
|
||||||
info.append(("NSError", NSError))
|
info.append(("NSError", NSError))
|
||||||
|
|
||||||
|
case .userError(error: let error):
|
||||||
|
firstLine = ".userError"
|
||||||
|
info.append(("Error", error))
|
||||||
|
|
||||||
|
case .userCancelled:
|
||||||
|
firstLine = ".userCancelled"
|
||||||
}
|
}
|
||||||
|
|
||||||
return createFormattedString(
|
return createFormattedString(
|
||||||
@@ -152,6 +158,32 @@ extension CoreStoreError: CustomDebugStringConvertible, CoreStoreDebugStringConv
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CoreStoreSchema
|
||||||
|
|
||||||
|
extension CoreStoreSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
|
// MARK: CustomDebugStringConvertible
|
||||||
|
|
||||||
|
public var debugDescription: String {
|
||||||
|
|
||||||
|
return formattedDebugDescription(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CoreStoreDebugStringConvertible
|
||||||
|
|
||||||
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
|
return createFormattedString(
|
||||||
|
"(", ")",
|
||||||
|
("modelVersion", self.modelVersion),
|
||||||
|
("entitiesByConfiguration", self.entitiesByConfiguration),
|
||||||
|
("rawModel", self.rawModel())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - DataStack
|
// MARK: - DataStack
|
||||||
|
|
||||||
extension DataStack: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
extension DataStack: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
@@ -173,14 +205,40 @@ extension DataStack: CustomDebugStringConvertible, CoreStoreDebugStringConvertib
|
|||||||
("coordinator", self.coordinator),
|
("coordinator", self.coordinator),
|
||||||
("rootSavingContext", self.rootSavingContext),
|
("rootSavingContext", self.rootSavingContext),
|
||||||
("mainContext", self.mainContext),
|
("mainContext", self.mainContext),
|
||||||
("model", self.model),
|
("schemaHistory", self.schemaHistory),
|
||||||
("migrationChain", self.migrationChain),
|
|
||||||
("coordinator.persistentStores", self.coordinator.persistentStores)
|
("coordinator.persistentStores", self.coordinator.persistentStores)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - Entity
|
||||||
|
|
||||||
|
extension Entity: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
|
// MARK: CustomDebugStringConvertible
|
||||||
|
|
||||||
|
public var debugDescription: String {
|
||||||
|
|
||||||
|
return formattedDebugDescription(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CoreStoreDebugStringConvertible
|
||||||
|
|
||||||
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
|
return createFormattedString(
|
||||||
|
"(", ")",
|
||||||
|
("type", self.type),
|
||||||
|
("entityName", self.entityName),
|
||||||
|
("isAbstract", self.isAbstract),
|
||||||
|
("versionHashModifier", self.versionHashModifier as Any)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - From
|
// MARK: - From
|
||||||
|
|
||||||
extension From: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
extension From: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
@@ -316,9 +374,9 @@ extension Into: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - LegacySQLiteStore
|
// MARK: - UnsafeDataModelSchema
|
||||||
|
|
||||||
extension LegacySQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
extension UnsafeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
// MARK: CustomDebugStringConvertible
|
// MARK: CustomDebugStringConvertible
|
||||||
|
|
||||||
@@ -334,20 +392,16 @@ extension LegacySQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringC
|
|||||||
|
|
||||||
return createFormattedString(
|
return createFormattedString(
|
||||||
"(", ")",
|
"(", ")",
|
||||||
("configuration", self.configuration as Any),
|
("modelVersion", self.modelVersion),
|
||||||
("storeOptions", self.storeOptions as Any),
|
("rawModel", self.rawModel())
|
||||||
("fileURL", self.fileURL),
|
|
||||||
("mappingModelBundles", self.mappingModelBundles),
|
|
||||||
("localStorageOptions", self.localStorageOptions)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - ListMonitor
|
// MARK: - ListMonitor
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertible {
|
private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
let sectionInfo: NSFetchedResultsSectionInfo
|
let sectionInfo: NSFetchedResultsSectionInfo
|
||||||
@@ -362,6 +416,7 @@ private struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConvertib
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
extension ListMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
extension ListMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
// MARK: CustomDebugStringConvertible
|
// MARK: CustomDebugStringConvertible
|
||||||
@@ -384,7 +439,6 @@ extension ListMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvert
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - LocalStorageOptions
|
// MARK: - LocalStorageOptions
|
||||||
@@ -451,7 +505,7 @@ extension MigrationChain: CustomDebugStringConvertible, CoreStoreDebugStringConv
|
|||||||
|
|
||||||
public var coreStoreDumpString: String {
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
guard self.valid else {
|
guard self.isValid else {
|
||||||
|
|
||||||
return "<invalid migration chain>"
|
return "<invalid migration chain>"
|
||||||
}
|
}
|
||||||
@@ -554,10 +608,9 @@ extension MigrationType: CustomDebugStringConvertible, CoreStoreDebugStringConve
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - ObjectMonitor
|
// MARK: - ObjectMonitor
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
extension ObjectMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
extension ObjectMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
// MARK: CustomDebugStringConvertible
|
// MARK: CustomDebugStringConvertible
|
||||||
@@ -579,7 +632,7 @@ extension ObjectMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConve
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// MARK: - OrderBy
|
// MARK: - OrderBy
|
||||||
|
|
||||||
@@ -607,6 +660,7 @@ extension OrderBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertible
|
|||||||
|
|
||||||
// MARK: - SaveResult
|
// MARK: - SaveResult
|
||||||
|
|
||||||
|
@available(*, deprecated, message: "Use the new DataStack.perform(asynchronous:...) and DataStack.perform(synchronous:...) family of APIs")
|
||||||
extension SaveResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
extension SaveResult: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
// MARK: CustomDebugStringConvertible
|
// MARK: CustomDebugStringConvertible
|
||||||
@@ -639,10 +693,9 @@ extension SaveResult: CustomDebugStringConvertible, CoreStoreDebugStringConverti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - SectionBy
|
// MARK: - SectionBy
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
extension SectionBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
extension SectionBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
// MARK: CustomDebugStringConvertible
|
// MARK: CustomDebugStringConvertible
|
||||||
@@ -663,7 +716,32 @@ extension SectionBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertib
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// MARK: - SchemaHistory
|
||||||
|
|
||||||
|
extension SchemaHistory: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
|
// MARK: CustomDebugStringConvertible
|
||||||
|
|
||||||
|
public var debugDescription: String {
|
||||||
|
|
||||||
|
return formattedDebugDescription(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CoreStoreDebugStringConvertible
|
||||||
|
|
||||||
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
|
return createFormattedString(
|
||||||
|
"(", ")",
|
||||||
|
("currentModelVersion", self.currentModelVersion),
|
||||||
|
("migrationChain", self.migrationChain),
|
||||||
|
("schemaByVersion", self.schemaByVersion)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Select
|
// MARK: - Select
|
||||||
@@ -789,7 +867,7 @@ extension SQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringConvert
|
|||||||
("configuration", self.configuration as Any),
|
("configuration", self.configuration as Any),
|
||||||
("storeOptions", self.storeOptions as Any),
|
("storeOptions", self.storeOptions as Any),
|
||||||
("fileURL", self.fileURL),
|
("fileURL", self.fileURL),
|
||||||
("mappingModelBundles", self.mappingModelBundles),
|
("migrationMappingProviders", self.migrationMappingProviders),
|
||||||
("localStorageOptions", self.localStorageOptions)
|
("localStorageOptions", self.localStorageOptions)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -817,8 +895,7 @@ extension SynchronousDataTransaction: CustomDebugStringConvertible, CoreStoreDeb
|
|||||||
("context", self.context),
|
("context", self.context),
|
||||||
("supportsUndo", self.supportsUndo),
|
("supportsUndo", self.supportsUndo),
|
||||||
("bypassesQueueing", self.bypassesQueueing),
|
("bypassesQueueing", self.bypassesQueueing),
|
||||||
("isCommitted", self.isCommitted),
|
("isCommitted", self.isCommitted)
|
||||||
("result", self.result as Any)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -894,6 +971,80 @@ extension Where: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - VersionLock
|
||||||
|
|
||||||
|
extension VersionLock: CustomStringConvertible, CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
|
// MARK: CustomStringConvertible
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
|
||||||
|
var string = "["
|
||||||
|
if self.hashesByEntityName.isEmpty {
|
||||||
|
|
||||||
|
string.append(":]")
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
|
return (0 ..< (count / MemoryLayout<HashElement>.size))
|
||||||
|
.map({ "\("0x\(String(pointer[$0], radix: 16, uppercase: false))")" })
|
||||||
|
}
|
||||||
|
string.append("\(index == 0 ? "\n" : ",\n")\"\(keyValue.key)\": [\(bytes.joined(separator: ", "))]")
|
||||||
|
}
|
||||||
|
string.indent(1)
|
||||||
|
string.append("\n]")
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CustomDebugStringConvertible
|
||||||
|
|
||||||
|
public var debugDescription: String {
|
||||||
|
|
||||||
|
return formattedDebugDescription(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CoreStoreDebugStringConvertible
|
||||||
|
|
||||||
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
|
return self.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - XcodeDataModelSchema
|
||||||
|
|
||||||
|
extension XcodeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
|
// MARK: CustomDebugStringConvertible
|
||||||
|
|
||||||
|
public var debugDescription: String {
|
||||||
|
|
||||||
|
return formattedDebugDescription(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: CoreStoreDebugStringConvertible
|
||||||
|
|
||||||
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
|
return createFormattedString(
|
||||||
|
"(", ")",
|
||||||
|
("modelVersion", self.modelVersion),
|
||||||
|
("modelVersionFileURL", self.modelVersionFileURL),
|
||||||
|
("rawModel", self.rawModel())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Private: Utilities
|
// MARK: - Private: Utilities
|
||||||
|
|
||||||
private typealias DumpInfo = [(key: String, value: Any)]
|
private typealias DumpInfo = [(key: String, value: Any)]
|
||||||
@@ -970,7 +1121,7 @@ public protocol CoreStoreDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Private:
|
// MARK: - Standard Types:
|
||||||
|
|
||||||
extension Array: CoreStoreDebugStringConvertible {
|
extension Array: CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
@@ -1212,7 +1363,15 @@ extension NSSortDescriptor: CoreStoreDebugStringConvertible {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension URL: CoreStoreDebugStringConvertible {
|
extension NSString: CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
|
return "\"\(self)\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NSURL: CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
public var coreStoreDumpString: String {
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
@@ -1247,3 +1406,11 @@ extension String: CoreStoreDebugStringConvertible {
|
|||||||
return "\"\(self)\""
|
return "\"\(self)\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension URL: CoreStoreDebugStringConvertible {
|
||||||
|
|
||||||
|
public var coreStoreDumpString: String {
|
||||||
|
|
||||||
|
return "\"\(self)\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public extension CoreStore {
|
|||||||
|
|
||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
|
@inline(__always)
|
||||||
internal static func log(_ level: LogLevel, message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
|
internal static func log(_ level: LogLevel, message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
|
||||||
|
|
||||||
self.logger.log(
|
self.logger.log(
|
||||||
@@ -49,6 +50,7 @@ public extension CoreStore {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inline(__always)
|
||||||
internal static func log(_ error: CoreStoreError, _ message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
|
internal static func log(_ error: CoreStoreError, _ message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
|
||||||
|
|
||||||
self.logger.log(
|
self.logger.log(
|
||||||
@@ -60,7 +62,8 @@ public extension CoreStore {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static func assert( _ condition: @autoclosure () -> Bool, _ message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
|
@inline(__always)
|
||||||
|
internal static func assert( _ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
|
||||||
|
|
||||||
self.logger.assert(
|
self.logger.assert(
|
||||||
condition,
|
condition,
|
||||||
@@ -71,6 +74,7 @@ public extension CoreStore {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inline(__always)
|
||||||
internal static func abort(_ message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) -> Never {
|
internal static func abort(_ message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) -> Never {
|
||||||
|
|
||||||
self.logger.abort(
|
self.logger.abort(
|
||||||
|
|||||||
@@ -31,27 +31,6 @@ import CoreData
|
|||||||
|
|
||||||
public extension CoreStore {
|
public extension CoreStore {
|
||||||
|
|
||||||
/**
|
|
||||||
Asynchronously adds a `StorageInterface` with default settings to the `defaultStack`. Migrations are also initiated by default.
|
|
||||||
```
|
|
||||||
CoreStore.addStorage(
|
|
||||||
InMemoryStore.self,
|
|
||||||
completion: { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let storage): // ...
|
|
||||||
case .failure(let error): // ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
- parameter storeType: the storage type
|
|
||||||
- parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `SetupResult` argument indicates the result. Note that the `StorageInterface` associated to the `SetupResult.success` may not always be the same instance as the parameter argument if a previous `StorageInterface` was already added at the same URL and with the same configuration.
|
|
||||||
*/
|
|
||||||
public static func addStorage<T: StorageInterface>(_ storeType: T.Type, completion: @escaping (SetupResult<T>) -> Void) where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
self.defaultStack.addStorage(storeType.init(), completion: completion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously adds a `StorageInterface` to the `defaultStack`. Migrations are also initiated by default.
|
Asynchronously adds a `StorageInterface` to the `defaultStack`. Migrations are also initiated by default.
|
||||||
```
|
```
|
||||||
@@ -73,28 +52,6 @@ public extension CoreStore {
|
|||||||
self.defaultStack.addStorage(storage, completion: completion)
|
self.defaultStack.addStorage(storage, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Asynchronously adds a `LocalStorage` with default settings to the `defaultStack`. Migrations are also initiated by default.
|
|
||||||
```
|
|
||||||
let migrationProgress = CoreStore.addStorage(
|
|
||||||
SQLiteStore.self,
|
|
||||||
completion: { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let storage): // ...
|
|
||||||
case .failure(let error): // ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
- parameter storeType: the local storage type
|
|
||||||
- parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `SetupResult` argument indicates the result. Note that the `LocalStorage` associated to the `SetupResult.success` may not always be the same instance as the parameter argument if a previous `LocalStorage` was already added at the same URL and with the same configuration.
|
|
||||||
- returns: a `Progress` instance if a migration has started, or `nil` if either no migrations are required or if a failure occured.
|
|
||||||
*/
|
|
||||||
public static func addStorage<T: LocalStorage>(_ storeType: T.Type, completion: @escaping (SetupResult<T>) -> Void) -> Progress? where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
return self.defaultStack.addStorage(storeType.init(), completion: completion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously adds a `LocalStorage` to the `defaultStack`. Migrations are also initiated by default.
|
Asynchronously adds a `LocalStorage` to the `defaultStack`. Migrations are also initiated by default.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -27,122 +27,119 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CoreStore
|
// MARK: - CoreStore
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
public extension CoreStore {
|
public extension CoreStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, creates an `ObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
|
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`.
|
||||||
|
|
||||||
- parameter object: the `NSManagedObject` to observe changes from
|
- parameter object: the `DynamicObject` to observe changes from
|
||||||
- returns: a `ObjectMonitor` that monitors changes to `object`
|
- returns: a `ObjectMonitor` that monitors changes to `object`
|
||||||
*/
|
*/
|
||||||
public static func monitorObject<T: NSManagedObject>(_ object: T) -> ObjectMonitor<T> {
|
public static func monitorObject<T: DynamicObject>(_ object: T) -> ObjectMonitor<T> {
|
||||||
|
|
||||||
return self.defaultStack.monitorObject(object)
|
return self.defaultStack.monitorObject(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Using the `defaultStack`, creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public static func monitorList<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
public static func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||||
|
|
||||||
return self.defaultStack.monitorList(from, fetchClauses)
|
return self.defaultStack.monitorList(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Using the `defaultStack`, creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public static func monitorList<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
public static func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||||
|
|
||||||
return self.defaultStack.monitorList(from, fetchClauses)
|
return self.defaultStack.monitorList(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public static func monitorList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
public static func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||||
|
|
||||||
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public static func monitorList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
public static func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||||
|
|
||||||
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Using the `defaultStack`, creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public static func monitorSectionedList<T: NSManagedObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
public static func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||||
|
|
||||||
return self.defaultStack.monitorSectionedList(from, sectionBy, fetchClauses)
|
return self.defaultStack.monitorSectionedList(from, sectionBy, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Using the `defaultStack`, creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public static func monitorSectionedList<T: NSManagedObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
public static func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||||
|
|
||||||
return self.defaultStack.monitorSectionedList(from, sectionBy, fetchClauses)
|
return self.defaultStack.monitorSectionedList(from, sectionBy, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public static func monitorSectionedList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
public static func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||||
|
|
||||||
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public static func monitorSectionedList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
public static func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||||
|
|
||||||
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -32,165 +32,165 @@ import CoreData
|
|||||||
public extension CoreStore {
|
public extension CoreStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.
|
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.
|
||||||
|
|
||||||
- parameter object: a reference to the object created/fetched outside the `DataStack`
|
- parameter object: a reference to the object created/fetched outside the `DataStack`
|
||||||
- returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||||
*/
|
*/
|
||||||
public static func fetchExisting<T: NSManagedObject>(_ object: T) -> T? {
|
public static func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
|
||||||
|
|
||||||
return self.defaultStack.fetchExisting(object)
|
return self.defaultStack.fetchExisting(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObject` instance in the `DataStack`'s context from an `NSManagedObjectID`.
|
Using the `defaultStack`, fetches the `DynamicObject` instance in the `DataStack`'s context from an `NSManagedObjectID`.
|
||||||
|
|
||||||
- parameter objectID: the `NSManagedObjectID` for the object
|
- parameter objectID: the `NSManagedObjectID` for the object
|
||||||
- returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||||
*/
|
*/
|
||||||
public static func fetchExisting<T: NSManagedObject>(_ objectID: NSManagedObjectID) -> T? {
|
public static func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||||
|
|
||||||
return self.defaultStack.fetchExisting(objectID)
|
return self.defaultStack.fetchExisting(objectID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObject` instances in the `DataStack`'s context from references created from a transaction or from a different managed object context.
|
Using the `defaultStack`, fetches the `DynamicObject` instances in the `DataStack`'s context from references created from a transaction or from a different managed object context.
|
||||||
|
|
||||||
- parameter objects: an array of `NSManagedObject`s created/fetched outside the `DataStack`
|
- parameter objects: an array of `DynamicObject`s created/fetched outside the `DataStack`
|
||||||
- returns: the `NSManagedObject` array for objects that exists in the `DataStack`
|
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||||
*/
|
*/
|
||||||
public static func fetchExisting<T: NSManagedObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
public static func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||||
|
|
||||||
return self.defaultStack.fetchExisting(objects)
|
return self.defaultStack.fetchExisting(objects)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObject` instances in the `DataStack`'s context from a list of `NSManagedObjectID`.
|
Using the `defaultStack`, fetches the `DynamicObject` instances in the `DataStack`'s context from a list of `NSManagedObjectID`.
|
||||||
|
|
||||||
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
||||||
- returns: the `NSManagedObject` array for objects that exists in the `DataStack`
|
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||||
*/
|
*/
|
||||||
public static func fetchExisting<T: NSManagedObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
public static func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||||
|
|
||||||
return self.defaultStack.fetchExisting(objectIDs)
|
return self.defaultStack.fetchExisting(objectIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the first `DynamicObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s
|
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
public static func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||||
|
|
||||||
return self.defaultStack.fetchOne(from, fetchClauses)
|
return self.defaultStack.fetchOne(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the first `DynamicObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s
|
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
public static func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||||
|
|
||||||
return self.defaultStack.fetchOne(from, fetchClauses)
|
return self.defaultStack.fetchOne(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s
|
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
public static func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||||
|
|
||||||
return self.defaultStack.fetchAll(from, fetchClauses)
|
return self.defaultStack.fetchAll(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s
|
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
public static func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||||
|
|
||||||
return self.defaultStack.fetchAll(from, fetchClauses)
|
return self.defaultStack.fetchAll(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
public static func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||||
|
|
||||||
return self.defaultStack.fetchCount(from, fetchClauses)
|
return self.defaultStack.fetchCount(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
public static func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||||
|
|
||||||
return self.defaultStack.fetchCount(from, fetchClauses)
|
return self.defaultStack.fetchCount(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
public static func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||||
|
|
||||||
return self.defaultStack.fetchObjectID(from, fetchClauses)
|
return self.defaultStack.fetchObjectID(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
public static func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||||
|
|
||||||
return self.defaultStack.fetchObjectID(from, fetchClauses)
|
return self.defaultStack.fetchObjectID(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
public static func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||||
|
|
||||||
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
|
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Using the `defaultStack`, fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public static func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
public static func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||||
|
|
||||||
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
|
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
|
||||||
}
|
}
|
||||||
@@ -205,7 +205,7 @@ public extension CoreStore {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public static func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
public static func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||||
|
|
||||||
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,7 @@ public extension CoreStore {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public static func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
public static func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||||
|
|
||||||
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,7 @@ public extension CoreStore {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public static func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
public static func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||||
|
|
||||||
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ public extension CoreStore {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public static func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
public static func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||||
|
|
||||||
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import CoreData
|
|||||||
public extension CoreStore {
|
public extension CoreStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the `defaultStack`'s model version. The version string is the same as the name of the version-specific .xcdatamodeld file.
|
Returns the `defaultStack`'s model version. The version string is the same as the name of a version-specific .xcdatamodeld file or `CoreStoreSchema`.
|
||||||
*/
|
*/
|
||||||
public static var modelVersion: String {
|
public static var modelVersion: String {
|
||||||
|
|
||||||
@@ -42,9 +42,17 @@ public extension CoreStore {
|
|||||||
/**
|
/**
|
||||||
Returns the entity name-to-class type mapping from the `defaultStack`'s model.
|
Returns the entity name-to-class type mapping from the `defaultStack`'s model.
|
||||||
*/
|
*/
|
||||||
public static var entityTypesByName: [String: NSManagedObject.Type] {
|
public static func entityTypesByName(for type: NSManagedObject.Type) -> [EntityName: NSManagedObject.Type] {
|
||||||
|
|
||||||
return self.defaultStack.entityTypesByName
|
return self.defaultStack.entityTypesByName(for: type)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the entity name-to-class type mapping from the `defaultStack`'s model.
|
||||||
|
*/
|
||||||
|
public static func entityTypesByName(for type: CoreStoreObject.Type) -> [EntityName: CoreStoreObject.Type] {
|
||||||
|
|
||||||
|
return self.defaultStack.entityTypesByName(for: type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,6 +63,14 @@ public extension CoreStore {
|
|||||||
return self.defaultStack.entityDescription(for: type)
|
return self.defaultStack.entityDescription(for: type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the `NSEntityDescription` for the specified `CoreStoreObject` subclass from `defaultStack`'s model.
|
||||||
|
*/
|
||||||
|
public static func entityDescription(for type: CoreStoreObject.Type) -> NSEntityDescription? {
|
||||||
|
|
||||||
|
return self.defaultStack.entityDescription(for: type)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates an `SQLiteStore` with default parameters and adds it to the `defaultStack`. This method blocks until completion.
|
Creates an `SQLiteStore` with default parameters and adds it to the `defaultStack`. This method blocks until completion.
|
||||||
```
|
```
|
||||||
@@ -65,22 +81,7 @@ public extension CoreStore {
|
|||||||
@discardableResult
|
@discardableResult
|
||||||
public static func addStorageAndWait() throws -> SQLiteStore {
|
public static func addStorageAndWait() throws -> SQLiteStore {
|
||||||
|
|
||||||
return try self.defaultStack.addStorageAndWait(SQLiteStore.self)
|
return try self.defaultStack.addStorageAndWait(SQLiteStore())
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Creates a `StorageInterface` of the specified store type with default values and adds it to the `defaultStack`. This method blocks until completion.
|
|
||||||
```
|
|
||||||
try CoreStore.addStorageAndWait(InMemoryStore.self)
|
|
||||||
```
|
|
||||||
- parameter storeType: the `StorageInterface` type
|
|
||||||
- throws: a `CoreStoreError` value indicating the failure
|
|
||||||
- returns: the `StorageInterface` added to the `defaultStack`
|
|
||||||
*/
|
|
||||||
@discardableResult
|
|
||||||
public static func addStorageAndWait<T: StorageInterface>(_ storeType: T.Type) throws -> T where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
return try self.defaultStack.addStorageAndWait(storeType.init())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,21 +99,6 @@ public extension CoreStore {
|
|||||||
return try self.defaultStack.addStorageAndWait(storage)
|
return try self.defaultStack.addStorageAndWait(storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Creates a `LocalStorageInterface` of the specified store type with default values and adds it to the `defaultStack`. This method blocks until completion.
|
|
||||||
```
|
|
||||||
try CoreStore.addStorageAndWait(SQLiteStore.self)
|
|
||||||
```
|
|
||||||
- parameter storeType: the `LocalStorageInterface` type
|
|
||||||
- throws: a `CoreStoreError` value indicating the failure
|
|
||||||
- returns: the local storage added to the `defaultStack`
|
|
||||||
*/
|
|
||||||
@discardableResult
|
|
||||||
public static func addStorageAndWait<T: LocalStorage>(_ storageType: T.Type) throws -> T where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
return try self.defaultStack.addStorageAndWait(storageType.init())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds a `LocalStorage` to the `defaultStack` and blocks until completion.
|
Adds a `LocalStorage` to the `defaultStack` and blocks until completion.
|
||||||
```
|
```
|
||||||
@@ -157,10 +143,16 @@ public extension CoreStore {
|
|||||||
|
|
||||||
// MARK: Deprecated
|
// MARK: Deprecated
|
||||||
|
|
||||||
/**
|
@available(*, deprecated, message: "Use the new CoreStore.entityTypesByName(for:) method passing `NSManagedObject.self` as argument.")
|
||||||
Returns the `NSEntityDescription` for the specified `NSManagedObject` subclass from `defaultStack`'s model.
|
public static var entityTypesByName: [EntityName: NSManagedObject.Type] {
|
||||||
*/
|
|
||||||
@available(*, deprecated: 3.0.0, renamed: "entityDescription(for:)")
|
return self.defaultStack.entityTypesByName
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Obsolete
|
||||||
|
|
||||||
|
@available(*, obsoleted: 3.1, renamed: "entityDescription(for:)")
|
||||||
public static func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
|
public static func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
|
||||||
|
|
||||||
return self.entityDescription(for: type)
|
return self.entityDescription(for: type)
|
||||||
|
|||||||
@@ -31,29 +31,43 @@ import Foundation
|
|||||||
public extension CoreStore {
|
public extension CoreStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
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`.
|
||||||
|
|
||||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
- parameter 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)`.
|
||||||
*/
|
*/
|
||||||
public static func beginAsynchronous(_ closure: @escaping (_ transaction: AsynchronousDataTransaction) -> Void) {
|
public static func perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, completion: @escaping (AsynchronousDataTransaction.Result<T>) -> Void) {
|
||||||
|
|
||||||
self.defaultStack.beginAsynchronous(closure)
|
self.defaultStack.perform(asynchronous: task, completion: completion)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
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 argument of the `success` closure. Any errors thrown from inside the `task` will be wrapped in a `CoreStoreError` and reported in the `failure` closure. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||||
|
|
||||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
- parameter 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`.
|
||||||
- returns: a `SaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
- parameter success: the closure executed after the save succeeds. The `T` argument of the closure will be the value returned from `task`.
|
||||||
|
- parameter failure: the closure executed if the save fails or if any errors are thrown within `task`. Cancelled `task`s will be indicated by `CoreStoreError.userCancelled`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
public static func perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, success: @escaping (T) -> Void, failure: @escaping (CoreStoreError) -> Void) {
|
||||||
public static func beginSynchronous(_ closure: @escaping (_ transaction: SynchronousDataTransaction) -> Void) -> SaveResult? {
|
|
||||||
|
|
||||||
return self.defaultStack.beginSynchronous(closure)
|
self.defaultStack.perform(asynchronous: task, success: success, failure: failure)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Using the `defaultStack`, begins a non-contiguous transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms. An unsafe transaction object should typically be only used from the main queue.
|
Using the `defaultStack`, performs a transaction synchronously 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 return value of `perform(synchronous:)`. Any errors thrown from inside the `task` will be rethrown from `perform(synchronous:)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||||
|
|
||||||
|
- parameter task: the synchronous non-escaping 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 waitForAllObservers: When `true`, this method waits for all observers to be notified of the changes before returning. This results in more predictable data update order, but may risk triggering deadlocks. When `false`, this method does not wait for observers to be notified of the changes before returning. This results in lower risk for deadlocks, but the updated data may not have been propagated to the `DataStack` after returning. Defaults to `true`.
|
||||||
|
- throws: a `CoreStoreError` value indicating the failure. Cancelled `task`s will be indicated by `CoreStoreError.userCancelled`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||||
|
- returns: the value returned from `task`
|
||||||
|
*/
|
||||||
|
public static func perform<T>(synchronous task: ((_ transaction: SynchronousDataTransaction) throws -> T), waitForAllObservers: Bool = true) throws -> T {
|
||||||
|
|
||||||
|
return try self.defaultStack.perform(synchronous: task, waitForAllObservers: waitForAllObservers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Using the `defaultStack`, begins a non-contiguous transaction where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms.
|
||||||
|
|
||||||
- prameter supportsUndo: `undo()`, `redo()`, and `rollback()` methods are only available when this parameter is `true`, otherwise those method will raise an exception. Defaults to `false`. Note that turning on Undo support may heavily impact performance especially on iOS or watchOS where memory is limited.
|
- prameter supportsUndo: `undo()`, `redo()`, and `rollback()` methods are only available when this parameter is `true`, otherwise those method will raise an exception. Defaults to `false`. Note that turning on Undo support may heavily impact performance especially on iOS or watchOS where memory is limited.
|
||||||
- returns: a `UnsafeDataTransaction` instance where creates, updates, and deletes can be made.
|
- returns: a `UnsafeDataTransaction` instance where creates, updates, and deletes can be made.
|
||||||
@@ -64,10 +78,26 @@ public extension CoreStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Refreshes all registered objects `NSManagedObject`s in the `defaultStack`.
|
Refreshes all registered objects `NSManagedObject`s or `CoreStoreObject`s in the `defaultStack`.
|
||||||
*/
|
*/
|
||||||
public static func refreshAndMergeAllObjects() {
|
public static func refreshAndMergeAllObjects() {
|
||||||
|
|
||||||
self.defaultStack.refreshAndMergeAllObjects()
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray<id> *_Nonnull c
|
|||||||
@abstract
|
@abstract
|
||||||
Initializes a <tt>CSGroupBy</tt> clause with a key path string
|
Initializes a <tt>CSGroupBy</tt> clause with a key path string
|
||||||
|
|
||||||
@param keyPaths
|
@param keyPath
|
||||||
a key path string to group results with
|
a key path string to group results with
|
||||||
|
|
||||||
@result
|
@result
|
||||||
@@ -169,7 +169,7 @@ CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CORESTORE_RETUR
|
|||||||
@abstract
|
@abstract
|
||||||
Initializes a <tt>CSGroupBy</tt> clause with a list of key path strings
|
Initializes a <tt>CSGroupBy</tt> clause with a list of key path strings
|
||||||
|
|
||||||
@param keyPaths
|
@param keyPath
|
||||||
a nil-terminated list of key path strings to group results with
|
a nil-terminated list of key path strings to group results with
|
||||||
|
|
||||||
@result
|
@result
|
||||||
@@ -328,7 +328,7 @@ CSOrderBy *_Nonnull CSOrderByKey(NSSortDescriptor *_Nonnull sortDescriptor) CORE
|
|||||||
fetchClauses:@[CSOrderByKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]];
|
fetchClauses:@[CSOrderByKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]];
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
@param sortDescriptors
|
@param sortDescriptor
|
||||||
a nil-terminated array of <tt>NSSortDescriptor</tt>s
|
a nil-terminated array of <tt>NSSortDescriptor</tt>s
|
||||||
|
|
||||||
@result
|
@result
|
||||||
@@ -473,9 +473,6 @@ CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RET
|
|||||||
// ...
|
// ...
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
@param selectTerm
|
|
||||||
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
|
|
||||||
|
|
||||||
@result
|
@result
|
||||||
a <tt>CSSelect</tt> clause for querying an <tt>NSManagedObjectID</tt> value
|
a <tt>CSSelect</tt> clause for querying an <tt>NSManagedObjectID</tt> value
|
||||||
*/
|
*/
|
||||||
@@ -538,10 +535,7 @@ CSWhere *_Nonnull CSWhereValue(BOOL value) CORESTORE_RETURNS_RETAINED;
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
@param format
|
@param format
|
||||||
the format string for the predicate
|
the format string for the predicate, followed by an optional comma-separated argument list
|
||||||
|
|
||||||
@param argumentArray
|
|
||||||
the arguments for <tt>format</tt>
|
|
||||||
|
|
||||||
@result
|
@result
|
||||||
a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments
|
a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ internal func bridge<T: CoreStoreSwiftType>(_ closure: () -> T) -> T.ObjectiveCT
|
|||||||
return closure().bridgeToObjectiveC
|
return closure().bridgeToObjectiveC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal func bridge<T: CoreStoreSwiftType>(_ closure: () -> [T]) -> [T.ObjectiveCType] {
|
||||||
|
|
||||||
|
return closure().map { $0.bridgeToObjectiveC }
|
||||||
|
}
|
||||||
|
|
||||||
internal func bridge<T: CoreStoreSwiftType>(_ closure: () -> T?) -> T.ObjectiveCType? {
|
internal func bridge<T: CoreStoreSwiftType>(_ closure: () -> T?) -> T.ObjectiveCType? {
|
||||||
|
|
||||||
return closure()?.bridgeToObjectiveC
|
return closure()?.bridgeToObjectiveC
|
||||||
|
|||||||
@@ -59,6 +59,16 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
|
|||||||
*/
|
*/
|
||||||
case internalError(NSError: NSError)
|
case internalError(NSError: NSError)
|
||||||
|
|
||||||
|
/**
|
||||||
|
The transaction was terminated by a user-thrown `Error`.
|
||||||
|
*/
|
||||||
|
case userError(error: Error)
|
||||||
|
|
||||||
|
/**
|
||||||
|
The transaction was cancelled by the user.
|
||||||
|
*/
|
||||||
|
case userCancelled
|
||||||
|
|
||||||
|
|
||||||
// MARK: CustomNSError
|
// MARK: CustomNSError
|
||||||
|
|
||||||
@@ -85,6 +95,12 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
|
|||||||
|
|
||||||
case .internalError:
|
case .internalError:
|
||||||
return CoreStoreErrorCode.internalError.rawValue
|
return CoreStoreErrorCode.internalError.rawValue
|
||||||
|
|
||||||
|
case .userError:
|
||||||
|
return CoreStoreErrorCode.userError.rawValue
|
||||||
|
|
||||||
|
case .userCancelled:
|
||||||
|
return CoreStoreErrorCode.userCancelled.rawValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +128,18 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
|
|||||||
"localStoreURL": localStoreURL
|
"localStoreURL": localStoreURL
|
||||||
]
|
]
|
||||||
|
|
||||||
case .internalError(let NSError):
|
case .internalError(let nsError):
|
||||||
return [
|
return [
|
||||||
"NSError": NSError
|
"NSError": nsError
|
||||||
]
|
]
|
||||||
|
|
||||||
|
case .userError(let error):
|
||||||
|
return [
|
||||||
|
"Error": error
|
||||||
|
]
|
||||||
|
|
||||||
|
case .userCancelled:
|
||||||
|
return [:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +163,23 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
|
|||||||
return url1 == url2
|
return url1 == url2
|
||||||
|
|
||||||
case (.internalError(let NSError1), .internalError(let NSError2)):
|
case (.internalError(let NSError1), .internalError(let NSError2)):
|
||||||
return NSError1 == NSError2
|
return NSError1.isEqual(NSError2)
|
||||||
|
|
||||||
|
case (.userError(let error1), .userError(let error2)):
|
||||||
|
switch (error1, error2) {
|
||||||
|
|
||||||
|
case (let error1 as AnyHashable, let error2 as AnyHashable):
|
||||||
|
return error1 == error2
|
||||||
|
|
||||||
|
case (let error1 as NSError, let error2 as NSError):
|
||||||
|
return error1.isEqual(error2)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false // shouldn't happen
|
||||||
|
}
|
||||||
|
|
||||||
|
case (.userCancelled, .userCancelled):
|
||||||
|
return true
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
@@ -166,8 +206,14 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
|
|||||||
case .progressiveMigrationRequired(let localStoreURL):
|
case .progressiveMigrationRequired(let localStoreURL):
|
||||||
return code.hashValue ^ localStoreURL.hashValue
|
return code.hashValue ^ localStoreURL.hashValue
|
||||||
|
|
||||||
case .internalError(let NSError):
|
case .internalError(let nsError):
|
||||||
return code.hashValue ^ NSError.hashValue
|
return code.hashValue ^ nsError.hashValue
|
||||||
|
|
||||||
|
case .userError(let error):
|
||||||
|
return code.hashValue ^ (error as NSError).hashValue
|
||||||
|
|
||||||
|
case .userCancelled:
|
||||||
|
return code.hashValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +222,7 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
|
|||||||
|
|
||||||
internal init(_ error: Error?) {
|
internal init(_ error: Error?) {
|
||||||
|
|
||||||
self = error.flatMap { $0.bridgeToSwift } ?? .unknown
|
self = error.flatMap({ $0.bridgeToSwift }) ?? .unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +267,16 @@ public enum CoreStoreErrorCode: Int {
|
|||||||
An internal SDK call failed with the specified "NSError" userInfo key.
|
An internal SDK call failed with the specified "NSError" userInfo key.
|
||||||
*/
|
*/
|
||||||
case internalError
|
case internalError
|
||||||
|
|
||||||
|
/**
|
||||||
|
The transaction was terminated by a user-thrown `Error` specified by "Error" userInfo key.
|
||||||
|
*/
|
||||||
|
case userError
|
||||||
|
|
||||||
|
/**
|
||||||
|
The transaction was cancelled by the user.
|
||||||
|
*/
|
||||||
|
case userCancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -232,10 +288,20 @@ public extension NSError {
|
|||||||
|
|
||||||
internal var isCoreDataMigrationError: Bool {
|
internal var isCoreDataMigrationError: Bool {
|
||||||
|
|
||||||
let code = self.code
|
guard self.domain == CocoaError.errorDomain else {
|
||||||
return (code == NSPersistentStoreIncompatibleVersionHashError
|
|
||||||
|| code == NSMigrationMissingSourceModelError
|
return false
|
||||||
|| code == NSMigrationError)
|
}
|
||||||
&& self.domain == NSCocoaErrorDomain
|
switch CocoaError.Code(rawValue: self.code) {
|
||||||
|
|
||||||
|
case CocoaError.Code.persistentStoreIncompatibleSchema,
|
||||||
|
CocoaError.Code.persistentStoreIncompatibleVersionHash,
|
||||||
|
CocoaError.Code.migrationMissingSourceModel,
|
||||||
|
CocoaError.Code.migration:
|
||||||
|
return true
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal extension CoreStoreFetchRequest {
|
|||||||
|
|
||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc @inline(__always)
|
||||||
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchRequest<U> {
|
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchRequest<U> {
|
||||||
|
|
||||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||||
|
|||||||
@@ -27,16 +27,15 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - CoreStoreFetchedResultsController
|
// MARK: - CoreStoreFetchedResultsController
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController<NSManagedObject> {
|
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController<NSManagedObject> {
|
||||||
|
|
||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
internal convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
internal convenience init<T: DynamicObject>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||||
|
|
||||||
self.init(
|
self.init(
|
||||||
context: dataStack.mainContext,
|
context: dataStack.mainContext,
|
||||||
@@ -48,7 +47,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
|||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc
|
||||||
internal init<T: NSManagedObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
internal init<T: DynamicObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||||
|
|
||||||
_ = from?.applyToFetchRequest(
|
_ = from?.applyToFetchRequest(
|
||||||
fetchRequest,
|
fetchRequest,
|
||||||
@@ -66,7 +65,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
guard let from = (fetchRequest.entity.flatMap { $0.managedObjectClassName }).flatMap(NSClassFromString).flatMap(From.init) else {
|
guard let from = (fetchRequest.entity.flatMap { $0.managedObjectClassName }).flatMap(NSClassFromString).flatMap({ From<T>($0 as! T.Type) }) else {
|
||||||
|
|
||||||
CoreStore.abort("Attempted to create a \(CoreStoreFetchedResultsController.self) without a \(cs_typeName(From<T>.self)) clause or an \(cs_typeName(NSEntityDescription.self)).")
|
CoreStore.abort("Attempted to create a \(CoreStoreFetchedResultsController.self) without a \(cs_typeName(From<T>.self)) clause or an \(cs_typeName(NSEntityDescription.self)).")
|
||||||
}
|
}
|
||||||
@@ -115,5 +114,3 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
|||||||
@nonobjc
|
@nonobjc
|
||||||
private let reapplyAffectedStores: (_ fetchRequest: NSFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) -> Bool
|
private let reapplyAffectedStores: (_ fetchRequest: NSFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -1,317 +0,0 @@
|
|||||||
//
|
|
||||||
// CoreStoreImportableAttributeType.swift
|
|
||||||
// CoreStore
|
|
||||||
//
|
|
||||||
// Copyright © 2017 John Rommel Estropia
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import CoreData
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - CoreStoreImportableAttributeType
|
|
||||||
|
|
||||||
public protocol CoreStoreImportableAttributeType: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
associatedtype ImportableNativeType: QueryableNativeType
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
static func cs_emptyValue() -> Self
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self?
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSNumber
|
|
||||||
|
|
||||||
extension NSNumber: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSNumber
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_emptyValue() -> Self {
|
|
||||||
|
|
||||||
return self.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? {
|
|
||||||
|
|
||||||
func forceCast<T: NSNumber>(_ value: Any) -> T? {
|
|
||||||
|
|
||||||
return value as? T
|
|
||||||
}
|
|
||||||
return forceCast(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSString
|
|
||||||
|
|
||||||
extension NSString: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSString
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_emptyValue() -> Self {
|
|
||||||
|
|
||||||
return self.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? {
|
|
||||||
|
|
||||||
func forceCast<T: NSString>(_ value: Any) -> T? {
|
|
||||||
|
|
||||||
return value as? T
|
|
||||||
}
|
|
||||||
return forceCast(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSDate
|
|
||||||
|
|
||||||
extension NSDate: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSDate
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_emptyValue() -> Self {
|
|
||||||
|
|
||||||
return self.init(timeIntervalSinceReferenceDate: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? {
|
|
||||||
|
|
||||||
func forceCast<T: NSDate>(_ value: Any) -> T? {
|
|
||||||
|
|
||||||
return value as? T
|
|
||||||
}
|
|
||||||
return forceCast(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSData
|
|
||||||
|
|
||||||
extension NSData: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSData
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_emptyValue() -> Self {
|
|
||||||
|
|
||||||
return self.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
|
||||||
public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? {
|
|
||||||
|
|
||||||
func forceCast<T: NSData>(_ value: Any) -> T? {
|
|
||||||
|
|
||||||
return value as? T
|
|
||||||
}
|
|
||||||
return forceCast(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Bool
|
|
||||||
|
|
||||||
extension Bool: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSNumber
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Bool {
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Bool? {
|
|
||||||
|
|
||||||
return value.boolValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Int16
|
|
||||||
|
|
||||||
extension Int16: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSNumber
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Int16 {
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int16? {
|
|
||||||
|
|
||||||
return value.int16Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Int32
|
|
||||||
|
|
||||||
extension Int32: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSNumber
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Int32 {
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int32? {
|
|
||||||
|
|
||||||
return value.int32Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Int64
|
|
||||||
|
|
||||||
extension Int64: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSNumber
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Int64 {
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int64? {
|
|
||||||
|
|
||||||
return value.int64Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Double
|
|
||||||
|
|
||||||
extension Double: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSNumber
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Double {
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Double? {
|
|
||||||
|
|
||||||
return value.doubleValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Float
|
|
||||||
|
|
||||||
extension Float: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSNumber
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Float {
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Float? {
|
|
||||||
|
|
||||||
return value.floatValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Date
|
|
||||||
|
|
||||||
extension Date: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSDate
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Date {
|
|
||||||
|
|
||||||
return Date(timeIntervalSinceReferenceDate: 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Date? {
|
|
||||||
|
|
||||||
return value as Date
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - String
|
|
||||||
|
|
||||||
extension String: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSString
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> String {
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> String? {
|
|
||||||
|
|
||||||
return value as String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Data
|
|
||||||
|
|
||||||
extension Data: CoreStoreImportableAttributeType {
|
|
||||||
|
|
||||||
public typealias ImportableNativeType = NSData
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_emptyValue() -> Data {
|
|
||||||
|
|
||||||
return Data()
|
|
||||||
}
|
|
||||||
|
|
||||||
@inline(__always)
|
|
||||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Data? {
|
|
||||||
|
|
||||||
return value as Data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
99
Sources/CoreStoreObject+Convenience.swift
Normal file
99
Sources/CoreStoreObject+Convenience.swift
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
//
|
||||||
|
// CoreStoreObject+Convenience.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CoreStoreObject
|
||||||
|
|
||||||
|
public extension CoreStoreObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Exposes a `FetchableSource` that can fetch sibling objects of this `CoreStoreObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated.
|
||||||
|
- Warning: Future implementations may change the instance returned by this method depending on the timing or condition that `fetchSource()` was called. Do not make assumptions that the instance will be a specific instance. If the `NSManagedObjectContext` instance is desired, use the `FetchableSource.unsafeContext()` method to get the correct instance. Also, do not assume that the `fetchSource()` and `querySource()` return the same instance all the time.
|
||||||
|
- returns: a `FetchableSource` that can fetch sibling objects of this `CoreStoreObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the object's parent is already deallocated.
|
||||||
|
*/
|
||||||
|
@nonobjc
|
||||||
|
public func fetchSource() -> FetchableSource? {
|
||||||
|
|
||||||
|
guard let context = self.rawObject!.managedObjectContext else {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if context.isTransactionContext {
|
||||||
|
|
||||||
|
return context.parentTransaction
|
||||||
|
}
|
||||||
|
if context.isDataStackContext {
|
||||||
|
|
||||||
|
return context.parentStack
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Exposes a `QueryableSource` that can query attributes and aggregate values. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated.
|
||||||
|
- Warning: Future implementations may change the instance returned by this method depending on the timing or condition that `querySource()` was called. Do not make assumptions that the instance will be a specific instance. If the `NSManagedObjectContext` instance is desired, use the `QueryableSource.unsafeContext()` method to get the correct instance. Also, do not assume that the `fetchSource()` and `querySource()` return the same instance all the time.
|
||||||
|
- returns: a `QueryableSource` that can query attributes and aggregate values. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the object's parent is already deallocated.
|
||||||
|
*/
|
||||||
|
@nonobjc
|
||||||
|
public func querySource() -> QueryableSource? {
|
||||||
|
|
||||||
|
guard let context = self.rawObject!.managedObjectContext else {
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if context.isTransactionContext {
|
||||||
|
|
||||||
|
return context.parentTransaction
|
||||||
|
}
|
||||||
|
if context.isDataStackContext {
|
||||||
|
|
||||||
|
return context.parentStack
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Re-faults the object to use the latest values from the persistent store
|
||||||
|
*/
|
||||||
|
@nonobjc
|
||||||
|
public func refreshAsFault() {
|
||||||
|
|
||||||
|
let rawObject = self.rawObject!
|
||||||
|
rawObject.managedObjectContext?.refresh(rawObject, mergeChanges: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Re-faults the object to use the latest values from the persistent store and merges previously pending changes back
|
||||||
|
*/
|
||||||
|
@nonobjc
|
||||||
|
public func refreshAndMerge() {
|
||||||
|
|
||||||
|
let rawObject = self.rawObject!
|
||||||
|
rawObject.managedObjectContext?.refresh(rawObject, mergeChanges: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
196
Sources/CoreStoreObject+Querying.swift
Normal file
196
Sources/CoreStoreObject+Querying.swift
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
//
|
||||||
|
// CoreStoreObject+Querying.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - DynamicObject
|
||||||
|
|
||||||
|
public extension DynamicObject where Self: CoreStoreObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Extracts the keyPath string from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let keyPath: String = Person.keyPath { $0.nickname }
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func keyPath<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Required<V>) -> String {
|
||||||
|
|
||||||
|
return attribute(self.meta).keyPath
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Extracts the keyPath string from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let keyPath: String = Person.keyPath { $0.nickname }
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func keyPath<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> String {
|
||||||
|
|
||||||
|
return attribute(self.meta).keyPath
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname == "John" })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func `where`(_ condition: (Self) -> Where) -> Where {
|
||||||
|
|
||||||
|
return condition(self.meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates an `OrderBy` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchAll(From<Person>(), Person.ascending { $0.age })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func ascending<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||||
|
|
||||||
|
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates an `OrderBy` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchAll(From<Person>(), Person.descending { $0.age })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func descending<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||||
|
|
||||||
|
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - ValueContainer.Required
|
||||||
|
|
||||||
|
public extension ValueContainer.Required {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname == "John" })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func == (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||||
|
|
||||||
|
return Where(attribute.keyPath, isEqualTo: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname != "John" })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func != (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||||
|
|
||||||
|
return !Where(attribute.keyPath, isEqualTo: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age < 20 })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func < (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||||
|
|
||||||
|
return Where("%K < %@", attribute.keyPath, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age > 20 })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func > (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||||
|
|
||||||
|
return Where("%K > %@", attribute.keyPath, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age <= 20 })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func <= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||||
|
|
||||||
|
return Where("%K <= %@", attribute.keyPath, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age >= 20 })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func >= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||||
|
|
||||||
|
return Where("%K >= %@", attribute.keyPath, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - ValueContainer.Optional
|
||||||
|
|
||||||
|
public extension ValueContainer.Optional {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname == "John" })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func == (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where {
|
||||||
|
|
||||||
|
return Where(attribute.keyPath, isEqualTo: value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||||
|
```
|
||||||
|
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname != "John" })
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
@inline(__always)
|
||||||
|
public static func != (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where {
|
||||||
|
|
||||||
|
return !Where(attribute.keyPath, isEqualTo: value)
|
||||||
|
}
|
||||||
|
}
|
||||||
137
Sources/CoreStoreObject.swift
Normal file
137
Sources/CoreStoreObject.swift
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
//
|
||||||
|
// CoreStoreObject.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CoreStoreObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `CoreStoreObject` is an abstract class for creating CoreStore-managed objects that are more type-safe and more convenient than `NSManagedObject` subclasses. The model entities for `CoreStoreObject` subclasses are inferred from the Swift declaration themselves; no .xcdatamodeld files are needed. To declare persisted attributes and relationships for the `CoreStoreObject` subclass, declare properties of type `Value.Required<T>`, `Value.Optional<T>` for values, or `Relationship.ToOne<T>`, `Relationship.ToManyOrdered<T>`, `Relationship.ToManyUnordered<T>` for relationships.
|
||||||
|
```
|
||||||
|
class Animal: CoreStoreObject {
|
||||||
|
let species = Value.Required<String>("species")
|
||||||
|
let nickname = Value.Optional<String>("nickname")
|
||||||
|
let master = Relationship.ToOne<Person>("master")
|
||||||
|
}
|
||||||
|
|
||||||
|
class Person: CoreStoreObject {
|
||||||
|
let name = Value.Required<String>("name")
|
||||||
|
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||||
|
}
|
||||||
|
```
|
||||||
|
`CoreStoreObject` entities for a model version should be added to `CoreStoreSchema` instance.
|
||||||
|
```
|
||||||
|
CoreStore.defaultStack = DataStack(
|
||||||
|
CoreStoreSchema(
|
||||||
|
modelVersion: "V1",
|
||||||
|
entities: [
|
||||||
|
Entity<Animal>("Animal"),
|
||||||
|
Entity<Person>("Person")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
- SeeAlso: CoreStoreSchema
|
||||||
|
- SeeAlso: CoreStoreObject.Value
|
||||||
|
- SeeAlso: CoreStoreObject.Relationship
|
||||||
|
*/
|
||||||
|
open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do not call this directly. This is exposed as public only as a required initializer.
|
||||||
|
- Important: subclasses that need a custom initializer should override both `init(_:)` and `init(asMeta:)`, and to call their corresponding super implementations.
|
||||||
|
*/
|
||||||
|
public required init(rawObject: NSManagedObject) {
|
||||||
|
|
||||||
|
self.isMeta = false
|
||||||
|
self.rawObject = rawObject
|
||||||
|
self.initializeAttributes(Mirror(reflecting: self), { [unowned self] in self })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do not call this directly. This is exposed as public only as a required initializer.
|
||||||
|
- Important: subclasses that need a custom initializer should override both `init(_:)` and `init(asMeta:)`, and to call their corresponding super implementations.
|
||||||
|
*/
|
||||||
|
public required init(asMeta: Void) {
|
||||||
|
|
||||||
|
self.isMeta = true
|
||||||
|
self.rawObject = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Equatable
|
||||||
|
|
||||||
|
public static func == (lhs: CoreStoreObject, rhs: CoreStoreObject) -> Bool {
|
||||||
|
|
||||||
|
guard lhs.isMeta == rhs.isMeta else {
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.isMeta {
|
||||||
|
|
||||||
|
return type(of: lhs) == type(of: rhs)
|
||||||
|
}
|
||||||
|
return lhs.rawObject!.isEqual(rhs.rawObject!)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Hashable
|
||||||
|
|
||||||
|
public var hashValue: Int {
|
||||||
|
|
||||||
|
return ObjectIdentifier(self).hashValue
|
||||||
|
^ (self.isMeta ? 0 : self.rawObject!.hashValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Internal
|
||||||
|
|
||||||
|
internal let rawObject: NSManagedObject?
|
||||||
|
internal let isMeta: Bool
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private func initializeAttributes(_ mirror: Mirror, _ parentObject: @escaping () -> CoreStoreObject) {
|
||||||
|
|
||||||
|
_ = mirror.superclassMirror.flatMap({ self.initializeAttributes($0, parentObject) })
|
||||||
|
for child in mirror.children {
|
||||||
|
|
||||||
|
switch child.value {
|
||||||
|
|
||||||
|
case let property as AttributeProtocol:
|
||||||
|
property.parentObject = parentObject
|
||||||
|
|
||||||
|
case let property as RelationshipProtocol:
|
||||||
|
property.parentObject = parentObject
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,272 +0,0 @@
|
|||||||
//
|
|
||||||
// CoreStoreQueryableAttributeType.swift
|
|
||||||
// CoreStore
|
|
||||||
//
|
|
||||||
// Copyright © 2017 John Rommel Estropia
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import CoreGraphics
|
|
||||||
import CoreData
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - CoreStoreQueryableAttributeType
|
|
||||||
|
|
||||||
public protocol CoreStoreQueryableAttributeType: Hashable {
|
|
||||||
|
|
||||||
associatedtype QueryableNativeType: CoreDataNativeType
|
|
||||||
|
|
||||||
func cs_toQueryableNativeType() -> QueryableNativeType
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSManagedObject
|
|
||||||
|
|
||||||
extension NSManagedObject: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSManagedObjectID
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self.objectID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSManagedObjectID
|
|
||||||
|
|
||||||
extension NSManagedObjectID: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSManagedObjectID
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSNumber
|
|
||||||
|
|
||||||
extension NSNumber: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSString
|
|
||||||
|
|
||||||
extension NSString: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSString
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSDate
|
|
||||||
|
|
||||||
extension NSDate: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSDate
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSData
|
|
||||||
|
|
||||||
extension NSData: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSData
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Bool
|
|
||||||
|
|
||||||
extension Bool: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Int16
|
|
||||||
|
|
||||||
extension Int16: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Int32
|
|
||||||
|
|
||||||
extension Int32: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Int64
|
|
||||||
|
|
||||||
extension Int64: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Int
|
|
||||||
|
|
||||||
extension Int: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Double
|
|
||||||
|
|
||||||
extension Double: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Float
|
|
||||||
|
|
||||||
extension Float: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - CGFloat
|
|
||||||
|
|
||||||
extension CGFloat: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNumber
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Date
|
|
||||||
|
|
||||||
extension Date: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSDate
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSDate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - String
|
|
||||||
|
|
||||||
extension String: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSString
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSString
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Data
|
|
||||||
|
|
||||||
extension Data: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSData
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self as NSData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - NSNull
|
|
||||||
|
|
||||||
extension NSNull: CoreStoreQueryableAttributeType {
|
|
||||||
|
|
||||||
public typealias QueryableNativeType = NSNull
|
|
||||||
|
|
||||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
|
||||||
|
|
||||||
return self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
428
Sources/CoreStoreSchema.swift
Normal file
428
Sources/CoreStoreSchema.swift
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
//
|
||||||
|
// CoreStoreSchema.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CoreStoreSchema
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `CoreStoreSchema` describes models written for `CoreStoreObject` Swift class declarations for a particular model version. `CoreStoreObject` entities for a model version should be added to `CoreStoreSchema` instance.
|
||||||
|
```
|
||||||
|
class Animal: CoreStoreObject {
|
||||||
|
let species = Value.Required<String>("species")
|
||||||
|
let nickname = Value.Optional<String>("nickname")
|
||||||
|
let master = Relationship.ToOne<Person>("master")
|
||||||
|
}
|
||||||
|
|
||||||
|
class Person: CoreStoreObject {
|
||||||
|
let name = Value.Required<String>("name")
|
||||||
|
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreStore.defaultStack = DataStack(
|
||||||
|
CoreStoreSchema(
|
||||||
|
modelVersion: "V1",
|
||||||
|
entities: [
|
||||||
|
Entity<Animal>("Animal"),
|
||||||
|
Entity<Person>("Person")
|
||||||
|
],
|
||||||
|
versionLock: [
|
||||||
|
"Animal": [0x2698c812ebbc3b97, 0x751e3fa3f04cf9, 0x51fd460d3babc82, 0x92b4ba735b5a3053],
|
||||||
|
"Person": [0xae4060a59f990ef0, 0x8ac83a6e1411c130, 0xa29fea58e2e38ab6, 0x2071bb7e33d77887]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
- SeeAlso: CoreStoreObject
|
||||||
|
- SeeAlso: Entity
|
||||||
|
*/
|
||||||
|
public final class CoreStoreSchema: DynamicSchema {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes a `CoreStoreSchema`. Using this initializer only if the entities don't need to be assigned to particular "Configurations". To use multiple configurations (for example, to separate entities in different `StorageInterface`s), use the `init(modelVersion:entitiesByConfiguration:versionLock:)` initializer.
|
||||||
|
```
|
||||||
|
class Animal: CoreStoreObject {
|
||||||
|
let species = Value.Required<String>("species")
|
||||||
|
let nickname = Value.Optional<String>("nickname")
|
||||||
|
let master = Relationship.ToOne<Person>("master")
|
||||||
|
}
|
||||||
|
|
||||||
|
class Person: CoreStoreObject {
|
||||||
|
let name = Value.Required<String>("name")
|
||||||
|
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreStore.defaultStack = DataStack(
|
||||||
|
CoreStoreSchema(
|
||||||
|
modelVersion: "V1",
|
||||||
|
entities: [
|
||||||
|
Entity<Animal>("Animal"),
|
||||||
|
Entity<Person>("Person")
|
||||||
|
],
|
||||||
|
versionLock: [
|
||||||
|
"Animal": [0x2698c812ebbc3b97, 0x751e3fa3f04cf9, 0x51fd460d3babc82, 0x92b4ba735b5a3053],
|
||||||
|
"Person": [0xae4060a59f990ef0, 0x8ac83a6e1411c130, 0xa29fea58e2e38ab6, 0x2071bb7e33d77887]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
- parameter modelVersion: the model version for the schema. This string should be unique from other `DynamicSchema`'s model versions.
|
||||||
|
- parameter entities: an array of `Entity<T>` pertaining to all `CoreStoreObject` subclasses to be added to the schema version.
|
||||||
|
- parameter versionLock: an optional list of `VersionLock` hashes for each entity name in the `entities` array. If any `DynamicEntity` doesn't match its version lock hash, an assertion will be raised.
|
||||||
|
*/
|
||||||
|
public convenience init(modelVersion: ModelVersion, entities: [DynamicEntity], versionLock: VersionLock? = nil) {
|
||||||
|
|
||||||
|
var entityConfigurations: [DynamicEntity: Set<String>] = [:]
|
||||||
|
for entity in entities {
|
||||||
|
|
||||||
|
entityConfigurations[entity] = []
|
||||||
|
}
|
||||||
|
self.init(
|
||||||
|
modelVersion: modelVersion,
|
||||||
|
entityConfigurations: entityConfigurations,
|
||||||
|
versionLock: versionLock
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes a `CoreStoreSchema`. Using this initializer if multiple "Configurations" (for example, to separate entities in different `StorageInterface`s) are needed. To add an entity only to the default configuration, assign an empty set to its configurations list. Note that regardless of the set configurations, all entities will be added to the default configuration.
|
||||||
|
```
|
||||||
|
class Animal: CoreStoreObject {
|
||||||
|
let species = Value.Required<String>("species")
|
||||||
|
let nickname = Value.Optional<String>("nickname")
|
||||||
|
}
|
||||||
|
|
||||||
|
class Person: CoreStoreObject {
|
||||||
|
let name = Value.Required<String>("name")
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreStore.defaultStack = DataStack(
|
||||||
|
CoreStoreSchema(
|
||||||
|
modelVersion: "V1",
|
||||||
|
entityConfigurations: [
|
||||||
|
Entity<Animal>("Animal"): [],
|
||||||
|
Entity<Person>("Person"): ["People"]
|
||||||
|
],
|
||||||
|
versionLock: [
|
||||||
|
"Animal": [0x2698c812ebbc3b97, 0x751e3fa3f04cf9, 0x51fd460d3babc82, 0x92b4ba735b5a3053],
|
||||||
|
"Person": [0xae4060a59f990ef0, 0x8ac83a6e1411c130, 0xa29fea58e2e38ab6, 0x2071bb7e33d77887]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
- parameter modelVersion: the model version for the schema. This string should be unique from other `DynamicSchema`'s model versions.
|
||||||
|
- parameter entityConfigurations: a dictionary with `Entity<T>` pertaining to all `CoreStoreObject` subclasses and the corresponding list of "Configurations" they should be added to. To add an entity only to the default configuration, assign an empty set to its configurations list. Note that regardless of the set configurations, all entities will be added to the default configuration.
|
||||||
|
- parameter versionLock: an optional list of `VersionLock` hashes for each entity name in the `entities` array. If any `DynamicEntity` doesn't match its version lock hash, an assertion will be raised.
|
||||||
|
*/
|
||||||
|
public required init(modelVersion: ModelVersion, entityConfigurations: [DynamicEntity: Set<String>], versionLock: VersionLock? = nil) {
|
||||||
|
|
||||||
|
var actualEntitiesByConfiguration: [String: Set<DynamicEntity>] = [:]
|
||||||
|
for (entity, configurations) in entityConfigurations {
|
||||||
|
|
||||||
|
for configuration in configurations {
|
||||||
|
|
||||||
|
var entities: Set<DynamicEntity>
|
||||||
|
if let existingEntities = actualEntitiesByConfiguration[configuration] {
|
||||||
|
|
||||||
|
entities = existingEntities
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
entities = []
|
||||||
|
}
|
||||||
|
entities.insert(entity)
|
||||||
|
actualEntitiesByConfiguration[configuration] = entities
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let allEntities = Set(entityConfigurations.keys)
|
||||||
|
actualEntitiesByConfiguration[DataStack.defaultConfigurationName] = allEntities
|
||||||
|
|
||||||
|
CoreStore.assert(
|
||||||
|
cs_lazy {
|
||||||
|
|
||||||
|
let expectedCount = allEntities.count
|
||||||
|
return Set(allEntities.map({ ObjectIdentifier($0.type) })).count == expectedCount
|
||||||
|
&& Set(allEntities.map({ $0.entityName })).count == expectedCount
|
||||||
|
},
|
||||||
|
"Ambiguous entity types or entity names were found in the model. Ensure that the entity types and entity names are unique to each other. Entities: \(allEntities)"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.modelVersion = modelVersion
|
||||||
|
self.entitiesByConfiguration = actualEntitiesByConfiguration
|
||||||
|
self.allEntities = allEntities
|
||||||
|
|
||||||
|
if let versionLock = versionLock {
|
||||||
|
|
||||||
|
CoreStore.assert(
|
||||||
|
versionLock == VersionLock(entityVersionHashesByName: self.rawModel().entityVersionHashesByName),
|
||||||
|
"A \(cs_typeName(VersionLock.self)) was provided for the \(cs_typeName(CoreStoreSchema.self)) with version \"\(modelVersion)\", but the actual hashes do not match. This may result in unwanted migrations or unusable persistent stores.\nExpected lock values: \(versionLock)\nActual lock values: \(VersionLock(entityVersionHashesByName: self.rawModel().entityVersionHashesByName))"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
CoreStore.log(
|
||||||
|
.notice,
|
||||||
|
message: "These are hashes for the \(cs_typeName(CoreStoreSchema.self)) with version name \"\(modelVersion)\". Copy the dictionary below and pass it to the \(cs_typeName(CoreStoreSchema.self)) initializer's \"versionLock\" argument:\nversionLock: \(VersionLock(entityVersionHashesByName: self.rawModel().entityVersionHashesByName))"
|
||||||
|
)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - DynamicSchema
|
||||||
|
|
||||||
|
public let modelVersion: ModelVersion
|
||||||
|
|
||||||
|
public func rawModel() -> NSManagedObjectModel {
|
||||||
|
|
||||||
|
if let cachedRawModel = self.cachedRawModel {
|
||||||
|
|
||||||
|
return cachedRawModel
|
||||||
|
}
|
||||||
|
let rawModel = NSManagedObjectModel()
|
||||||
|
var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||||
|
for entity in self.allEntities {
|
||||||
|
|
||||||
|
let entityDescription = self.entityDescription(
|
||||||
|
for: entity,
|
||||||
|
initializer: CoreStoreSchema.firstPassCreateEntityDescription
|
||||||
|
)
|
||||||
|
entityDescriptionsByEntity[entity] = (entityDescription.copy() as! NSEntityDescription)
|
||||||
|
}
|
||||||
|
CoreStoreSchema.secondPassConnectRelationshipAttributes(for: entityDescriptionsByEntity)
|
||||||
|
CoreStoreSchema.thirdPassConnectInheritanceTree(for: entityDescriptionsByEntity)
|
||||||
|
|
||||||
|
rawModel.entities = entityDescriptionsByEntity.values.sorted(by: { $0.name! < $1.name! })
|
||||||
|
for (configuration, entities) in self.entitiesByConfiguration {
|
||||||
|
|
||||||
|
rawModel.setEntities(
|
||||||
|
entities
|
||||||
|
.map({ entityDescriptionsByEntity[$0]! })
|
||||||
|
.sorted(by: { $0.name! < $1.name! }),
|
||||||
|
forConfigurationName: configuration
|
||||||
|
)
|
||||||
|
}
|
||||||
|
self.cachedRawModel = rawModel
|
||||||
|
return rawModel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Internal
|
||||||
|
|
||||||
|
internal let entitiesByConfiguration: [String: Set<DynamicEntity>]
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private static let barrierQueue = DispatchQueue.concurrent("com.coreStore.coreStoreDataModelBarrierQueue")
|
||||||
|
|
||||||
|
private let allEntities: Set<DynamicEntity>
|
||||||
|
|
||||||
|
private var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||||
|
private weak var cachedRawModel: NSManagedObjectModel?
|
||||||
|
|
||||||
|
private func entityDescription(for entity: DynamicEntity, initializer: (DynamicEntity) -> NSEntityDescription) -> NSEntityDescription {
|
||||||
|
|
||||||
|
if let cachedEntityDescription = self.entityDescriptionsByEntity[entity] {
|
||||||
|
|
||||||
|
return cachedEntityDescription
|
||||||
|
}
|
||||||
|
let entityDescription = withoutActuallyEscaping(initializer, do: { $0(entity) })
|
||||||
|
self.entityDescriptionsByEntity[entity] = entityDescription
|
||||||
|
return entityDescription
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func firstPassCreateEntityDescription(from entity: DynamicEntity) -> NSEntityDescription {
|
||||||
|
|
||||||
|
let entityDescription = NSEntityDescription()
|
||||||
|
entityDescription.coreStoreEntity = entity
|
||||||
|
entityDescription.name = entity.entityName
|
||||||
|
entityDescription.isAbstract = entity.isAbstract
|
||||||
|
entityDescription.versionHashModifier = entity.versionHashModifier
|
||||||
|
entityDescription.managedObjectClassName = NSStringFromClass(NSManagedObject.self)
|
||||||
|
|
||||||
|
func createProperties(for type: CoreStoreObject.Type) -> [NSPropertyDescription] {
|
||||||
|
|
||||||
|
var propertyDescriptions: [NSPropertyDescription] = []
|
||||||
|
for child in Mirror(reflecting: type.meta).children {
|
||||||
|
|
||||||
|
switch child.value {
|
||||||
|
|
||||||
|
case let attribute as AttributeProtocol:
|
||||||
|
let description = NSAttributeDescription()
|
||||||
|
description.name = attribute.keyPath
|
||||||
|
description.attributeType = type(of: attribute).attributeType
|
||||||
|
description.isOptional = attribute.isOptional
|
||||||
|
description.isIndexed = attribute.isIndexed
|
||||||
|
description.defaultValue = attribute.defaultValue
|
||||||
|
description.isTransient = attribute.isTransient
|
||||||
|
description.versionHashModifier = attribute.versionHashModifier
|
||||||
|
description.renamingIdentifier = attribute.renamingIdentifier
|
||||||
|
propertyDescriptions.append(description)
|
||||||
|
|
||||||
|
case let relationship as RelationshipProtocol:
|
||||||
|
let description = NSRelationshipDescription()
|
||||||
|
description.name = relationship.keyPath
|
||||||
|
description.minCount = relationship.minCount
|
||||||
|
description.maxCount = relationship.maxCount
|
||||||
|
description.isOrdered = relationship.isOrdered
|
||||||
|
description.deleteRule = relationship.deleteRule
|
||||||
|
description.versionHashModifier = relationship.versionHashModifier
|
||||||
|
description.renamingIdentifier = relationship.renamingIdentifier
|
||||||
|
propertyDescriptions.append(description)
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return propertyDescriptions
|
||||||
|
}
|
||||||
|
|
||||||
|
entityDescription.properties = createProperties(for: entity.type as! CoreStoreObject.Type)
|
||||||
|
return entityDescription
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func secondPassConnectRelationshipAttributes(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription]) {
|
||||||
|
|
||||||
|
var relationshipsByNameByEntity: [DynamicEntity: [String: NSRelationshipDescription]] = [:]
|
||||||
|
for (entity, entityDescription) in entityDescriptionsByEntity {
|
||||||
|
|
||||||
|
relationshipsByNameByEntity[entity] = entityDescription.relationshipsByName
|
||||||
|
}
|
||||||
|
func findEntity(for type: CoreStoreObject.Type) -> DynamicEntity {
|
||||||
|
|
||||||
|
var matchedEntities: Set<DynamicEntity> = []
|
||||||
|
for (entity, _) in entityDescriptionsByEntity where entity.type == type {
|
||||||
|
|
||||||
|
matchedEntities.insert(entity)
|
||||||
|
}
|
||||||
|
if matchedEntities.count == 1 {
|
||||||
|
|
||||||
|
return matchedEntities.first!
|
||||||
|
}
|
||||||
|
if matchedEntities.isEmpty {
|
||||||
|
|
||||||
|
CoreStore.abort(
|
||||||
|
"No \(cs_typeName("Entity<\(type)>")) instance found in the \(cs_typeName(CoreStoreSchema.self))."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
CoreStore.abort(
|
||||||
|
"Ambiguous entity types or entity names were found in the model. Ensure that the entity types and entity names are unique to each other. Entities: \(matchedEntities)"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func findInverseRelationshipMatching(destinationEntity: DynamicEntity, destinationKeyPath: String) -> NSRelationshipDescription {
|
||||||
|
|
||||||
|
for case (destinationKeyPath, let relationshipDescription) in relationshipsByNameByEntity[destinationEntity]! {
|
||||||
|
|
||||||
|
return relationshipDescription
|
||||||
|
}
|
||||||
|
CoreStore.abort(
|
||||||
|
"The inverse relationship for \"\(destinationEntity.type).\(destinationKeyPath)\" could not be found. Make sure to set the `inverse:` initializer argument for one of the paired \(cs_typeName("Relationship.ToOne<T>")), \(cs_typeName("Relationship.ToManyOrdered<T>")), or \(cs_typeName("Relationship.ToManyUnozrdered<T>"))"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (entity, entityDescription) in entityDescriptionsByEntity {
|
||||||
|
|
||||||
|
let relationshipsByName = relationshipsByNameByEntity[entity]!
|
||||||
|
for child in Mirror(reflecting: (entity.type as! CoreStoreObject.Type).meta).children {
|
||||||
|
|
||||||
|
switch child.value {
|
||||||
|
|
||||||
|
case let relationship as RelationshipProtocol:
|
||||||
|
let (destinationType, destinationKeyPath) = relationship.inverse
|
||||||
|
let destinationEntity = findEntity(for: destinationType)
|
||||||
|
let description = relationshipsByName[relationship.keyPath]!
|
||||||
|
description.destinationEntity = entityDescriptionsByEntity[destinationEntity]!
|
||||||
|
|
||||||
|
if let destinationKeyPath = destinationKeyPath() {
|
||||||
|
|
||||||
|
let inverseRelationshipDescription = findInverseRelationshipMatching(
|
||||||
|
destinationEntity: destinationEntity,
|
||||||
|
destinationKeyPath: destinationKeyPath
|
||||||
|
)
|
||||||
|
description.inverseRelationship = inverseRelationshipDescription
|
||||||
|
|
||||||
|
inverseRelationshipDescription.inverseRelationship = description
|
||||||
|
inverseRelationshipDescription.destinationEntity = entityDescription
|
||||||
|
|
||||||
|
description.destinationEntity!.properties = description.destinationEntity!.properties
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (entity, entityDescription) in entityDescriptionsByEntity {
|
||||||
|
|
||||||
|
for (name, relationshipDescription) in entityDescription.relationshipsByName {
|
||||||
|
|
||||||
|
CoreStore.assert(
|
||||||
|
relationshipDescription.destinationEntity != nil,
|
||||||
|
"The destination entity for relationship \"\(entity.type).\(name)\" could not be resolved."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
relationshipDescription.inverseRelationship != nil,
|
||||||
|
"The inverse relationship for \"\(entity.type).\(name)\" could not be found. Make sure to set the `inverse:` argument of the initializer for one of the paired \(cs_typeName("Relationship.ToOne<T>")), \(cs_typeName("Relationship.ToManyOrdered<T>")), or \(cs_typeName("Relationship.ToManyUnozrdered<T>"))"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func thirdPassConnectInheritanceTree(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription]) {
|
||||||
|
|
||||||
|
func connectBaseEntity(mirror: Mirror, entityDescription: NSEntityDescription) {
|
||||||
|
|
||||||
|
guard let superclassMirror = mirror.superclassMirror,
|
||||||
|
let superType = superclassMirror.subjectType as? CoreStoreObject.Type,
|
||||||
|
superType != CoreStoreObject.self else {
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (superEntity, superEntityDescription) in entityDescriptionsByEntity where superEntity.type == superType {
|
||||||
|
|
||||||
|
if !superEntityDescription.subentities.contains(entityDescription) {
|
||||||
|
|
||||||
|
superEntityDescription.subentities.append(entityDescription)
|
||||||
|
}
|
||||||
|
connectBaseEntity(mirror: superclassMirror, entityDescription: superEntityDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (entity, entityDescription) in entityDescriptionsByEntity {
|
||||||
|
|
||||||
|
connectBaseEntity(
|
||||||
|
mirror: Mirror(reflecting: (entity.type as! CoreStoreObject.Type).meta),
|
||||||
|
entityDescription: entityDescription
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
Sources/CoreStoreStrings.swift
Normal file
66
Sources/CoreStoreStrings.swift
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// CoreStoreStrings.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - XcodeDataModelFileName
|
||||||
|
|
||||||
|
/**
|
||||||
|
A `String` that pertains to the name of an *.xcdatamodeld file (without the file extension).
|
||||||
|
*/
|
||||||
|
public typealias XcodeDataModelFileName = String
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - ModelConfiguration
|
||||||
|
|
||||||
|
/**
|
||||||
|
An `Optional<String>` that pertains to the name of a "Configuration" which particular groups of entities may belong to. When `nil`, pertains to the default configuration which includes all entities.
|
||||||
|
*/
|
||||||
|
public typealias ModelConfiguration = String?
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - ModelVersion
|
||||||
|
|
||||||
|
/**
|
||||||
|
An `String` that pertains to the name of a versioned *.xcdatamodeld file (without the file extension). Model version strings don't necessarily have to be numeric or ordered in any way. The migration sequence will always be decided by (or the lack of) the `MigrationChain`.
|
||||||
|
*/
|
||||||
|
public typealias ModelVersion = String
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - EntityName
|
||||||
|
|
||||||
|
/**
|
||||||
|
An `String` that pertains to an Entity name.
|
||||||
|
*/
|
||||||
|
public typealias EntityName = String
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - ClassName
|
||||||
|
|
||||||
|
/**
|
||||||
|
An `String` that pertains to a dynamically-accessable class name (usable with NSClassFromString(...)).
|
||||||
|
*/
|
||||||
|
public typealias ClassName = String
|
||||||
748
Sources/CustomSchemaMappingProvider.swift
Normal file
748
Sources/CustomSchemaMappingProvider.swift
Normal file
@@ -0,0 +1,748 @@
|
|||||||
|
//
|
||||||
|
// CustomSchemaMappingProvider.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CustomSchemaMappingProvider
|
||||||
|
|
||||||
|
/**
|
||||||
|
A `SchemaMappingProvider` that accepts custom mappings for some entities. Mappings of entities with no `CustomMapping` provided will be automatically calculated if possible.
|
||||||
|
*/
|
||||||
|
open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
The source model version for the mapping.
|
||||||
|
*/
|
||||||
|
public let sourceVersion: ModelVersion
|
||||||
|
|
||||||
|
/**
|
||||||
|
The destination model version for the mapping.
|
||||||
|
*/
|
||||||
|
public let destinationVersion: ModelVersion
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a `CustomSchemaMappingProvider`
|
||||||
|
|
||||||
|
- parameter sourceVersion: the source model version for the mapping
|
||||||
|
- parameter destinationVersion: the destination model version for the mapping
|
||||||
|
- parameter entityMappings: a list of `CustomMapping`s. Mappings of entities with no `CustomMapping` provided will be automatically calculated if possible. Any conflicts or ambiguity will raise an assertion.
|
||||||
|
*/
|
||||||
|
public required init(from sourceVersion: ModelVersion, to destinationVersion: ModelVersion, entityMappings: Set<CustomMapping> = []) {
|
||||||
|
|
||||||
|
CoreStore.assert(
|
||||||
|
cs_lazy {
|
||||||
|
|
||||||
|
let sources = entityMappings.flatMap({ $0.entityMappingSourceEntity })
|
||||||
|
let destinations = entityMappings.flatMap({ $0.entityMappingDestinationEntity })
|
||||||
|
return sources.count == Set(sources).count
|
||||||
|
&& destinations.count == Set(destinations).count
|
||||||
|
},
|
||||||
|
"Duplicate source/destination entities found in provided \"entityMappings\" argument."
|
||||||
|
)
|
||||||
|
self.sourceVersion = sourceVersion
|
||||||
|
self.destinationVersion = destinationVersion
|
||||||
|
self.entityMappings = entityMappings
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CustomMapping
|
||||||
|
|
||||||
|
/**
|
||||||
|
Provides the type of mapping for an entity. Mappings of entities with no `CustomMapping` provided will be automatically calculated if possible. Any conflicts or ambiguity will raise an assertion.
|
||||||
|
*/
|
||||||
|
public enum CustomMapping: Hashable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `sourceEntity` is meant to be removed from the source `DynamicSchema` and should not be migrated to the destination `DynamicSchema`.
|
||||||
|
*/
|
||||||
|
case deleteEntity(sourceEntity: EntityName)
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `destinationEntity` is newly added to the destination `DynamicSchema` and has no mapping from the source `DynamicSchema`.
|
||||||
|
*/
|
||||||
|
case insertEntity(destinationEntity: EntityName)
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `DynamicSchema`s entity has no changes and can be copied directly from `sourceEntity` to `destinationEntity`.
|
||||||
|
*/
|
||||||
|
case copyEntity(sourceEntity: EntityName, destinationEntity: EntityName)
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `DynamicSchema`s entity needs transformations from `sourceEntity` to `destinationEntity`. The `transformer` closure will be used to apply the changes. The `CustomMapping.inferredTransformation` method can be used directly as the `transformer` if the changes can be inferred (i.e. lightweight).
|
||||||
|
*/
|
||||||
|
case transformEntity(sourceEntity: EntityName, destinationEntity: EntityName, transformer: Transformer)
|
||||||
|
|
||||||
|
/**
|
||||||
|
The closure type for `CustomMapping.transformEntity`.
|
||||||
|
- parameter sourceObject: a proxy object representing the source entity. The properties can be accessed via keyPath.
|
||||||
|
- parameter createDestinationObject: the closure to create the object for the destination entity. The `CustomMapping.inferredTransformation` method can be used directly as the `transformer` if the changes can be inferred (i.e. lightweight). The object is created lazily and executing the closure multiple times will return the same instance. The destination object's properties can be accessed and updated via keyPath.
|
||||||
|
*/
|
||||||
|
public typealias Transformer = (_ sourceObject: UnsafeSourceObject, _ createDestinationObject: () -> UnsafeDestinationObject) throws -> Void
|
||||||
|
|
||||||
|
/**
|
||||||
|
The `CustomMapping.inferredTransformation` method can be used directly as the `transformer` if the changes can be inferred (i.e. lightweight).
|
||||||
|
*/
|
||||||
|
public static func inferredTransformation(_ sourceObject: UnsafeSourceObject, _ createDestinationObject: () -> UnsafeDestinationObject) throws -> Void {
|
||||||
|
|
||||||
|
let destinationObject = createDestinationObject()
|
||||||
|
destinationObject.enumerateAttributes { (attribute, sourceAttribute) in
|
||||||
|
|
||||||
|
if let sourceAttribute = sourceAttribute {
|
||||||
|
|
||||||
|
destinationObject[attribute] = sourceObject[sourceAttribute]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Equatable
|
||||||
|
|
||||||
|
public static func == (lhs: CustomMapping, rhs: CustomMapping) -> Bool {
|
||||||
|
|
||||||
|
switch (lhs, rhs) {
|
||||||
|
|
||||||
|
case (.deleteEntity(let sourceEntity1), .deleteEntity(let sourceEntity2)):
|
||||||
|
return sourceEntity1 == sourceEntity2
|
||||||
|
|
||||||
|
case (.insertEntity(let destinationEntity1), .insertEntity(let destinationEntity2)):
|
||||||
|
return destinationEntity1 == destinationEntity2
|
||||||
|
|
||||||
|
case (.copyEntity(let sourceEntity1, let destinationEntity1), .copyEntity(let sourceEntity2, let destinationEntity2)):
|
||||||
|
return sourceEntity1 == sourceEntity2
|
||||||
|
&& destinationEntity1 == destinationEntity2
|
||||||
|
|
||||||
|
case (.transformEntity(let sourceEntity1, let destinationEntity1, _), .transformEntity(let sourceEntity2, let destinationEntity2, _)):
|
||||||
|
return sourceEntity1 == sourceEntity2
|
||||||
|
&& destinationEntity1 == destinationEntity2
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Hashable
|
||||||
|
|
||||||
|
public var hashValue: Int {
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
|
||||||
|
case .deleteEntity(let sourceEntity):
|
||||||
|
return sourceEntity.hashValue
|
||||||
|
|
||||||
|
case .insertEntity(let destinationEntity):
|
||||||
|
return destinationEntity.hashValue
|
||||||
|
|
||||||
|
case .copyEntity(let sourceEntity, let destinationEntity):
|
||||||
|
return sourceEntity.hashValue
|
||||||
|
^ destinationEntity.hashValue
|
||||||
|
|
||||||
|
case .transformEntity(let sourceEntity, let destinationEntity, _):
|
||||||
|
return sourceEntity.hashValue
|
||||||
|
^ destinationEntity.hashValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: FilePrivate
|
||||||
|
|
||||||
|
fileprivate var entityMappingSourceEntity: EntityName? {
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
|
||||||
|
case .deleteEntity(let sourceEntity),
|
||||||
|
.copyEntity(let sourceEntity, _),
|
||||||
|
.transformEntity(let sourceEntity, _, _):
|
||||||
|
return sourceEntity
|
||||||
|
|
||||||
|
case .insertEntity:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate var entityMappingDestinationEntity: EntityName? {
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
|
||||||
|
case .insertEntity(let destinationEntity),
|
||||||
|
.copyEntity(_, let destinationEntity),
|
||||||
|
.transformEntity(_, let destinationEntity, _):
|
||||||
|
return destinationEntity
|
||||||
|
|
||||||
|
case .deleteEntity:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - UnsafeSourceObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
The read-only proxy object used for the source object in a mapping's `Transformer` closure. Properties can be accessed either by keyPath string or by `NSAttributeDescription`.
|
||||||
|
*/
|
||||||
|
public final class UnsafeSourceObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Accesses the property value via its keyPath.
|
||||||
|
*/
|
||||||
|
public subscript(attribute: KeyPath) -> Any? {
|
||||||
|
|
||||||
|
return self.rawObject.cs_accessValueForKVCKey(attribute)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Accesses the property value via its `NSAttributeDescription`, which can be accessed from the `enumerateAttributes(_:)` method.
|
||||||
|
*/
|
||||||
|
public subscript(attribute: NSAttributeDescription) -> Any? {
|
||||||
|
|
||||||
|
return self.rawObject.cs_accessValueForKVCKey(attribute.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enumerates the all `NSAttributeDescription`s. The `attribute` argument can be used as the subscript key to access the property.
|
||||||
|
*/
|
||||||
|
public func enumerateAttributes(_ closure: (_ attribute: NSAttributeDescription) -> Void) {
|
||||||
|
|
||||||
|
func enumerate(_ entity: NSEntityDescription, _ closure: (NSAttributeDescription) -> Void) {
|
||||||
|
|
||||||
|
if let superEntity = entity.superentity {
|
||||||
|
|
||||||
|
enumerate(superEntity, closure)
|
||||||
|
}
|
||||||
|
for case let attribute as NSAttributeDescription in entity.properties {
|
||||||
|
|
||||||
|
closure(attribute)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerate(self.rawObject.entity, closure)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Internal
|
||||||
|
|
||||||
|
internal init(_ rawObject: NSManagedObject) {
|
||||||
|
|
||||||
|
self.rawObject = rawObject
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private let rawObject: NSManagedObject
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - UnsafeDestinationObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
The read-write proxy object used for the destination object that can be created in a mapping's `Transformer` closure. Properties can be accessed and mutated either through keyPath string or by `NSAttributeDescription`.
|
||||||
|
*/
|
||||||
|
public final class UnsafeDestinationObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Accesses or mutates the property value via its keyPath.
|
||||||
|
*/
|
||||||
|
public subscript(attribute: KeyPath) -> Any? {
|
||||||
|
|
||||||
|
get { return self.rawObject.cs_accessValueForKVCKey(attribute) }
|
||||||
|
set { self.rawObject.cs_setValue(newValue, forKVCKey: attribute) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Accesses or mutates the property value via its `NSAttributeDescription`, which can be accessed from the `enumerateAttributes(_:)` method.
|
||||||
|
*/
|
||||||
|
public subscript(attribute: NSAttributeDescription) -> Any? {
|
||||||
|
|
||||||
|
get { return self.rawObject.cs_accessValueForKVCKey(attribute.name) }
|
||||||
|
set { self.rawObject.cs_setValue(newValue, forKVCKey: attribute.name) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enumerates the all `NSAttributeDescription`s. The `attribute` argument can be used as the subscript key to access and mutate the property. The `sourceAttribute` can be used to access properties from the source `UnsafeSourceObject`.
|
||||||
|
*/
|
||||||
|
public func enumerateAttributes(_ closure: (_ attribute: NSAttributeDescription, _ sourceAttribute: NSAttributeDescription?) -> Void) {
|
||||||
|
|
||||||
|
func enumerate(_ entity: NSEntityDescription, _ closure: (_ attribute: NSAttributeDescription, _ sourceAttribute: NSAttributeDescription?) -> Void) {
|
||||||
|
|
||||||
|
if let superEntity = entity.superentity {
|
||||||
|
|
||||||
|
enumerate(superEntity, closure)
|
||||||
|
}
|
||||||
|
for case let attribute as NSAttributeDescription in entity.properties {
|
||||||
|
|
||||||
|
closure(attribute, self.sourceAttributesByDestinationKey[attribute.name])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerate(self.rawObject.entity, closure)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Internal
|
||||||
|
|
||||||
|
internal init(_ rawObject: NSManagedObject, _ sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription]) {
|
||||||
|
|
||||||
|
self.rawObject = rawObject
|
||||||
|
self.sourceAttributesByDestinationKey = sourceAttributesByDestinationKey
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: FilePrivate
|
||||||
|
|
||||||
|
fileprivate let rawObject: NSManagedObject
|
||||||
|
fileprivate let sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Equatable
|
||||||
|
|
||||||
|
public static func == (lhs: CustomSchemaMappingProvider, rhs: CustomSchemaMappingProvider) -> Bool {
|
||||||
|
|
||||||
|
return lhs.sourceVersion == rhs.sourceVersion
|
||||||
|
&& lhs.destinationVersion == rhs.destinationVersion
|
||||||
|
&& type(of: lhs) == type(of: rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Hashable
|
||||||
|
|
||||||
|
public var hashValue: Int {
|
||||||
|
|
||||||
|
return self.sourceVersion.hashValue
|
||||||
|
^ self.destinationVersion.hashValue
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: SchemaMappingProvider
|
||||||
|
|
||||||
|
public func cs_createMappingModel(from sourceSchema: DynamicSchema, to destinationSchema: DynamicSchema, storage: LocalStorage) throws -> (mappingModel: NSMappingModel, migrationType: MigrationType) {
|
||||||
|
|
||||||
|
let sourceModel = sourceSchema.rawModel()
|
||||||
|
let destinationModel = destinationSchema.rawModel()
|
||||||
|
|
||||||
|
let mappingModel = NSMappingModel()
|
||||||
|
|
||||||
|
let (deleteMappings, insertMappings, copyMappings, transformMappings) = self.resolveEntityMappings(
|
||||||
|
sourceModel: sourceModel,
|
||||||
|
destinationModel: destinationModel
|
||||||
|
)
|
||||||
|
func expression(forSource sourceEntity: NSEntityDescription) -> NSExpression {
|
||||||
|
|
||||||
|
return NSExpression(format: "FETCH(FUNCTION($\(NSMigrationManagerKey), \"fetchRequestForSourceEntityNamed:predicateString:\" , \"\(sourceEntity.name!)\", \"\(NSPredicate(value: true))\"), $\(NSMigrationManagerKey).\(#keyPath(NSMigrationManager.sourceContext)), \(false))")
|
||||||
|
}
|
||||||
|
|
||||||
|
let sourceEntitiesByName = sourceModel.entitiesByName
|
||||||
|
let destinationEntitiesByName = destinationModel.entitiesByName
|
||||||
|
|
||||||
|
var entityMappings: [NSEntityMapping] = []
|
||||||
|
for case .deleteEntity(let sourceEntityName) in deleteMappings {
|
||||||
|
|
||||||
|
let sourceEntity = sourceEntitiesByName[sourceEntityName]!
|
||||||
|
|
||||||
|
let entityMapping = NSEntityMapping()
|
||||||
|
entityMapping.sourceEntityName = sourceEntity.name
|
||||||
|
entityMapping.sourceEntityVersionHash = sourceEntity.versionHash
|
||||||
|
entityMapping.mappingType = .removeEntityMappingType
|
||||||
|
entityMapping.sourceExpression = expression(forSource: sourceEntity)
|
||||||
|
|
||||||
|
entityMappings.append(entityMapping)
|
||||||
|
}
|
||||||
|
for case .insertEntity(let destinationEntityName) in insertMappings {
|
||||||
|
|
||||||
|
let destinationEntity = destinationEntitiesByName[destinationEntityName]!
|
||||||
|
|
||||||
|
let entityMapping = NSEntityMapping()
|
||||||
|
entityMapping.destinationEntityName = destinationEntity.name
|
||||||
|
entityMapping.destinationEntityVersionHash = destinationEntity.versionHash
|
||||||
|
entityMapping.mappingType = .addEntityMappingType
|
||||||
|
entityMapping.attributeMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||||
|
|
||||||
|
var attributeMappings: [NSPropertyMapping] = []
|
||||||
|
for (_, destinationAttribute) in destinationEntity.attributesByName {
|
||||||
|
|
||||||
|
let propertyMapping = NSPropertyMapping()
|
||||||
|
propertyMapping.name = destinationAttribute.name
|
||||||
|
attributeMappings.append(propertyMapping)
|
||||||
|
}
|
||||||
|
return attributeMappings
|
||||||
|
}
|
||||||
|
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||||
|
|
||||||
|
var relationshipMappings: [NSPropertyMapping] = []
|
||||||
|
for (_, destinationRelationship) in destinationEntity.relationshipsByName {
|
||||||
|
|
||||||
|
let propertyMapping = NSPropertyMapping()
|
||||||
|
propertyMapping.name = destinationRelationship.name
|
||||||
|
relationshipMappings.append(propertyMapping)
|
||||||
|
}
|
||||||
|
return relationshipMappings
|
||||||
|
}
|
||||||
|
entityMappings.append(entityMapping)
|
||||||
|
}
|
||||||
|
for case .copyEntity(let sourceEntityName, let destinationEntityName) in copyMappings {
|
||||||
|
|
||||||
|
let sourceEntity = sourceEntitiesByName[sourceEntityName]!
|
||||||
|
let destinationEntity = destinationEntitiesByName[destinationEntityName]!
|
||||||
|
|
||||||
|
let entityMapping = NSEntityMapping()
|
||||||
|
entityMapping.sourceEntityName = sourceEntity.name
|
||||||
|
entityMapping.sourceEntityVersionHash = sourceEntity.versionHash
|
||||||
|
entityMapping.destinationEntityName = destinationEntity.name
|
||||||
|
entityMapping.destinationEntityVersionHash = destinationEntity.versionHash
|
||||||
|
entityMapping.mappingType = .copyEntityMappingType
|
||||||
|
entityMapping.sourceExpression = expression(forSource: sourceEntity)
|
||||||
|
entityMapping.attributeMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||||
|
|
||||||
|
let sourceAttributes = sourceEntity.cs_resolvedAttributeRenamingIdentities()
|
||||||
|
let destinationAttributes = destinationEntity.cs_resolvedAttributeRenamingIdentities()
|
||||||
|
|
||||||
|
var attributeMappings: [NSPropertyMapping] = []
|
||||||
|
for (renamingIdentifier, destination) in destinationAttributes {
|
||||||
|
|
||||||
|
let sourceAttribute = sourceAttributes[renamingIdentifier]!.attribute
|
||||||
|
let destinationAttribute = destination.attribute
|
||||||
|
let propertyMapping = NSPropertyMapping()
|
||||||
|
propertyMapping.name = destinationAttribute.name
|
||||||
|
propertyMapping.valueExpression = NSExpression(format: "$\(NSMigrationSourceObjectKey).\(sourceAttribute.name)")
|
||||||
|
attributeMappings.append(propertyMapping)
|
||||||
|
}
|
||||||
|
return attributeMappings
|
||||||
|
}
|
||||||
|
let entityMappingName = entityMapping.name!
|
||||||
|
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||||
|
|
||||||
|
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||||
|
var relationshipMappings: [NSPropertyMapping] = []
|
||||||
|
for (_, destination) in destinationRelationships {
|
||||||
|
|
||||||
|
let destinationRelationship = destination.relationship
|
||||||
|
let propertyMapping = NSPropertyMapping()
|
||||||
|
propertyMapping.name = destinationRelationship.name
|
||||||
|
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"\(#selector(NSMigrationManager.destinationInstances(forEntityMappingName:sourceInstances:)))\" , \"\(entityMappingName)\", $\(NSMigrationSourceObjectKey))[0]")
|
||||||
|
relationshipMappings.append(propertyMapping)
|
||||||
|
}
|
||||||
|
return relationshipMappings
|
||||||
|
}
|
||||||
|
entityMappings.append(entityMapping)
|
||||||
|
}
|
||||||
|
for case .transformEntity(let sourceEntityName, let destinationEntityName, let transformEntity) in transformMappings {
|
||||||
|
|
||||||
|
let sourceEntity = sourceEntitiesByName[sourceEntityName]!
|
||||||
|
let destinationEntity = destinationEntitiesByName[destinationEntityName]!
|
||||||
|
|
||||||
|
let entityMapping = NSEntityMapping()
|
||||||
|
entityMapping.sourceEntityName = sourceEntity.name
|
||||||
|
entityMapping.sourceEntityVersionHash = sourceEntity.versionHash
|
||||||
|
entityMapping.destinationEntityName = destinationEntity.name
|
||||||
|
entityMapping.destinationEntityVersionHash = destinationEntity.versionHash
|
||||||
|
entityMapping.mappingType = .customEntityMappingType
|
||||||
|
entityMapping.sourceExpression = expression(forSource: sourceEntity)
|
||||||
|
entityMapping.entityMigrationPolicyClassName = NSStringFromClass(CustomEntityMigrationPolicy.self)
|
||||||
|
|
||||||
|
var userInfo: [AnyHashable: Any] = [
|
||||||
|
CustomEntityMigrationPolicy.UserInfoKey.transformer: transformEntity
|
||||||
|
]
|
||||||
|
autoreleasepool {
|
||||||
|
|
||||||
|
let sourceAttributes = sourceEntity.cs_resolvedAttributeRenamingIdentities()
|
||||||
|
let destinationAttributes = destinationEntity.cs_resolvedAttributeRenamingIdentities()
|
||||||
|
|
||||||
|
let transformedRenamingIdentifiers = Set(destinationAttributes.keys)
|
||||||
|
.intersection(sourceAttributes.keys)
|
||||||
|
|
||||||
|
var sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription] = [:]
|
||||||
|
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||||
|
|
||||||
|
let sourceAttribute = sourceAttributes[renamingIdentifier]!.attribute
|
||||||
|
let destinationAttribute = destinationAttributes[renamingIdentifier]!.attribute
|
||||||
|
sourceAttributesByDestinationKey[destinationAttribute.name] = sourceAttribute
|
||||||
|
}
|
||||||
|
userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] = sourceAttributesByDestinationKey
|
||||||
|
}
|
||||||
|
let entityMappingName = entityMapping.name!
|
||||||
|
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||||
|
|
||||||
|
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||||
|
var relationshipMappings: [NSPropertyMapping] = []
|
||||||
|
for (_, destination) in destinationRelationships {
|
||||||
|
|
||||||
|
let destinationRelationship = destination.relationship
|
||||||
|
let propertyMapping = NSPropertyMapping()
|
||||||
|
propertyMapping.name = destinationRelationship.name
|
||||||
|
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"\(#selector(NSMigrationManager.destinationInstances(forEntityMappingName:sourceInstances:)))\" , \"\(entityMappingName)\", $\(NSMigrationSourceObjectKey))[0]")
|
||||||
|
relationshipMappings.append(propertyMapping)
|
||||||
|
}
|
||||||
|
return relationshipMappings
|
||||||
|
}
|
||||||
|
entityMapping.userInfo = userInfo
|
||||||
|
entityMappings.append(entityMapping)
|
||||||
|
}
|
||||||
|
|
||||||
|
mappingModel.entityMappings = entityMappings
|
||||||
|
return (
|
||||||
|
mappingModel,
|
||||||
|
.heavyweight(
|
||||||
|
sourceVersion: self.sourceVersion,
|
||||||
|
destinationVersion: self.destinationVersion
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
// MARK: - CustomEntityMigrationPolicy
|
||||||
|
|
||||||
|
private final class CustomEntityMigrationPolicy: NSEntityMigrationPolicy {
|
||||||
|
|
||||||
|
// MARK: NSEntityMigrationPolicy
|
||||||
|
|
||||||
|
override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||||
|
|
||||||
|
let userInfo = mapping.userInfo!
|
||||||
|
let transformer = userInfo[CustomEntityMigrationPolicy.UserInfoKey.transformer]! as! CustomMapping.Transformer
|
||||||
|
let sourceAttributesByDestinationKey = userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] as! [KeyPath: NSAttributeDescription]
|
||||||
|
|
||||||
|
var destinationObject: UnsafeDestinationObject?
|
||||||
|
try transformer(
|
||||||
|
UnsafeSourceObject(sInstance),
|
||||||
|
{
|
||||||
|
if let destinationObject = destinationObject {
|
||||||
|
|
||||||
|
return destinationObject
|
||||||
|
}
|
||||||
|
let rawObject = NSEntityDescription.insertNewObject(
|
||||||
|
forEntityName: mapping.destinationEntityName!,
|
||||||
|
into: manager.destinationContext
|
||||||
|
)
|
||||||
|
destinationObject = UnsafeDestinationObject(rawObject, sourceAttributesByDestinationKey)
|
||||||
|
return destinationObject!
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if let dInstance = destinationObject?.rawObject {
|
||||||
|
|
||||||
|
manager.associate(
|
||||||
|
sourceInstance: sInstance,
|
||||||
|
withDestinationInstance: dInstance,
|
||||||
|
for: mapping
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func createRelationships(forDestination dInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws {
|
||||||
|
|
||||||
|
try super.createRelationships(forDestination: dInstance, in: mapping, manager: manager)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: FilePrivate
|
||||||
|
|
||||||
|
fileprivate enum UserInfoKey {
|
||||||
|
|
||||||
|
fileprivate static let transformer = "CoreStore.CustomEntityMigrationPolicy.transformer"
|
||||||
|
fileprivate static let sourceAttributesByDestinationKey = "CoreStore.CustomEntityMigrationPolicy.sourceAttributesByDestinationKey"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
private let entityMappings: Set<CustomMapping>
|
||||||
|
|
||||||
|
private func resolveEntityMappings(sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel) -> (delete: Set<CustomMapping>, insert: Set<CustomMapping>, copy: Set<CustomMapping>, transform: Set<CustomMapping>) {
|
||||||
|
|
||||||
|
var deleteMappings: Set<CustomMapping> = []
|
||||||
|
var insertMappings: Set<CustomMapping> = []
|
||||||
|
var copyMappings: Set<CustomMapping> = []
|
||||||
|
var transformMappings: Set<CustomMapping> = []
|
||||||
|
var allMappedSourceKeys: [KeyPath: KeyPath] = [:]
|
||||||
|
var allMappedDestinationKeys: [KeyPath: KeyPath] = [:]
|
||||||
|
|
||||||
|
let sourceRenamingIdentifiers = sourceModel.cs_resolvedRenamingIdentities()
|
||||||
|
let sourceEntityNames = sourceModel.entitiesByName
|
||||||
|
let destinationRenamingIdentifiers = destinationModel.cs_resolvedRenamingIdentities()
|
||||||
|
let destinationEntityNames = destinationModel.entitiesByName
|
||||||
|
|
||||||
|
let removedRenamingIdentifiers = Set(sourceRenamingIdentifiers.keys)
|
||||||
|
.subtracting(destinationRenamingIdentifiers.keys)
|
||||||
|
let addedRenamingIdentifiers = Set(destinationRenamingIdentifiers.keys)
|
||||||
|
.subtracting(sourceRenamingIdentifiers.keys)
|
||||||
|
let transformedRenamingIdentifiers = Set(destinationRenamingIdentifiers.keys)
|
||||||
|
.subtracting(addedRenamingIdentifiers)
|
||||||
|
.subtracting(removedRenamingIdentifiers)
|
||||||
|
|
||||||
|
// First pass: resolve source-destination entities
|
||||||
|
for mapping in self.entityMappings {
|
||||||
|
|
||||||
|
switch mapping {
|
||||||
|
|
||||||
|
case .deleteEntity(let sourceEntity):
|
||||||
|
CoreStore.assert(
|
||||||
|
sourceEntityNames[sourceEntity] != nil,
|
||||||
|
"A \(cs_typeName(CustomMapping.self)) with value '\(mapping)' passed to \(cs_typeName(CustomSchemaMappingProvider.self)) could not be mapped to any \(cs_typeName(NSEntityDescription.self)) from the source \(cs_typeName(NSManagedObjectModel.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
allMappedSourceKeys[sourceEntity] == nil,
|
||||||
|
"Duplicate \(cs_typeName(CustomMapping.self))s found for source entity name \"\(sourceEntity)\" in \(cs_typeName(CustomSchemaMappingProvider.self))."
|
||||||
|
)
|
||||||
|
deleteMappings.insert(mapping)
|
||||||
|
allMappedSourceKeys[sourceEntity] = ""
|
||||||
|
|
||||||
|
case .insertEntity(let destinationEntity):
|
||||||
|
CoreStore.assert(
|
||||||
|
destinationEntityNames[destinationEntity] != nil,
|
||||||
|
"A \(cs_typeName(CustomMapping.self)) with value '\(mapping)' passed to \(cs_typeName(CustomSchemaMappingProvider.self)) could not be mapped to any \(cs_typeName(NSEntityDescription.self)) from the destination \(cs_typeName(NSManagedObjectModel.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
allMappedDestinationKeys[destinationEntity] == nil,
|
||||||
|
"Duplicate \(cs_typeName(CustomMapping.self))s found for destination entity name \"\(destinationEntity)\" in \(cs_typeName(CustomSchemaMappingProvider.self))."
|
||||||
|
)
|
||||||
|
insertMappings.insert(mapping)
|
||||||
|
allMappedDestinationKeys[destinationEntity] = ""
|
||||||
|
|
||||||
|
case .transformEntity(let sourceEntity, let destinationEntity, _):
|
||||||
|
CoreStore.assert(
|
||||||
|
sourceEntityNames[sourceEntity] != nil,
|
||||||
|
"A \(cs_typeName(CustomMapping.self)) with value '\(mapping)' passed to \(cs_typeName(CustomSchemaMappingProvider.self)) could not be mapped to any \(cs_typeName(NSEntityDescription.self)) from the source \(cs_typeName(NSManagedObjectModel.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
destinationEntityNames[destinationEntity] != nil,
|
||||||
|
"A \(cs_typeName(CustomMapping.self)) with value '\(mapping)' passed to \(cs_typeName(CustomSchemaMappingProvider.self)) could not be mapped to any \(cs_typeName(NSEntityDescription.self)) from the destination \(cs_typeName(NSManagedObjectModel.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
allMappedSourceKeys[sourceEntity] == nil,
|
||||||
|
"Duplicate \(cs_typeName(CustomMapping.self))s found for source entity name \"\(sourceEntity)\" in \(cs_typeName(CustomSchemaMappingProvider.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
allMappedDestinationKeys[destinationEntity] == nil,
|
||||||
|
"Duplicate \(cs_typeName(CustomMapping.self))s found for destination entity name \"\(destinationEntity)\" in \(cs_typeName(CustomSchemaMappingProvider.self))."
|
||||||
|
)
|
||||||
|
transformMappings.insert(mapping)
|
||||||
|
allMappedSourceKeys[sourceEntity] = destinationEntity
|
||||||
|
allMappedDestinationKeys[destinationEntity] = sourceEntity
|
||||||
|
|
||||||
|
case .copyEntity(let sourceEntity, let destinationEntity):
|
||||||
|
CoreStore.assert(
|
||||||
|
sourceEntityNames[sourceEntity] != nil,
|
||||||
|
"A \(cs_typeName(CustomMapping.self)) with value '\(mapping)' passed to \(cs_typeName(CustomSchemaMappingProvider.self)) could not be mapped to any \(cs_typeName(NSEntityDescription.self)) from the source \(cs_typeName(NSManagedObjectModel.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
destinationEntityNames[destinationEntity] != nil,
|
||||||
|
"A \(cs_typeName(CustomMapping.self)) with value '\(mapping)' passed to \(cs_typeName(CustomSchemaMappingProvider.self)) could not be mapped to any \(cs_typeName(NSEntityDescription.self)) from the destination \(cs_typeName(NSManagedObjectModel.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
sourceEntityNames[sourceEntity]!.versionHash == destinationEntityNames[destinationEntity]!.versionHash,
|
||||||
|
"A \(cs_typeName(CustomMapping.self)) with value '\(mapping)' was passed to \(cs_typeName(CustomSchemaMappingProvider.self)) but the \(cs_typeName(NSEntityDescription.self))'s \"versionHash\" of the source and destination entities do not match."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
allMappedSourceKeys[sourceEntity] == nil,
|
||||||
|
"Duplicate \(cs_typeName(CustomMapping.self))s found for source entity name \"\(sourceEntity)\" in \(cs_typeName(CustomSchemaMappingProvider.self))."
|
||||||
|
)
|
||||||
|
CoreStore.assert(
|
||||||
|
allMappedDestinationKeys[destinationEntity] == nil,
|
||||||
|
"Duplicate \(cs_typeName(CustomMapping.self))s found for destination entity name \"\(destinationEntity)\" in \(cs_typeName(CustomSchemaMappingProvider.self))."
|
||||||
|
)
|
||||||
|
copyMappings.insert(mapping)
|
||||||
|
allMappedSourceKeys[sourceEntity] = destinationEntity
|
||||||
|
allMappedDestinationKeys[destinationEntity] = sourceEntity
|
||||||
|
}
|
||||||
|
|
||||||
|
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||||
|
|
||||||
|
let sourceEntity = sourceRenamingIdentifiers[renamingIdentifier]!.entity
|
||||||
|
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
|
||||||
|
let sourceEntityName = sourceEntity.name!
|
||||||
|
let destinationEntityName = destinationEntity.name!
|
||||||
|
switch (allMappedSourceKeys[sourceEntityName], allMappedDestinationKeys[destinationEntityName]) {
|
||||||
|
|
||||||
|
case (nil, nil):
|
||||||
|
if sourceEntity.versionHash == destinationEntity.versionHash {
|
||||||
|
|
||||||
|
copyMappings.insert(
|
||||||
|
.copyEntity(
|
||||||
|
sourceEntity: sourceEntityName,
|
||||||
|
destinationEntity: destinationEntityName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
transformMappings.insert(
|
||||||
|
.transformEntity(
|
||||||
|
sourceEntity: sourceEntityName,
|
||||||
|
destinationEntity: destinationEntityName,
|
||||||
|
transformer: CustomMapping.inferredTransformation
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
allMappedSourceKeys[sourceEntityName] = destinationEntityName
|
||||||
|
allMappedDestinationKeys[destinationEntityName] = sourceEntityName
|
||||||
|
|
||||||
|
case (""?, nil):
|
||||||
|
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||||
|
allMappedDestinationKeys[destinationEntityName] = ""
|
||||||
|
|
||||||
|
case (nil, ""?):
|
||||||
|
deleteMappings.insert(.deleteEntity(sourceEntity: sourceEntityName))
|
||||||
|
allMappedSourceKeys[sourceEntityName] = ""
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for renamingIdentifier in removedRenamingIdentifiers {
|
||||||
|
|
||||||
|
let sourceEntity = sourceRenamingIdentifiers[renamingIdentifier]!.entity
|
||||||
|
let sourceEntityName = sourceEntity.name!
|
||||||
|
switch allMappedSourceKeys[sourceEntityName] {
|
||||||
|
|
||||||
|
case nil:
|
||||||
|
deleteMappings.insert(.deleteEntity(sourceEntity: sourceEntityName))
|
||||||
|
allMappedSourceKeys[sourceEntityName] = ""
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for renamingIdentifier in addedRenamingIdentifiers {
|
||||||
|
|
||||||
|
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
|
||||||
|
let destinationEntityName = destinationEntity.name!
|
||||||
|
switch allMappedDestinationKeys[destinationEntityName] {
|
||||||
|
|
||||||
|
case nil:
|
||||||
|
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||||
|
allMappedDestinationKeys[destinationEntityName] = ""
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (deleteMappings, insertMappings, copyMappings, transformMappings)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,27 +31,6 @@ import CoreData
|
|||||||
|
|
||||||
public extension DataStack {
|
public extension DataStack {
|
||||||
|
|
||||||
/**
|
|
||||||
Asynchronously adds a `StorageInterface` with default settings to the stack. Migrations are also initiated by default.
|
|
||||||
```
|
|
||||||
dataStack.addStorage(
|
|
||||||
InMemoryStore.self,
|
|
||||||
completion: { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let storage): // ...
|
|
||||||
case .failure(let error): // ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
- parameter storeType: the storage type
|
|
||||||
- parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `SetupResult` argument indicates the result. Note that the `StorageInterface` associated to the `SetupResult.success` may not always be the same instance as the parameter argument if a previous `StorageInterface` was already added at the same URL and with the same configuration.
|
|
||||||
*/
|
|
||||||
public func addStorage<T: StorageInterface>(_ storeType: T.Type, completion: @escaping (SetupResult<T>) -> Void) where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
self.addStorage(storeType.init(), completion: completion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously adds a `StorageInterface` to the stack. Migrations are also initiated by default.
|
Asynchronously adds a `StorageInterface` to the stack. Migrations are also initiated by default.
|
||||||
```
|
```
|
||||||
@@ -109,28 +88,6 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Asynchronously adds a `LocalStorage` with default settings to the stack. Migrations are also initiated by default.
|
|
||||||
```
|
|
||||||
let migrationProgress = dataStack.addStorage(
|
|
||||||
SQLiteStore.self,
|
|
||||||
completion: { result in
|
|
||||||
switch result {
|
|
||||||
case .success(let storage): // ...
|
|
||||||
case .failure(let error): // ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
- parameter storeType: the local storage type
|
|
||||||
- parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `SetupResult` argument indicates the result. Note that the `LocalStorage` associated to the `SetupResult.success` may not always be the same instance as the parameter argument if a previous `LocalStorage` was already added at the same URL and with the same configuration.
|
|
||||||
- returns: a `Progress` instance if a migration has started, or `nil` if either no migrations are required or if a failure occured.
|
|
||||||
*/
|
|
||||||
public func addStorage<T: LocalStorage>(_ storeType: T.Type, completion: @escaping (SetupResult<T>) -> Void) -> Progress? where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
return self.addStorage(storeType.init() as! T.Type, completion: completion)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously adds a `LocalStorage` to the stack. Migrations are also initiated by default.
|
Asynchronously adds a `LocalStorage` to the stack. Migrations are also initiated by default.
|
||||||
```
|
```
|
||||||
@@ -216,9 +173,9 @@ public extension DataStack {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
try storage.eraseStorageAndWait(
|
try storage.cs_eraseStorageAndWait(
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
soureModelHint: self.model[metadata]
|
soureModelHint: self.schemaHistory.schema(for: metadata)?.rawModel()
|
||||||
)
|
)
|
||||||
_ = try self.addStorageAndWait(storage)
|
_ = try self.addStorageAndWait(storage)
|
||||||
|
|
||||||
@@ -382,7 +339,9 @@ public extension DataStack {
|
|||||||
at: cacheFileURL,
|
at: cacheFileURL,
|
||||||
options: storeOptions
|
options: storeOptions
|
||||||
)
|
)
|
||||||
_ = try self.model[metadata].flatMap(storage.eraseStorageAndWait)
|
_ = try self.schemaHistory
|
||||||
|
.schema(for: metadata)
|
||||||
|
.flatMap({ try storage.cs_eraseStorageAndWait(soureModel: $0.rawModel()) })
|
||||||
_ = try self.createPersistentStoreFromStorage(
|
_ = try self.createPersistentStoreFromStorage(
|
||||||
storage,
|
storage,
|
||||||
finalURL: cacheFileURL,
|
finalURL: cacheFileURL,
|
||||||
@@ -497,7 +456,7 @@ public extension DataStack {
|
|||||||
|
|
||||||
let error = CoreStoreError.mappingModelNotFound(
|
let error = CoreStoreError.mappingModelNotFound(
|
||||||
localStoreURL: fileURL,
|
localStoreURL: fileURL,
|
||||||
targetModel: self.model,
|
targetModel: self.schemaHistory.rawModel,
|
||||||
targetModelVersion: self.modelVersion
|
targetModelVersion: self.modelVersion
|
||||||
)
|
)
|
||||||
CoreStore.log(
|
CoreStore.log(
|
||||||
@@ -545,12 +504,12 @@ public extension DataStack {
|
|||||||
|
|
||||||
let error = CoreStoreError.mappingModelNotFound(
|
let error = CoreStoreError.mappingModelNotFound(
|
||||||
localStoreURL: storage.fileURL,
|
localStoreURL: storage.fileURL,
|
||||||
targetModel: self.model,
|
targetModel: self.schemaHistory.rawModel,
|
||||||
targetModelVersion: self.modelVersion
|
targetModelVersion: self.modelVersion
|
||||||
)
|
)
|
||||||
CoreStore.log(
|
CoreStore.log(
|
||||||
error,
|
error,
|
||||||
"Failed to find migration steps from \(cs_typeName(storage)) at URL \"\(storage.fileURL)\" to version model \"\(self.model)\"."
|
"Failed to find migration steps from \(cs_typeName(storage)) at URL \"\(storage.fileURL)\" to version model \"\(self.schemaHistory.rawModel)\"."
|
||||||
)
|
)
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
@@ -592,7 +551,7 @@ public extension DataStack {
|
|||||||
let progress = Progress(parent: nil, userInfo: nil)
|
let progress = Progress(parent: nil, userInfo: nil)
|
||||||
progress.totalUnitCount = numberOfMigrations
|
progress.totalUnitCount = numberOfMigrations
|
||||||
|
|
||||||
for (sourceModel, destinationModel, mappingModel, _) in migrationSteps {
|
for (sourceModel, destinationModel, mappingModel, migrationType) in migrationSteps {
|
||||||
|
|
||||||
progress.becomeCurrent(withPendingUnitCount: 1)
|
progress.becomeCurrent(withPendingUnitCount: 1)
|
||||||
|
|
||||||
@@ -621,7 +580,12 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
migrationResult = MigrationResult(error)
|
let migrationError = CoreStoreError(error)
|
||||||
|
CoreStore.log(
|
||||||
|
migrationError,
|
||||||
|
"Failed to migrate version model \"\(migrationType.sourceVersion)\" to version \"\(migrationType.destinationVersion)\"."
|
||||||
|
)
|
||||||
|
migrationResult = MigrationResult(migrationError)
|
||||||
cancelled = true
|
cancelled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -658,76 +622,56 @@ public extension DataStack {
|
|||||||
|
|
||||||
private func computeMigrationFromStorage<T: LocalStorage>(_ storage: T, metadata: [String: Any]) -> [(sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType)]? {
|
private func computeMigrationFromStorage<T: LocalStorage>(_ storage: T, metadata: [String: Any]) -> [(sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType)]? {
|
||||||
|
|
||||||
let model = self.model
|
let schemaHistory = self.schemaHistory
|
||||||
if model.isConfiguration(withName: storage.configuration, compatibleWithStoreMetadata: metadata) {
|
if schemaHistory.rawModel.isConfiguration(withName: storage.configuration, compatibleWithStoreMetadata: metadata) {
|
||||||
|
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let initialModel = model[metadata],
|
guard let initialSchema = schemaHistory.schema(for: metadata) else {
|
||||||
var currentVersion = initialModel.currentModelVersion else {
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
var currentVersion = initialSchema.modelVersion
|
||||||
let migrationChain: MigrationChain = self.migrationChain.empty
|
let migrationChain: MigrationChain = schemaHistory.migrationChain.isEmpty
|
||||||
? [currentVersion: model.currentModelVersion!]
|
? [currentVersion: schemaHistory.currentModelVersion]
|
||||||
: self.migrationChain
|
: schemaHistory.migrationChain
|
||||||
|
|
||||||
var migrationSteps = [(sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType)]()
|
var migrationSteps = [(sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType)]()
|
||||||
|
|
||||||
while let nextVersion = migrationChain.nextVersionFrom(currentVersion),
|
while let nextVersion = migrationChain.nextVersionFrom(currentVersion),
|
||||||
let sourceModel = model[currentVersion],
|
let sourceSchema = schemaHistory.schema(for: currentVersion),
|
||||||
sourceModel != model,
|
sourceSchema.modelVersion != schemaHistory.currentModelVersion,
|
||||||
let destinationModel = model[nextVersion] {
|
let destinationSchema = schemaHistory.schema(for: nextVersion) {
|
||||||
|
|
||||||
if let mappingModel = NSMappingModel(
|
let mappingProviders = storage.migrationMappingProviders
|
||||||
from: storage.mappingModelBundles,
|
do {
|
||||||
forSourceModel: sourceModel,
|
|
||||||
destinationModel: destinationModel) {
|
|
||||||
|
|
||||||
|
try withExtendedLifetime((sourceSchema.rawModel(), destinationSchema.rawModel())) { (sourceModel, destinationModel) in
|
||||||
|
|
||||||
|
let mapping = try mappingProviders.findMapping(
|
||||||
|
sourceSchema: sourceSchema,
|
||||||
|
destinationSchema: destinationSchema,
|
||||||
|
storage: storage
|
||||||
|
)
|
||||||
migrationSteps.append(
|
migrationSteps.append(
|
||||||
(
|
(
|
||||||
sourceModel: sourceModel,
|
sourceModel: sourceModel,
|
||||||
destinationModel: destinationModel,
|
destinationModel: destinationModel,
|
||||||
mappingModel: mappingModel,
|
mappingModel: mapping.mappingModel,
|
||||||
migrationType: .heavyweight(
|
migrationType: mapping.migrationType
|
||||||
sourceVersion: currentVersion,
|
|
||||||
destinationVersion: nextVersion
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
|
||||||
do {
|
|
||||||
|
|
||||||
let mappingModel = try NSMappingModel.inferredMappingModel(
|
|
||||||
forSourceModel: sourceModel,
|
|
||||||
destinationModel: destinationModel
|
|
||||||
)
|
|
||||||
|
|
||||||
migrationSteps.append(
|
|
||||||
(
|
|
||||||
sourceModel: sourceModel,
|
|
||||||
destinationModel: destinationModel,
|
|
||||||
mappingModel: mappingModel,
|
|
||||||
migrationType: .lightweight(
|
|
||||||
sourceVersion: currentVersion,
|
|
||||||
destinationVersion: nextVersion
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
currentVersion = nextVersion
|
currentVersion = nextVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
if migrationSteps.last?.destinationModel == model {
|
if migrationSteps.last?.destinationModel == schemaHistory.rawModel {
|
||||||
|
|
||||||
return migrationSteps
|
return migrationSteps
|
||||||
}
|
}
|
||||||
@@ -775,21 +719,8 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
do {
|
_ = try? fileManager.removeItem(at: temporaryFileURL)
|
||||||
|
throw CoreStoreError(error)
|
||||||
try fileManager.removeItem(at: temporaryFileURL)
|
|
||||||
}
|
|
||||||
catch _ { }
|
|
||||||
|
|
||||||
let sourceVersion = migrationManager.sourceModel.currentModelVersion ?? "???"
|
|
||||||
let destinationVersion = migrationManager.destinationModel.currentModelVersion ?? "???"
|
|
||||||
let migrationError = CoreStoreError(error)
|
|
||||||
CoreStore.log(
|
|
||||||
migrationError,
|
|
||||||
"Failed to migrate from version model \"\(sourceVersion)\" to version model \"\(destinationVersion)\"."
|
|
||||||
)
|
|
||||||
|
|
||||||
throw migrationError
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -806,21 +737,36 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
|
|
||||||
do {
|
_ = try? fileManager.removeItem(at: temporaryFileURL)
|
||||||
|
throw CoreStoreError(error)
|
||||||
try fileManager.removeItem(at: temporaryFileURL)
|
|
||||||
}
|
|
||||||
catch _ { }
|
|
||||||
|
|
||||||
let sourceVersion = migrationManager.sourceModel.currentModelVersion ?? "???"
|
|
||||||
let destinationVersion = migrationManager.destinationModel.currentModelVersion ?? "???"
|
|
||||||
let fileError = CoreStoreError(error)
|
|
||||||
CoreStore.log(
|
|
||||||
fileError,
|
|
||||||
"Failed to save store after migrating from version model \"\(sourceVersion)\" to version model \"\(destinationVersion)\"."
|
|
||||||
)
|
|
||||||
|
|
||||||
throw fileError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - FilePrivate
|
||||||
|
|
||||||
|
fileprivate extension Array where Element == SchemaMappingProvider {
|
||||||
|
|
||||||
|
func findMapping(sourceSchema: DynamicSchema, destinationSchema: DynamicSchema, storage: LocalStorage) throws -> (mappingModel: NSMappingModel, migrationType: MigrationType) {
|
||||||
|
|
||||||
|
for element in self {
|
||||||
|
|
||||||
|
switch element {
|
||||||
|
|
||||||
|
case let element as CustomSchemaMappingProvider
|
||||||
|
where element.sourceVersion == sourceSchema.modelVersion && element.destinationVersion == destinationSchema.modelVersion:
|
||||||
|
return try element.cs_createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||||
|
|
||||||
|
case let element as XcodeSchemaMappingProvider
|
||||||
|
where element.sourceVersion == sourceSchema.modelVersion && element.destinationVersion == destinationSchema.modelVersion:
|
||||||
|
return try element.cs_createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return try InferredSchemaMappingProvider()
|
||||||
|
.cs_createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,19 +27,18 @@ import Foundation
|
|||||||
import CoreData
|
import CoreData
|
||||||
|
|
||||||
|
|
||||||
#if os(iOS) || os(watchOS) || os(tvOS)
|
|
||||||
|
|
||||||
// MARK: - DataStack
|
// MARK: - DataStack
|
||||||
|
|
||||||
|
@available(OSX 10.12, *)
|
||||||
public extension DataStack {
|
public extension DataStack {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates an `ObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
|
Creates an `ObjectMonitor` for the specified `DynamicObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `DynamicObject`.
|
||||||
|
|
||||||
- parameter object: the `NSManagedObject` to observe changes from
|
- parameter object: the `DynamicObject` to observe changes from
|
||||||
- returns: a `ObjectMonitor` that monitors changes to `object`
|
- returns: a `ObjectMonitor` that monitors changes to `object`
|
||||||
*/
|
*/
|
||||||
public func monitorObject<T: NSManagedObject>(_ object: T) -> ObjectMonitor<T> {
|
public func monitorObject<T: DynamicObject>(_ object: T) -> ObjectMonitor<T> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -49,25 +48,25 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public func monitorList<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
public func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||||
|
|
||||||
return self.monitorList(from, fetchClauses)
|
return self.monitorList(from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public func monitorList<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
public func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -90,25 +89,25 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public func monitorList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
public func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||||
|
|
||||||
self.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
self.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public func monitorList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
public func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -132,27 +131,27 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public func monitorSectionedList<T: NSManagedObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
public func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||||
|
|
||||||
return self.monitorSectionedList(from, sectionBy, fetchClauses)
|
return self.monitorSectionedList(from, sectionBy, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
Creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||||
*/
|
*/
|
||||||
public func monitorSectionedList<T: NSManagedObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
public func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -176,27 +175,27 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public func monitorSectionedList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
public func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||||
|
|
||||||
self.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
self.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
Asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||||
|
|
||||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
*/
|
*/
|
||||||
public func monitorSectionedList<T: NSManagedObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
public func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -220,5 +219,3 @@ public extension DataStack {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -34,57 +34,57 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
// MARK: FetchableSource
|
// MARK: FetchableSource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.
|
Fetches the `DynamicObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.
|
||||||
|
|
||||||
- parameter object: a reference to the object created/fetched outside the `DataStack`
|
- parameter object: a reference to the object created/fetched outside the `DataStack`
|
||||||
- returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject>(_ object: T) -> T? {
|
public func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
|
||||||
|
|
||||||
return self.mainContext.fetchExisting(object)
|
return self.mainContext.fetchExisting(object)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instance in the `DataStack`'s context from an `NSManagedObjectID`.
|
Fetches the `DynamicObject` instance in the `DataStack`'s context from an `NSManagedObjectID`.
|
||||||
|
|
||||||
- parameter objectID: the `NSManagedObjectID` for the object
|
- parameter objectID: the `NSManagedObjectID` for the object
|
||||||
- returns: the `NSManagedObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject>(_ objectID: NSManagedObjectID) -> T? {
|
public func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||||
|
|
||||||
return self.mainContext.fetchExisting(objectID)
|
return self.mainContext.fetchExisting(objectID)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instances in the `DataStack`'s context from references created from a transaction or from a different managed object context.
|
Fetches the `DynamicObject` instances in the `DataStack`'s context from references created from a transaction or from a different managed object context.
|
||||||
|
|
||||||
- parameter objects: an array of `NSManagedObject`s created/fetched outside the `DataStack`
|
- parameter objects: an array of `DynamicObject`s created/fetched outside the `DataStack`
|
||||||
- returns: the `NSManagedObject` array for objects that exists in the `DataStack`
|
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||||
|
|
||||||
return self.mainContext.fetchExisting(objects)
|
return self.mainContext.fetchExisting(objects)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObject` instances in the `DataStack`'s context from a list of `NSManagedObjectID`.
|
Fetches the `DynamicObject` instances in the `DataStack`'s context from a list of `NSManagedObjectID`.
|
||||||
|
|
||||||
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
||||||
- returns: the `NSManagedObject` array for objects that exists in the `DataStack`
|
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||||
*/
|
*/
|
||||||
public func fetchExisting<T: NSManagedObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||||
|
|
||||||
return self.mainContext.fetchExisting(objectIDs)
|
return self.mainContext.fetchExisting(objectIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the first `DynamicObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s
|
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -94,13 +94,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the first `DynamicObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the first `NSManagedObject` instance that satisfies the specified `FetchClause`s
|
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -110,13 +110,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s
|
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -126,13 +126,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches all `NSManagedObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: all `NSManagedObject` instances that satisfy the specified `FetchClause`s
|
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -142,13 +142,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -158,13 +158,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the number of `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the number `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -174,13 +174,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -190,13 +190,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for the first `NSManagedObject` that satisfies the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -206,13 +206,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -222,13 +222,13 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fetches the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
|
|
||||||
- parameter from: a `From` clause indicating the entity type
|
- parameter from: a `From` clause indicating the entity type
|
||||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||||
- returns: the `NSManagedObjectID` for all `NSManagedObject`s that satisfy the specified `FetchClause`s
|
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||||
*/
|
*/
|
||||||
public func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -250,7 +250,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -269,7 +269,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -288,7 +288,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -307,7 +307,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||||
*/
|
*/
|
||||||
public func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||||
|
|
||||||
CoreStore.assert(
|
CoreStore.assert(
|
||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
@@ -322,8 +322,17 @@ extension DataStack: FetchableSource, QueryableSource {
|
|||||||
/**
|
/**
|
||||||
The internal `NSManagedObjectContext` managed by this instance. Using this context directly should typically be avoided, and is provided by CoreStore only for extremely specialized cases.
|
The internal `NSManagedObjectContext` managed by this instance. Using this context directly should typically be avoided, and is provided by CoreStore only for extremely specialized cases.
|
||||||
*/
|
*/
|
||||||
public func internalContext() -> NSManagedObjectContext {
|
public func unsafeContext() -> NSManagedObjectContext {
|
||||||
|
|
||||||
return self.mainContext
|
return self.mainContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Obsoleted
|
||||||
|
|
||||||
|
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
|
||||||
|
public func internalContext() -> NSManagedObjectContext {
|
||||||
|
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,35 +32,114 @@ import CoreData
|
|||||||
public extension DataStack {
|
public extension DataStack {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
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`.
|
||||||
|
|
||||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
- parameter 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)`.
|
||||||
*/
|
*/
|
||||||
public func beginAsynchronous(_ closure: @escaping (_ transaction: AsynchronousDataTransaction) -> Void) {
|
public func perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, completion: @escaping (AsynchronousDataTransaction.Result<T>) -> Void) {
|
||||||
|
|
||||||
AsynchronousDataTransaction(
|
self.perform(
|
||||||
mainContext: self.rootSavingContext,
|
asynchronous: task,
|
||||||
queue: self.childTransactionQueue,
|
success: { completion(.init(userInfo: $0)) },
|
||||||
closure: closure).perform()
|
failure: { completion(.init(error: $0)) }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
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 argument of the `success` closure. Any errors thrown from inside the `task` will be wrapped in a `CoreStoreError` and reported in the `failure` closure. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||||
|
|
||||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
- parameter 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`.
|
||||||
- returns: a `SaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
- parameter success: the closure executed after the save succeeds. The `T` argument of the closure will be the value returned from `task`.
|
||||||
|
- parameter failure: the closure executed if the save fails or if any errors are thrown within `task`. Cancelled `task`s will be indicated by `CoreStoreError.userCancelled`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||||
*/
|
*/
|
||||||
@discardableResult
|
public func perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, success: @escaping (T) -> Void, failure: @escaping (CoreStoreError) -> Void) {
|
||||||
public func beginSynchronous(_ closure: @escaping (_ transaction: SynchronousDataTransaction) -> Void) -> SaveResult? {
|
|
||||||
|
|
||||||
return SynchronousDataTransaction(
|
let transaction = AsynchronousDataTransaction(
|
||||||
mainContext: self.rootSavingContext,
|
mainContext: self.rootSavingContext,
|
||||||
queue: self.childTransactionQueue,
|
queue: self.childTransactionQueue
|
||||||
closure: closure).performAndWait()
|
)
|
||||||
|
transaction.transactionQueue.cs_async {
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
withExtendedLifetime((self, transaction), {})
|
||||||
|
}
|
||||||
|
let userInfo: T
|
||||||
|
do {
|
||||||
|
|
||||||
|
userInfo = try task(transaction)
|
||||||
|
}
|
||||||
|
catch let error as CoreStoreError {
|
||||||
|
|
||||||
|
DispatchQueue.main.async { failure(error) }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
catch let error {
|
||||||
|
|
||||||
|
DispatchQueue.main.async { failure(.userError(error: error)) }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
transaction.autoCommit { (_, error) in
|
||||||
|
|
||||||
|
if let error = error {
|
||||||
|
|
||||||
|
failure(error)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
success(userInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begins a non-contiguous transaction where `NSManagedObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms.
|
Performs a transaction synchronously 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 return value of `perform(synchronous:)`. Any errors thrown from inside the `task` will be rethrown from `perform(synchronous:)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||||
|
|
||||||
|
- parameter task: the synchronous non-escaping 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 waitForAllObservers: When `true`, this method waits for all observers to be notified of the changes before returning. This results in more predictable data update order, but may risk triggering deadlocks. When `false`, this method does not wait for observers to be notified of the changes before returning. This results in lower risk for deadlocks, but the updated data may not have been propagated to the `DataStack` after returning. Defaults to `true`.
|
||||||
|
- throws: a `CoreStoreError` value indicating the failure. Cancelled `task`s will be indicated by `CoreStoreError.userCancelled`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||||
|
- returns: the value returned from `task`
|
||||||
|
*/
|
||||||
|
public func perform<T>(synchronous task: ((_ transaction: SynchronousDataTransaction) throws -> T), waitForAllObservers: Bool = true) throws -> T {
|
||||||
|
|
||||||
|
let transaction = SynchronousDataTransaction(
|
||||||
|
mainContext: self.rootSavingContext,
|
||||||
|
queue: self.childTransactionQueue
|
||||||
|
)
|
||||||
|
return try transaction.transactionQueue.cs_sync {
|
||||||
|
|
||||||
|
defer {
|
||||||
|
|
||||||
|
withExtendedLifetime((self, transaction), {})
|
||||||
|
}
|
||||||
|
let userInfo: T
|
||||||
|
do {
|
||||||
|
|
||||||
|
userInfo = try withoutActuallyEscaping(task, do: { try $0(transaction) })
|
||||||
|
}
|
||||||
|
catch let error as CoreStoreError {
|
||||||
|
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
catch let error {
|
||||||
|
|
||||||
|
throw CoreStoreError.userError(error: error)
|
||||||
|
}
|
||||||
|
if case (_, let error?) = transaction.autoCommit(waitForMerge: waitForAllObservers) {
|
||||||
|
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
return userInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Begins a non-contiguous transaction where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. This is useful for making temporary changes, such as partially filled forms.
|
||||||
|
|
||||||
- prameter supportsUndo: `undo()`, `redo()`, and `rollback()` methods are only available when this parameter is `true`, otherwise those method will raise an exception. Defaults to `false`. Note that turning on Undo support may heavily impact performance especially on iOS or watchOS where memory is limited.
|
- prameter supportsUndo: `undo()`, `redo()`, and `rollback()` methods are only available when this parameter is `true`, otherwise those method will raise an exception. Defaults to `false`. Note that turning on Undo support may heavily impact performance especially on iOS or watchOS where memory is limited.
|
||||||
- returns: a `UnsafeDataTransaction` instance where creates, updates, and deletes can be made.
|
- returns: a `UnsafeDataTransaction` instance where creates, updates, and deletes can be made.
|
||||||
@@ -75,7 +154,7 @@ public extension DataStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Refreshes all registered objects `NSManagedObject`s in the `DataStack`.
|
Refreshes all registered objects `NSManagedObject`s or `CoreStoreObject`s in the `DataStack`.
|
||||||
*/
|
*/
|
||||||
public func refreshAndMergeAllObjects() {
|
public func refreshAndMergeAllObjects() {
|
||||||
|
|
||||||
@@ -83,7 +162,58 @@ public extension DataStack {
|
|||||||
Thread.isMainThread,
|
Thread.isMainThread,
|
||||||
"Attempted to refresh entities outside their designated queue."
|
"Attempted to refresh entities outside their designated queue."
|
||||||
)
|
)
|
||||||
|
|
||||||
self.mainContext.refreshAndMergeAllObjects()
|
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 nil: return nil
|
||||||
|
case (let hasChanges, nil)?: return SaveResult(hasChanges: hasChanges)
|
||||||
|
case (_, let error?)?: return SaveResult(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,43 +35,83 @@ import CoreData
|
|||||||
public final class DataStack: Equatable {
|
public final class DataStack: Equatable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes a `DataStack` from the model with the specified `modelName` in the specified `bundle`.
|
Convenience initializer for `DataStack` that creates a `SchemaHistory` from the model with the specified `modelName` in the specified `bundle`.
|
||||||
|
|
||||||
- parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
|
- parameter xcodeModelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set (e.g. in Unit Tests).
|
||||||
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
||||||
- parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
- parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
||||||
*/
|
*/
|
||||||
public convenience init(modelName: String = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
public convenience init(xcodeModelName: XcodeDataModelFileName = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
||||||
|
|
||||||
let model = NSManagedObjectModel.fromBundle(
|
self.init(
|
||||||
bundle,
|
schemaHistory: SchemaHistory(
|
||||||
modelName: modelName,
|
XcodeDataModelSchema.from(
|
||||||
modelVersionHints: migrationChain.leafVersions
|
modelName: xcodeModelName,
|
||||||
|
bundle: bundle,
|
||||||
|
migrationChain: migrationChain
|
||||||
|
),
|
||||||
|
migrationChain: migrationChain
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.init(model: model, migrationChain: migrationChain)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes a `DataStack` from an `NSManagedObjectModel`.
|
Convenience initializer for `DataStack` that creates a `SchemaHistory` from a list of `DynamicSchema` versions.
|
||||||
|
```
|
||||||
- parameter model: the `NSManagedObjectModel` for the stack
|
CoreStore.defaultStack = DataStack(
|
||||||
|
XcodeDataModelSchema(modelName: "MyModelV1"),
|
||||||
|
CoreStoreSchema(
|
||||||
|
modelVersion: "MyModelV2",
|
||||||
|
entities: [
|
||||||
|
Entity<Animal>("Animal"),
|
||||||
|
Entity<Person>("Person")
|
||||||
|
]
|
||||||
|
),
|
||||||
|
migrationChain: ["MyModelV1", "MyModelV2"]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
- parameter schema: an instance of `DynamicSchema`
|
||||||
|
- parameter otherSchema: a list of other `DynamicSchema` instances that represent present/previous/future model versions, in any order
|
||||||
- parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
- parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
||||||
*/
|
*/
|
||||||
public required init(model: NSManagedObjectModel, migrationChain: MigrationChain = nil) {
|
public convenience init(_ schema: DynamicSchema, _ otherSchema: DynamicSchema..., migrationChain: MigrationChain = nil) {
|
||||||
|
|
||||||
|
self.init(
|
||||||
|
schemaHistory: SchemaHistory(
|
||||||
|
allSchema: [schema] + otherSchema,
|
||||||
|
migrationChain: migrationChain
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializes a `DataStack` from a `SchemaHistory` instance.
|
||||||
|
```
|
||||||
|
CoreStore.defaultStack = DataStack(
|
||||||
|
schemaHistory: SchemaHistory(
|
||||||
|
XcodeDataModelSchema(modelName: "MyModelV1"),
|
||||||
|
CoreStoreSchema(
|
||||||
|
modelVersion: "MyModelV2",
|
||||||
|
entities: [
|
||||||
|
Entity<Animal>("Animal"),
|
||||||
|
Entity<Person>("Person")
|
||||||
|
]
|
||||||
|
),
|
||||||
|
migrationChain: ["MyModelV1", "MyModelV2"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
- parameter schemaHistory: the `SchemaHistory` for the stack
|
||||||
|
*/
|
||||||
|
public required init(schemaHistory: SchemaHistory) {
|
||||||
|
|
||||||
// TODO: test before release (rolled back)
|
// TODO: test before release (rolled back)
|
||||||
// _ = DataStack.isGloballyInitialized
|
// _ = DataStack.isGloballyInitialized
|
||||||
|
|
||||||
CoreStore.assert(
|
self.coordinator = NSPersistentStoreCoordinator(managedObjectModel: schemaHistory.rawModel)
|
||||||
migrationChain.valid,
|
|
||||||
"Invalid migration chain passed to the \(cs_typeName(DataStack.self)). Check that the model versions' order is correct and that no repetitions or ambiguities exist."
|
|
||||||
)
|
|
||||||
|
|
||||||
self.coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
|
|
||||||
self.rootSavingContext = NSManagedObjectContext.rootSavingContextForCoordinator(self.coordinator)
|
self.rootSavingContext = NSManagedObjectContext.rootSavingContextForCoordinator(self.coordinator)
|
||||||
self.mainContext = NSManagedObjectContext.mainContextForRootContext(self.rootSavingContext)
|
self.mainContext = NSManagedObjectContext.mainContextForRootContext(self.rootSavingContext)
|
||||||
self.model = model
|
self.schemaHistory = schemaHistory
|
||||||
self.migrationChain = migrationChain
|
|
||||||
|
|
||||||
self.rootSavingContext.parentStack = self
|
self.rootSavingContext.parentStack = self
|
||||||
|
|
||||||
@@ -79,19 +119,71 @@ public final class DataStack: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the `DataStack`'s model version. The version string is the same as the name of the version-specific .xcdatamodeld file.
|
Returns the `DataStack`'s current model version. `StorageInterface`s added to the stack will be migrated to this version.
|
||||||
*/
|
*/
|
||||||
public var modelVersion: String {
|
public var modelVersion: String {
|
||||||
|
|
||||||
return self.model.currentModelVersion!
|
return self.schemaHistory.currentModelVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the `DataStack`'s current model schema. `StorageInterface`s added to the stack will be migrated to this version.
|
||||||
|
*/
|
||||||
|
public var modelSchema: DynamicSchema {
|
||||||
|
|
||||||
|
return self.schemaHistory.schemaByVersion[self.schemaHistory.currentModelVersion]!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the entity name-to-class type mapping from the `DataStack`'s model.
|
Returns the entity name-to-class type mapping from the `DataStack`'s model.
|
||||||
*/
|
*/
|
||||||
public var entityTypesByName: [String: NSManagedObject.Type] {
|
public func entityTypesByName(for type: NSManagedObject.Type) -> [EntityName: NSManagedObject.Type] {
|
||||||
|
|
||||||
return self.model.entityTypesMapping()
|
var entityTypesByName: [EntityName: NSManagedObject.Type] = [:]
|
||||||
|
for (entityIdentifier, entityDescription) in self.schemaHistory.entityDescriptionsByEntityIdentifier {
|
||||||
|
|
||||||
|
switch entityIdentifier.category {
|
||||||
|
|
||||||
|
case .coreData:
|
||||||
|
let actualType = NSClassFromString(entityDescription.managedObjectClassName!)! as! NSManagedObject.Type
|
||||||
|
if (actualType as AnyClass).isSubclass(of: type) {
|
||||||
|
|
||||||
|
entityTypesByName[entityDescription.name!] = actualType
|
||||||
|
}
|
||||||
|
|
||||||
|
case .coreStore:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entityTypesByName
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the entity name-to-class type mapping from the `DataStack`'s model.
|
||||||
|
*/
|
||||||
|
public func entityTypesByName(for type: CoreStoreObject.Type) -> [EntityName: CoreStoreObject.Type] {
|
||||||
|
|
||||||
|
var entityTypesByName: [EntityName: CoreStoreObject.Type] = [:]
|
||||||
|
for (entityIdentifier, entityDescription) in self.schemaHistory.entityDescriptionsByEntityIdentifier {
|
||||||
|
|
||||||
|
switch entityIdentifier.category {
|
||||||
|
|
||||||
|
case .coreData:
|
||||||
|
continue
|
||||||
|
|
||||||
|
case .coreStore:
|
||||||
|
guard let anyEntity = entityDescription.coreStoreEntity else {
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let actualType = anyEntity.type
|
||||||
|
if (actualType as AnyClass).isSubclass(of: type) {
|
||||||
|
|
||||||
|
entityTypesByName[entityDescription.name!] = (actualType as! CoreStoreObject.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return entityTypesByName
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,10 +191,15 @@ public final class DataStack: Equatable {
|
|||||||
*/
|
*/
|
||||||
public func entityDescription(for type: NSManagedObject.Type) -> NSEntityDescription? {
|
public func entityDescription(for type: NSManagedObject.Type) -> NSEntityDescription? {
|
||||||
|
|
||||||
return NSEntityDescription.entity(
|
return self.entityDescription(for: EntityIdentifier(type))
|
||||||
forEntityName: self.model.entityNameForClass(type),
|
}
|
||||||
in: self.mainContext
|
|
||||||
)
|
/**
|
||||||
|
Returns the `NSEntityDescription` for the specified `CoreStoreObject` subclass.
|
||||||
|
*/
|
||||||
|
public func entityDescription(for type: CoreStoreObject.Type) -> NSEntityDescription? {
|
||||||
|
|
||||||
|
return self.entityDescription(for: EntityIdentifier(type))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,22 +221,7 @@ public final class DataStack: Equatable {
|
|||||||
@discardableResult
|
@discardableResult
|
||||||
public func addStorageAndWait() throws -> SQLiteStore {
|
public func addStorageAndWait() throws -> SQLiteStore {
|
||||||
|
|
||||||
return try self.addStorageAndWait(SQLiteStore.self)
|
return try self.addStorageAndWait(SQLiteStore())
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Creates a `StorageInterface` of the specified store type with default values and adds it to the stack. This method blocks until completion.
|
|
||||||
```
|
|
||||||
try dataStack.addStorageAndWait(InMemoryStore.self)
|
|
||||||
```
|
|
||||||
- parameter storeType: the `StorageInterface` type
|
|
||||||
- throws: a `CoreStoreError` value indicating the failure
|
|
||||||
- returns: the `StorageInterface` added to the stack
|
|
||||||
*/
|
|
||||||
@discardableResult
|
|
||||||
public func addStorageAndWait<T: StorageInterface>(_ storeType: T.Type) throws -> T where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
return try self.addStorageAndWait(storeType.init())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,21 +263,6 @@ public final class DataStack: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Creates a `LocalStorageInterface` of the specified store type with default values and adds it to the stack. This method blocks until completion.
|
|
||||||
```
|
|
||||||
try dataStack.addStorageAndWait(SQLiteStore.self)
|
|
||||||
```
|
|
||||||
- parameter storeType: the `LocalStorageInterface` type
|
|
||||||
- throws: a `CoreStoreError` value indicating the failure
|
|
||||||
- returns: the local storage added to the stack
|
|
||||||
*/
|
|
||||||
@discardableResult
|
|
||||||
public func addStorageAndWait<T: LocalStorage>(_ storageType: T.Type) throws -> T where T: DefaultInitializableStore {
|
|
||||||
|
|
||||||
return try self.addStorageAndWait(storageType.init())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Adds a `LocalStorage` to the stack and blocks until completion.
|
Adds a `LocalStorage` to the stack and blocks until completion.
|
||||||
```
|
```
|
||||||
@@ -264,9 +331,9 @@ public final class DataStack: Equatable {
|
|||||||
at: fileURL,
|
at: fileURL,
|
||||||
options: storeOptions
|
options: storeOptions
|
||||||
)
|
)
|
||||||
try storage.eraseStorageAndWait(
|
try storage.cs_eraseStorageAndWait(
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
soureModelHint: self.model[metadata]
|
soureModelHint: self.schemaHistory.schema(for: metadata)?.rawModel()
|
||||||
)
|
)
|
||||||
let finalStoreOptions = storage.dictionary(forOptions: storage.localStorageOptions)
|
let finalStoreOptions = storage.dictionary(forOptions: storage.localStorageOptions)
|
||||||
_ = try self.createPersistentStoreFromStorage(
|
_ = try self.createPersistentStoreFromStorage(
|
||||||
@@ -359,7 +426,9 @@ public final class DataStack: Equatable {
|
|||||||
at: cacheFileURL,
|
at: cacheFileURL,
|
||||||
options: storeOptions
|
options: storeOptions
|
||||||
)
|
)
|
||||||
_ = try self.model[metadata].flatMap(storage.eraseStorageAndWait)
|
_ = try self.schemaHistory
|
||||||
|
.schema(for: metadata)
|
||||||
|
.flatMap({ try storage.cs_eraseStorageAndWait(soureModel: $0.rawModel()) })
|
||||||
_ = try self.createPersistentStoreFromStorage(
|
_ = try self.createPersistentStoreFromStorage(
|
||||||
storage,
|
storage,
|
||||||
finalURL: cacheFileURL,
|
finalURL: cacheFileURL,
|
||||||
@@ -381,6 +450,21 @@ public final class DataStack: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: 3rd Party Utilities
|
||||||
|
|
||||||
|
/**
|
||||||
|
Allow external libraries to store custom data in the `DataStack`. App code should rarely have a need for this.
|
||||||
|
```
|
||||||
|
enum Static {
|
||||||
|
static var myDataKey: Void?
|
||||||
|
}
|
||||||
|
CoreStore.defaultStack.userInfo[&Static.myDataKey] = myObject
|
||||||
|
```
|
||||||
|
- Important: Do not use this method to store thread-sensitive data.
|
||||||
|
*/
|
||||||
|
public let userInfo = UserInfo()
|
||||||
|
|
||||||
|
|
||||||
// MARK: Equatable
|
// MARK: Equatable
|
||||||
|
|
||||||
public static func == (lhs: DataStack, rhs: DataStack) -> Bool {
|
public static func == (lhs: DataStack, rhs: DataStack) -> Bool {
|
||||||
@@ -391,16 +475,17 @@ public final class DataStack: Equatable {
|
|||||||
|
|
||||||
// MARK: Internal
|
// MARK: Internal
|
||||||
|
|
||||||
|
internal static var defaultConfigurationName = "PF_DEFAULT_CONFIGURATION_NAME"
|
||||||
|
|
||||||
internal static let applicationName = (Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String) ?? "CoreData"
|
internal static let applicationName = (Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String) ?? "CoreData"
|
||||||
|
|
||||||
internal let coordinator: NSPersistentStoreCoordinator
|
internal let coordinator: NSPersistentStoreCoordinator
|
||||||
internal let rootSavingContext: NSManagedObjectContext
|
internal let rootSavingContext: NSManagedObjectContext
|
||||||
internal let mainContext: NSManagedObjectContext
|
internal let mainContext: NSManagedObjectContext
|
||||||
internal let model: NSManagedObjectModel
|
internal let schemaHistory: SchemaHistory
|
||||||
internal let migrationChain: MigrationChain
|
|
||||||
internal let childTransactionQueue = DispatchQueue.serial("com.coreStore.dataStack.childTransactionQueue")
|
internal let childTransactionQueue = DispatchQueue.serial("com.coreStore.dataStack.childTransactionQueue")
|
||||||
internal let storeMetadataUpdateQueue = DispatchQueue.concurrent("com.coreStore.persistentStoreBarrierQueue")
|
internal let storeMetadataUpdateQueue = DispatchQueue.concurrent("com.coreStore.persistentStoreBarrierQueue")
|
||||||
internal let migrationQueue: OperationQueue = {
|
internal let migrationQueue: OperationQueue = cs_lazy {
|
||||||
|
|
||||||
let migrationQueue = OperationQueue()
|
let migrationQueue = OperationQueue()
|
||||||
migrationQueue.maxConcurrentOperationCount = 1
|
migrationQueue.maxConcurrentOperationCount = 1
|
||||||
@@ -408,7 +493,7 @@ public final class DataStack: Equatable {
|
|||||||
migrationQueue.qualityOfService = .utility
|
migrationQueue.qualityOfService = .utility
|
||||||
migrationQueue.underlyingQueue = DispatchQueue.serial("com.coreStore.migrationQueue", qos: .userInitiated)
|
migrationQueue.underlyingQueue = DispatchQueue.serial("com.coreStore.migrationQueue", qos: .userInitiated)
|
||||||
return migrationQueue
|
return migrationQueue
|
||||||
}()
|
}
|
||||||
|
|
||||||
internal func persistentStoreForStorage(_ storage: StorageInterface) -> NSPersistentStore? {
|
internal func persistentStoreForStorage(_ storage: StorageInterface) -> NSPersistentStore? {
|
||||||
|
|
||||||
@@ -417,34 +502,27 @@ public final class DataStack: Equatable {
|
|||||||
.first
|
.first
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func entityNameForEntityClass(_ entityClass: AnyClass) -> String? {
|
internal func persistentStores(for entityIdentifier: EntityIdentifier) -> [NSPersistentStore]? {
|
||||||
|
|
||||||
return self.model.entityNameForClass(entityClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func persistentStoresForEntityClass(_ entityClass: AnyClass) -> [NSPersistentStore]? {
|
|
||||||
|
|
||||||
var returnValue: [NSPersistentStore]? = nil
|
var returnValue: [NSPersistentStore]? = nil
|
||||||
self.storeMetadataUpdateQueue.sync(flags: .barrier) {
|
self.storeMetadataUpdateQueue.sync(flags: .barrier) {
|
||||||
|
|
||||||
returnValue = self.entityConfigurationsMapping[NSStringFromClass(entityClass)]?.map {
|
returnValue = self.finalConfigurationsByEntityIdentifier[entityIdentifier]?
|
||||||
|
.map({ self.persistentStoresByFinalConfiguration[$0]! }) ?? []
|
||||||
return self.configurationStoreMapping[$0]!
|
|
||||||
} ?? []
|
|
||||||
}
|
}
|
||||||
return returnValue
|
return returnValue
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func persistentStoreForEntityClass(_ entityClass: AnyClass, configuration: String?, inferStoreIfPossible: Bool) -> (store: NSPersistentStore?, isAmbiguous: Bool) {
|
internal func persistentStore(for entityIdentifier: EntityIdentifier, configuration: ModelConfiguration, inferStoreIfPossible: Bool) -> (store: NSPersistentStore?, isAmbiguous: Bool) {
|
||||||
|
|
||||||
return self.storeMetadataUpdateQueue.sync(flags: .barrier) { () -> (store: NSPersistentStore?, isAmbiguous: Bool) in
|
return self.storeMetadataUpdateQueue.sync(flags: .barrier) { () -> (store: NSPersistentStore?, isAmbiguous: Bool) in
|
||||||
|
|
||||||
let configurationsForEntity = self.entityConfigurationsMapping[NSStringFromClass(entityClass)] ?? []
|
let configurationsForEntity = self.finalConfigurationsByEntityIdentifier[entityIdentifier] ?? []
|
||||||
if let configuration = configuration {
|
if let configuration = configuration {
|
||||||
|
|
||||||
if configurationsForEntity.contains(configuration) {
|
if configurationsForEntity.contains(configuration) {
|
||||||
|
|
||||||
return (store: self.configurationStoreMapping[configuration], isAmbiguous: false)
|
return (store: self.persistentStoresByFinalConfiguration[configuration], isAmbiguous: false)
|
||||||
}
|
}
|
||||||
else if !inferStoreIfPossible {
|
else if !inferStoreIfPossible {
|
||||||
|
|
||||||
@@ -458,7 +536,7 @@ public final class DataStack: Equatable {
|
|||||||
return (store: nil, isAmbiguous: false)
|
return (store: nil, isAmbiguous: false)
|
||||||
|
|
||||||
case 1 where inferStoreIfPossible:
|
case 1 where inferStoreIfPossible:
|
||||||
return (store: self.configurationStoreMapping[configurationsForEntity.first!], isAmbiguous: false)
|
return (store: self.persistentStoresByFinalConfiguration[configurationsForEntity.first!], isAmbiguous: false)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (store: nil, isAmbiguous: true)
|
return (store: nil, isAmbiguous: true)
|
||||||
@@ -479,7 +557,7 @@ public final class DataStack: Equatable {
|
|||||||
self.storeMetadataUpdateQueue.async(flags: .barrier) {
|
self.storeMetadataUpdateQueue.async(flags: .barrier) {
|
||||||
|
|
||||||
let configurationName = persistentStore.configurationName
|
let configurationName = persistentStore.configurationName
|
||||||
self.configurationStoreMapping[configurationName] = persistentStore
|
self.persistentStoresByFinalConfiguration[configurationName] = persistentStore
|
||||||
for entityDescription in (self.coordinator.managedObjectModel.entities(forConfigurationName: configurationName) ?? []) {
|
for entityDescription in (self.coordinator.managedObjectModel.entities(forConfigurationName: configurationName) ?? []) {
|
||||||
|
|
||||||
let managedObjectClassName = entityDescription.managedObjectClassName!
|
let managedObjectClassName = entityDescription.managedObjectClassName!
|
||||||
@@ -487,18 +565,23 @@ public final class DataStack: Equatable {
|
|||||||
NSClassFromString(managedObjectClassName) != nil,
|
NSClassFromString(managedObjectClassName) != nil,
|
||||||
"The class \(cs_typeName(managedObjectClassName)) for the entity \(cs_typeName(entityDescription.name)) does not exist. Check if the subclass type and module name are properly configured."
|
"The class \(cs_typeName(managedObjectClassName)) for the entity \(cs_typeName(entityDescription.name)) does not exist. Check if the subclass type and module name are properly configured."
|
||||||
)
|
)
|
||||||
|
let entityIdentifier = EntityIdentifier(entityDescription)
|
||||||
|
if self.finalConfigurationsByEntityIdentifier[entityIdentifier] == nil {
|
||||||
|
|
||||||
if self.entityConfigurationsMapping[managedObjectClassName] == nil {
|
self.finalConfigurationsByEntityIdentifier[entityIdentifier] = []
|
||||||
|
|
||||||
self.entityConfigurationsMapping[managedObjectClassName] = []
|
|
||||||
}
|
}
|
||||||
self.entityConfigurationsMapping[managedObjectClassName]?.insert(configurationName)
|
self.finalConfigurationsByEntityIdentifier[entityIdentifier]?.insert(configurationName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
storage.didAddToDataStack(self)
|
storage.cs_didAddToDataStack(self)
|
||||||
return persistentStore
|
return persistentStore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal func entityDescription(for entityIdentifier: EntityIdentifier) -> NSEntityDescription? {
|
||||||
|
|
||||||
|
return self.schemaHistory.entityDescriptionsByEntityIdentifier[entityIdentifier]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
@@ -509,8 +592,8 @@ public final class DataStack: Equatable {
|
|||||||
// return true
|
// return true
|
||||||
// }()
|
// }()
|
||||||
|
|
||||||
private var configurationStoreMapping = [String: NSPersistentStore]()
|
private var persistentStoresByFinalConfiguration = [String: NSPersistentStore]()
|
||||||
private var entityConfigurationsMapping = [String: Set<String>]()
|
private var finalConfigurationsByEntityIdentifier = [EntityIdentifier: Set<String>]()
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
|
||||||
@@ -530,13 +613,51 @@ public final class DataStack: Equatable {
|
|||||||
|
|
||||||
// MARK: Deprecated
|
// MARK: Deprecated
|
||||||
|
|
||||||
@available(*, deprecated: 3.0.0, renamed: "entityDescription(for:)")
|
@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? {
|
public func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
|
||||||
|
|
||||||
return self.entityDescription(for: type)
|
return self.entityDescription(for: type)
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(*, deprecated: 3.0.0, renamed: "objectID(forURIRepresentation:)")
|
@available(*, obsoleted: 3.1, renamed: "objectID(forURIRepresentation:)")
|
||||||
public func objectIDForURIRepresentation(_ url: URL) -> NSManagedObjectID? {
|
public func objectIDForURIRepresentation(_ url: URL) -> NSManagedObjectID? {
|
||||||
|
|
||||||
return self.objectID(forURIRepresentation: url)
|
return self.objectID(forURIRepresentation: url)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import Foundation
|
|||||||
|
|
||||||
internal extension DispatchQueue {
|
internal extension DispatchQueue {
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc @inline(__always)
|
||||||
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
||||||
|
|
||||||
return DispatchQueue(
|
return DispatchQueue(
|
||||||
@@ -42,7 +42,7 @@ internal extension DispatchQueue {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc @inline(__always)
|
||||||
internal static func concurrent(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
internal static func concurrent(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
||||||
|
|
||||||
return DispatchQueue(
|
return DispatchQueue(
|
||||||
@@ -57,31 +57,36 @@ internal extension DispatchQueue {
|
|||||||
@nonobjc
|
@nonobjc
|
||||||
internal func cs_isCurrentExecutionContext() -> Bool {
|
internal func cs_isCurrentExecutionContext() -> Bool {
|
||||||
|
|
||||||
|
enum Static {
|
||||||
|
|
||||||
|
static let specificKey = DispatchSpecificKey<ObjectIdentifier>()
|
||||||
|
}
|
||||||
|
|
||||||
let specific = ObjectIdentifier(self)
|
let specific = ObjectIdentifier(self)
|
||||||
|
|
||||||
self.setSpecific(key: Static.specificKey, value: specific)
|
self.setSpecific(key: Static.specificKey, value: specific)
|
||||||
return DispatchQueue.getSpecific(key: Static.specificKey) == specific
|
return DispatchQueue.getSpecific(key: Static.specificKey) == specific
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc @inline(__always)
|
||||||
internal func cs_sync<T>(_ closure: () throws -> T) rethrows -> T {
|
internal func cs_sync<T>(_ closure: () throws -> T) rethrows -> T {
|
||||||
|
|
||||||
return try self.sync { try autoreleasepool(invoking: closure) }
|
return try self.sync { try autoreleasepool(invoking: closure) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc @inline(__always)
|
||||||
internal func cs_async(_ closure: @escaping () -> Void) {
|
internal func cs_async(_ closure: @escaping () -> Void) {
|
||||||
|
|
||||||
self.async { autoreleasepool(invoking: closure) }
|
self.async { autoreleasepool(invoking: closure) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc @inline(__always)
|
||||||
internal func cs_barrierSync<T>(_ closure: () throws -> T) rethrows -> T {
|
internal func cs_barrierSync<T>(_ closure: () throws -> T) rethrows -> T {
|
||||||
|
|
||||||
return try self.sync(flags: .barrier) { try autoreleasepool(invoking: closure) }
|
return try self.sync(flags: .barrier) { try autoreleasepool(invoking: closure) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc
|
@nonobjc @inline(__always)
|
||||||
internal func cs_barrierAsync(_ closure: @escaping () -> Void) {
|
internal func cs_barrierAsync(_ closure: @escaping () -> Void) {
|
||||||
|
|
||||||
self.async(flags: .barrier) { autoreleasepool(invoking: closure) }
|
self.async(flags: .barrier) { autoreleasepool(invoking: closure) }
|
||||||
@@ -89,9 +94,4 @@ internal extension DispatchQueue {
|
|||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private enum Static {
|
|
||||||
|
|
||||||
static let specificKey = DispatchSpecificKey<ObjectIdentifier>()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
168
Sources/DynamicObject.swift
Normal file
168
Sources/DynamicObject.swift
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
//
|
||||||
|
// DynamicObject.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - DynamicObject
|
||||||
|
|
||||||
|
/**
|
||||||
|
All CoreStore's utilities are designed around `DynamicObject` instances. `NSManagedObject` and `CoreStoreObject` instances all conform to `DynamicObject`.
|
||||||
|
*/
|
||||||
|
public protocol DynamicObject: class {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used internally by CoreStore. Do not call directly.
|
||||||
|
*/
|
||||||
|
static func cs_forceCreate(entityDescription: NSEntityDescription, into context: NSManagedObjectContext, assignTo store: NSPersistentStore) -> Self
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used internally by CoreStore. Do not call directly.
|
||||||
|
*/
|
||||||
|
static func cs_fromRaw(object: NSManagedObject) -> Self
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used internally by CoreStore. Do not call directly.
|
||||||
|
*/
|
||||||
|
static func cs_matches(object: NSManagedObject) -> Bool
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used internally by CoreStore. Do not call directly.
|
||||||
|
*/
|
||||||
|
func cs_id() -> NSManagedObjectID
|
||||||
|
|
||||||
|
/**
|
||||||
|
Used internally by CoreStore. Do not call directly.
|
||||||
|
*/
|
||||||
|
func cs_toRaw() -> NSManagedObject
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - NSManagedObject
|
||||||
|
|
||||||
|
extension NSManagedObject: DynamicObject {
|
||||||
|
|
||||||
|
// MARK: DynamicObject
|
||||||
|
|
||||||
|
public class func cs_forceCreate(entityDescription: NSEntityDescription, into context: NSManagedObjectContext, assignTo store: NSPersistentStore) -> Self {
|
||||||
|
|
||||||
|
let object = self.init(entity: entityDescription, insertInto: context)
|
||||||
|
defer {
|
||||||
|
|
||||||
|
context.assign(object, to: store)
|
||||||
|
}
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
|
||||||
|
public class func cs_fromRaw(object: NSManagedObject) -> Self {
|
||||||
|
|
||||||
|
@inline(__always)
|
||||||
|
func forceCast<T: NSManagedObject>(_ value: Any) -> T {
|
||||||
|
|
||||||
|
return value as! T
|
||||||
|
}
|
||||||
|
return forceCast(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func cs_matches(object: NSManagedObject) -> Bool {
|
||||||
|
|
||||||
|
return object.isKind(of: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func cs_id() -> NSManagedObjectID {
|
||||||
|
|
||||||
|
return self.objectID
|
||||||
|
}
|
||||||
|
|
||||||
|
public func cs_toRaw() -> NSManagedObject {
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - CoreStoreObject
|
||||||
|
|
||||||
|
extension CoreStoreObject {
|
||||||
|
|
||||||
|
// MARK: DynamicObject
|
||||||
|
|
||||||
|
public class func cs_forceCreate(entityDescription: NSEntityDescription, into context: NSManagedObjectContext, assignTo store: NSPersistentStore) -> Self {
|
||||||
|
|
||||||
|
let type = NSClassFromString(entityDescription.managedObjectClassName!)! as! NSManagedObject.Type
|
||||||
|
let object = type.init(entity: entityDescription, insertInto: context)
|
||||||
|
defer {
|
||||||
|
|
||||||
|
context.assign(object, to: store)
|
||||||
|
}
|
||||||
|
return self.cs_fromRaw(object: object)
|
||||||
|
}
|
||||||
|
|
||||||
|
public class func cs_fromRaw(object: NSManagedObject) -> Self {
|
||||||
|
|
||||||
|
if let coreStoreObject = object.coreStoreObject {
|
||||||
|
|
||||||
|
@inline(__always)
|
||||||
|
func forceCast<T: CoreStoreObject>(_ value: CoreStoreObject) -> T {
|
||||||
|
|
||||||
|
return value as! T
|
||||||
|
}
|
||||||
|
return forceCast(coreStoreObject)
|
||||||
|
}
|
||||||
|
let coreStoreObject = self.init(rawObject: object)
|
||||||
|
object.coreStoreObject = coreStoreObject
|
||||||
|
return coreStoreObject
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func cs_matches(object: NSManagedObject) -> Bool {
|
||||||
|
|
||||||
|
guard let type = object.entity.coreStoreEntity?.type else {
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (self as AnyClass).isSubclass(of: type as AnyClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func cs_id() -> NSManagedObjectID {
|
||||||
|
|
||||||
|
return self.rawObject!.objectID
|
||||||
|
}
|
||||||
|
|
||||||
|
public func cs_toRaw() -> NSManagedObject {
|
||||||
|
|
||||||
|
return self.rawObject!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - Internal
|
||||||
|
|
||||||
|
internal extension DynamicObject where Self: CoreStoreObject {
|
||||||
|
|
||||||
|
internal static var meta: Self {
|
||||||
|
|
||||||
|
return self.init(asMeta: ())
|
||||||
|
}
|
||||||
|
}
|
||||||
296
Sources/DynamicSchema+Convenience.swift
Normal file
296
Sources/DynamicSchema+Convenience.swift
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
//
|
||||||
|
// DynamicSchema+Convenience.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - DynamicSchema
|
||||||
|
|
||||||
|
public 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.
|
||||||
|
|
||||||
|
- Important: After transitioning to the new `CoreStoreSchema` framework, it is recommended to add the new schema as a new version that the existing versions' `XcodeDataModelSchema` can migrate to. It is discouraged to load existing SQLite files created with `XcodeDataModelSchema` directly into a `CoreStoreSchema`.
|
||||||
|
- returns: a string that represents the source code for the `DynamicSchema` as their corresponding `CoreStoreObject` Swift declarations.
|
||||||
|
*/
|
||||||
|
public func printCoreStoreSchema() -> String {
|
||||||
|
|
||||||
|
let model = self.rawModel()
|
||||||
|
let entitiesByName = model.entitiesByName
|
||||||
|
|
||||||
|
var output = "/// Generated by CoreStore on \(DateFormatter.localizedString(from: Date(), dateStyle: .short, timeStyle: .short))\n"
|
||||||
|
var addedInverse: Set<String> = []
|
||||||
|
for (entityName, entity) in entitiesByName {
|
||||||
|
|
||||||
|
let superName: String
|
||||||
|
if let superEntity = entity.superentity {
|
||||||
|
|
||||||
|
superName = superEntity.name!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
superName = String(describing: CoreStoreObject.self)
|
||||||
|
}
|
||||||
|
output.append("class \(entityName): \(superName) {\n")
|
||||||
|
defer {
|
||||||
|
|
||||||
|
output.append("}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
let attributesByName = entity.attributesByName
|
||||||
|
if !attributesByName.isEmpty {
|
||||||
|
|
||||||
|
output.append(" \n")
|
||||||
|
for (attributeName, attribute) in attributesByName {
|
||||||
|
|
||||||
|
let containerType: String
|
||||||
|
if attribute.attributeType == .transformableAttributeType {
|
||||||
|
|
||||||
|
if attribute.isOptional {
|
||||||
|
|
||||||
|
containerType = "Transformable.Optional"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
containerType = "Transformable.Required"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if attribute.isOptional {
|
||||||
|
|
||||||
|
containerType = "Value.Optional"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
containerType = "Value.Required"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let valueType: Any.Type
|
||||||
|
var defaultString = ""
|
||||||
|
switch attribute.attributeType {
|
||||||
|
|
||||||
|
case .integer16AttributeType:
|
||||||
|
valueType = Int16.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Int16.ImportableNativeType?).flatMap(Int16.cs_fromImportableNativeType),
|
||||||
|
defaultValue != Int16.cs_emptyValue() {
|
||||||
|
|
||||||
|
defaultString = ", default: \(defaultValue)"
|
||||||
|
}
|
||||||
|
case .integer32AttributeType:
|
||||||
|
valueType = Int32.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Int32.ImportableNativeType?).flatMap(Int32.cs_fromImportableNativeType),
|
||||||
|
defaultValue != Int32.cs_emptyValue() {
|
||||||
|
|
||||||
|
defaultString = ", default: \(defaultValue)"
|
||||||
|
}
|
||||||
|
case .integer64AttributeType:
|
||||||
|
valueType = Int64.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Int64.ImportableNativeType?).flatMap(Int64.cs_fromImportableNativeType),
|
||||||
|
defaultValue != Int64.cs_emptyValue() {
|
||||||
|
|
||||||
|
defaultString = ", default: \(defaultValue)"
|
||||||
|
}
|
||||||
|
case .decimalAttributeType:
|
||||||
|
valueType = NSDecimalNumber.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! NSDecimalNumber.ImportableNativeType?).flatMap(NSDecimalNumber.cs_fromImportableNativeType),
|
||||||
|
defaultValue != NSDecimalNumber.cs_emptyValue() {
|
||||||
|
|
||||||
|
defaultString = ", default: NSDecimalNumber(string: \"\(defaultValue.description(withLocale: nil))\")"
|
||||||
|
}
|
||||||
|
case .doubleAttributeType:
|
||||||
|
valueType = Double.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Double.ImportableNativeType?).flatMap(Double.cs_fromImportableNativeType),
|
||||||
|
defaultValue != Double.cs_emptyValue() {
|
||||||
|
|
||||||
|
defaultString = ", default: \(defaultValue)"
|
||||||
|
}
|
||||||
|
case .floatAttributeType:
|
||||||
|
valueType = Float.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Float.ImportableNativeType?).flatMap(Float.cs_fromImportableNativeType),
|
||||||
|
defaultValue != Float.cs_emptyValue() {
|
||||||
|
|
||||||
|
defaultString = ", default: \(defaultValue)"
|
||||||
|
}
|
||||||
|
case .stringAttributeType:
|
||||||
|
valueType = String.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! String.ImportableNativeType?).flatMap(String.cs_fromImportableNativeType),
|
||||||
|
defaultValue != String.cs_emptyValue() {
|
||||||
|
|
||||||
|
// TODO: escape strings
|
||||||
|
defaultString = ", default: \"\(defaultValue)\""
|
||||||
|
}
|
||||||
|
case .booleanAttributeType:
|
||||||
|
valueType = Bool.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Bool.ImportableNativeType?).flatMap(Bool.cs_fromImportableNativeType),
|
||||||
|
defaultValue != Bool.cs_emptyValue() {
|
||||||
|
|
||||||
|
defaultString = ", default: \(defaultValue ? "true" : "false")"
|
||||||
|
}
|
||||||
|
case .dateAttributeType:
|
||||||
|
valueType = Date.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Date.ImportableNativeType?).flatMap(Date.cs_fromImportableNativeType) {
|
||||||
|
|
||||||
|
defaultString = ", default: Date(timeIntervalSinceReferenceDate: \(defaultValue.timeIntervalSinceReferenceDate))"
|
||||||
|
}
|
||||||
|
case .binaryDataAttributeType:
|
||||||
|
valueType = Data.self
|
||||||
|
if let defaultValue = (attribute.defaultValue as! Data.ImportableNativeType?).flatMap(Data.cs_fromImportableNativeType),
|
||||||
|
defaultValue != Data.cs_emptyValue() {
|
||||||
|
|
||||||
|
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))")" })
|
||||||
|
}
|
||||||
|
defaultString = ", default: Data(bytes: [\(bytes.joined(separator: ", "))])"
|
||||||
|
}
|
||||||
|
case .transformableAttributeType:
|
||||||
|
if let attributeValueClassName = attribute.attributeValueClassName {
|
||||||
|
|
||||||
|
valueType = NSClassFromString(attributeValueClassName)!
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
valueType = (NSCoding & NSCopying).self
|
||||||
|
}
|
||||||
|
if let defaultValue = attribute.defaultValue {
|
||||||
|
|
||||||
|
defaultString = ", default: /* \"\(defaultValue)\" */"
|
||||||
|
}
|
||||||
|
else if !attribute.isOptional {
|
||||||
|
|
||||||
|
defaultString = ", default: /* required */"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
fatalError("Unsupported attribute type: \(attribute.attributeType.rawValue)")
|
||||||
|
}
|
||||||
|
let indexedString = attribute.isIndexed ? ", isIndexed: true" : ""
|
||||||
|
let transientString = attribute.isTransient ? ", isTransient: true" : ""
|
||||||
|
// TODO: escape strings
|
||||||
|
let versionHashModifierString = attribute.versionHashModifier
|
||||||
|
.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||||
|
// TODO: escape strings
|
||||||
|
let renamingIdentifierString = attribute.renamingIdentifier
|
||||||
|
.flatMap({ ($0 == attributeName ? "" : ", renamingIdentifier: \"\($0)\"") as String }) ?? ""
|
||||||
|
output.append(" let \(attributeName) = \(containerType)<\(String(describing: valueType))>(\"\(attributeName)\"\(indexedString)\(defaultString)\(transientString)\(versionHashModifierString)\(renamingIdentifierString))\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let relationshipsByName = entity.relationshipsByName
|
||||||
|
if !relationshipsByName.isEmpty {
|
||||||
|
|
||||||
|
output.append(" \n")
|
||||||
|
for (relationshipName, relationship) in relationshipsByName {
|
||||||
|
|
||||||
|
let containerType: String
|
||||||
|
var minCountString = ""
|
||||||
|
var maxCountString = ""
|
||||||
|
if relationship.isToMany {
|
||||||
|
|
||||||
|
let minCount = relationship.minCount
|
||||||
|
let maxCount = relationship.maxCount
|
||||||
|
if relationship.isOrdered {
|
||||||
|
|
||||||
|
containerType = "Relationship.ToManyOrdered"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
containerType = "Relationship.ToManyUnordered"
|
||||||
|
}
|
||||||
|
if minCount > 0 {
|
||||||
|
|
||||||
|
minCountString = ", minCount: \(minCount)"
|
||||||
|
}
|
||||||
|
if maxCount > 0 {
|
||||||
|
|
||||||
|
maxCountString = ", maxCount: \(maxCount)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
containerType = "Relationship.ToOne"
|
||||||
|
}
|
||||||
|
var inverseString = ""
|
||||||
|
let relationshipQualifier = "\(entityName).\(relationshipName)"
|
||||||
|
if !addedInverse.contains(relationshipQualifier),
|
||||||
|
let inverseRelationship = relationship.inverseRelationship {
|
||||||
|
|
||||||
|
inverseString = ", inverse: { $0.\(inverseRelationship.name) }"
|
||||||
|
addedInverse.insert("\(relationship.destinationEntity!.name!).\(inverseRelationship.name)")
|
||||||
|
}
|
||||||
|
var deleteRuleString = ""
|
||||||
|
if relationship.deleteRule != .nullifyDeleteRule {
|
||||||
|
|
||||||
|
switch relationship.deleteRule {
|
||||||
|
|
||||||
|
case .cascadeDeleteRule:
|
||||||
|
deleteRuleString = ", deleteRule: .cascade"
|
||||||
|
|
||||||
|
case .denyDeleteRule:
|
||||||
|
deleteRuleString = ", deleteRule: .deny"
|
||||||
|
|
||||||
|
case .nullifyDeleteRule:
|
||||||
|
deleteRuleString = ", deleteRule: .nullify"
|
||||||
|
|
||||||
|
default:
|
||||||
|
fatalError("Unsupported delete rule \((relationship.deleteRule)) for relationship \"\(relationshipQualifier)\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let versionHashModifierString = relationship.versionHashModifier
|
||||||
|
.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||||
|
let renamingIdentifierString = relationship.renamingIdentifier
|
||||||
|
.flatMap({ ($0 == relationshipName ? "" : ", renamingIdentifier: \"\($0)\"") as String }) ?? ""
|
||||||
|
output.append(" let \(relationshipName) = \(containerType)<\(relationship.destinationEntity!.name!)>(\"\(relationshipName)\"\(inverseString)\(deleteRuleString)\(minCountString)\(maxCountString)\(versionHashModifierString)\(renamingIdentifierString))\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.append("\n\n\n")
|
||||||
|
output.append("CoreStoreSchema(\n")
|
||||||
|
output.append(" modelVersion: \"\(self.modelVersion)\",\n")
|
||||||
|
output.append(" entities: [\n")
|
||||||
|
for (entityName, entity) in entitiesByName {
|
||||||
|
|
||||||
|
var abstractString = ""
|
||||||
|
if entity.isAbstract {
|
||||||
|
|
||||||
|
abstractString = ", isAbstract: true"
|
||||||
|
}
|
||||||
|
var versionHashModifierString = ""
|
||||||
|
if let versionHashModifier = entity.versionHashModifier {
|
||||||
|
|
||||||
|
versionHashModifierString = ", versionHashModifier: \"\(versionHashModifier)\""
|
||||||
|
}
|
||||||
|
output.append(" Entity<\(entityName)>(\"\(entityName)\"\(abstractString)\(versionHashModifierString)),\n")
|
||||||
|
}
|
||||||
|
output.append(" ],\n")
|
||||||
|
output.append(" versionLock: \(VersionLock(entityVersionHashesByName: model.entityVersionHashesByName).description.components(separatedBy: "\n").joined(separator: "\n "))\n")
|
||||||
|
output.append(")\n\n")
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Sources/DynamicSchema.swift
Normal file
49
Sources/DynamicSchema.swift
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// DynamicSchema.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 John Rommel Estropia
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - DynamicSchema
|
||||||
|
|
||||||
|
/**
|
||||||
|
`DynamicSchema` are types that provide `NSManagedObjectModel` instances for a single model version. CoreStore currently supports the following concrete types:
|
||||||
|
- `XcodeDataModelSchema`: describes models loaded from a .xcdatamodeld file.
|
||||||
|
- `UnsafeDataModelSchema`: describes models loaded directly from an existing `NSManagedObjectModel`. It is not advisable to continue using this model as its metadata are not available to CoreStore.
|
||||||
|
- `CoreStoreSchema`: describes models written for `CoreStoreObject` Swift class declarations.
|
||||||
|
*/
|
||||||
|
public protocol DynamicSchema {
|
||||||
|
|
||||||
|
/**
|
||||||
|
The version string for this model schema.
|
||||||
|
*/
|
||||||
|
var modelVersion: ModelVersion { get }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Do not call this directly. The `NSManagedObjectModel` for this schema may be created lazily and using this method directly may affect the integrity of the model.
|
||||||
|
*/
|
||||||
|
func rawModel() -> NSManagedObjectModel
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user