mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-03 14:50:08 +01:00
Compare commits
126 Commits
4.0.0-beta
...
4.2.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18b933957e | ||
|
|
2c7039232e | ||
|
|
d3b3b5ff4a | ||
|
|
d90e8d1303 | ||
|
|
e314db8f56 | ||
|
|
48d936d068 | ||
|
|
f3816b9abf | ||
|
|
21961780d4 | ||
|
|
305e2b61a0 | ||
|
|
588fa35c84 | ||
|
|
f6614cda66 | ||
|
|
639574d8c2 | ||
|
|
27ffc1d225 | ||
|
|
ba6f0c39d5 | ||
|
|
ab2eac8f6c | ||
|
|
f460a0b30f | ||
|
|
50bc3ace06 | ||
|
|
d2ddf2002f | ||
|
|
b4117eeb02 | ||
|
|
50e50c0613 | ||
|
|
5c8a0e425b | ||
|
|
03b71caf7e | ||
|
|
7ff29d6086 | ||
|
|
8d86425875 | ||
|
|
0aa8c03424 | ||
|
|
85706a3c57 | ||
|
|
c5ae4606b9 | ||
|
|
fa682215c5 | ||
|
|
be5da632b3 | ||
|
|
dc73cd6dd9 | ||
|
|
53100b202d | ||
|
|
2a62770552 | ||
|
|
f436b26e8e | ||
|
|
0b57cff27d | ||
|
|
3ebc44b546 | ||
|
|
68f1027ba7 | ||
|
|
8bac4aa901 | ||
|
|
211e69023e | ||
|
|
2912dcf010 | ||
|
|
3e00a3da06 | ||
|
|
9922deac4d | ||
|
|
86be046c9f | ||
|
|
0f10bc3349 | ||
|
|
9685f0aef2 | ||
|
|
3bd459bb1a | ||
|
|
28b43f33fa | ||
|
|
74c64619c3 | ||
|
|
f36cb8af63 | ||
|
|
10ccadd96c | ||
|
|
5c0e78bd53 | ||
|
|
8a09688117 | ||
|
|
a366bcf1a3 | ||
|
|
c6e68ac24f | ||
|
|
a20ad87583 | ||
|
|
a11915db12 | ||
|
|
961f39a806 | ||
|
|
3096cb784c | ||
|
|
809aa4ff96 | ||
|
|
8d926d25ec | ||
|
|
790454f514 | ||
|
|
fb7e2f7f7f | ||
|
|
f72efc80b2 | ||
|
|
fd3a9b00ec | ||
|
|
5f5000218a | ||
|
|
e8eb309d82 | ||
|
|
d0c3203e63 | ||
|
|
f5b3901caa | ||
|
|
1a99fea820 | ||
|
|
195b60615b | ||
|
|
2c394965b8 | ||
|
|
746d697691 | ||
|
|
5689158b43 | ||
|
|
6fcdf3d011 | ||
|
|
e26573c18e | ||
|
|
801cf8d9f0 | ||
|
|
6a42a0054e | ||
|
|
8c437e19b8 | ||
|
|
9cd3b6c879 | ||
|
|
fe135acbec | ||
|
|
997c5bdcfa | ||
|
|
23e12c4539 | ||
|
|
f618617053 | ||
|
|
49b8b9c372 | ||
|
|
129f975d96 | ||
|
|
a2e463e58c | ||
|
|
5fd50f0e15 | ||
|
|
7f9a915d71 | ||
|
|
0a81736b7a | ||
|
|
f9b6dd0c6a | ||
|
|
0354401b56 | ||
|
|
0304067beb | ||
|
|
ddd83da434 | ||
|
|
fc7df671de | ||
|
|
5fde9030c7 | ||
|
|
d7b07b3f00 | ||
|
|
ddd1ffb29f | ||
|
|
98094000bb | ||
|
|
d5026ef996 | ||
|
|
2cd913b9dd | ||
|
|
ad9520abbc | ||
|
|
c0fc57d10c | ||
|
|
0cf4d303e4 | ||
|
|
6de397958a | ||
|
|
55292a84dc | ||
|
|
981b560d53 | ||
|
|
c4c4dd55cd | ||
|
|
1ddbe20c86 | ||
|
|
da9e8c1550 | ||
|
|
ef0937fec4 | ||
|
|
35885b40de | ||
|
|
d669569196 | ||
|
|
ae919ff3c8 | ||
|
|
1a7a4690d1 | ||
|
|
b9b96d1a35 | ||
|
|
da3a9590ac | ||
|
|
6b3d75bea1 | ||
|
|
d44721fef0 | ||
|
|
3f268e8376 | ||
|
|
303fea4ebe | ||
|
|
77173cdad0 | ||
|
|
1e24a7d739 | ||
|
|
a3b33bedb8 | ||
|
|
eaf7544c50 | ||
|
|
67863120e0 | ||
|
|
1b0e305d9a | ||
|
|
91fda01071 |
2
.cocoapods.yml
Normal file
2
.cocoapods.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
try:
|
||||
project: 'CoreStore.xcworkspace'
|
||||
@@ -1 +1 @@
|
||||
3.1
|
||||
3.2
|
||||
|
||||
39
.travis.yml
39
.travis.yml
@@ -1,5 +1,5 @@
|
||||
language: objective-c
|
||||
osx_image: xcode8.3
|
||||
osx_image: xcode9
|
||||
sudo: false
|
||||
git:
|
||||
submodules: false
|
||||
@@ -9,25 +9,30 @@ env:
|
||||
global:
|
||||
- LC_CTYPE=en_US.UTF-8
|
||||
- LANG=en_US.UTF-8
|
||||
matrix:
|
||||
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 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=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 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 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 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="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.2 RUN_TESTS="NO" 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.2 RUN_TESTS="YES" POD_LINT="NO"
|
||||
matrix:
|
||||
- DESTINATION="OS=11.0,name=iPhone 8" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.13 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=4.0,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=11.0,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
before_install:
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.20.1/Carthage.pkg"
|
||||
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.26.0/Carthage.pkg"
|
||||
- sudo installer -pkg "Carthage.pkg" -target /
|
||||
- rm "Carthage.pkg"
|
||||
- npm install ios-sim -g
|
||||
- ios-sim start --devicetypeid "com.apple.CoreSimulator.SimDeviceType.iPhone-8, 11.0"
|
||||
before_script:
|
||||
- carthage update --use-submodules
|
||||
script:
|
||||
@@ -38,8 +43,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 Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||
fi
|
||||
- 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.3" -destination "OS=10.3,name=iPhone 7" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "iphonesimulator11.0" -destination "OS=11.0,name=iPhone 8" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
|
||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "iphonesimulator11.0" -destination "OS=11.0,name=iPhone 8" -configuration Release ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
|
||||
- if [ $POD_LINT == "YES" ]; then
|
||||
pod lib lint --quick;
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "CoreStore"
|
||||
s.version = "4.0.0-beta"
|
||||
s.version = "4.2.4"
|
||||
s.license = "MIT"
|
||||
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
|
||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||
|
||||
@@ -214,10 +214,10 @@
|
||||
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 /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; };
|
||||
B52F74421E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; };
|
||||
B52F74431E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; };
|
||||
B52F74441E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.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 */; };
|
||||
@@ -238,6 +238,14 @@
|
||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B53B275F1EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
@@ -426,10 +434,10 @@
|
||||
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 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; };
|
||||
B56924001EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; };
|
||||
B56924011EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; };
|
||||
B56924021EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.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 */; };
|
||||
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965231B356B820075EE4A /* MigrationResult.swift */; };
|
||||
B57D27BE1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */; };
|
||||
@@ -441,6 +449,18 @@
|
||||
B580857A1CDF808C004C2EEB /* 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 */; };
|
||||
B5831B701F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B711F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B721F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B731F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B7A1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
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 */; };
|
||||
@@ -746,12 +766,14 @@
|
||||
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 /* LegacyXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyXcodeDataModelSchema.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>"; };
|
||||
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>"; };
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
|
||||
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PartialObject.swift; sourceTree = "<group>"; };
|
||||
B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = "<group>"; };
|
||||
B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = "<group>"; };
|
||||
B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = "<group>"; };
|
||||
@@ -800,12 +822,15 @@
|
||||
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 /* CSLegacyXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSLegacyXcodeDataModelSchema.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; };
|
||||
B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.swift; sourceTree = "<group>"; };
|
||||
B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestDataTestCase.swift; sourceTree = "<group>"; };
|
||||
B57D27C11D0BC20100539C58 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
|
||||
B58085741CDF7F00004C2EEB /* SetupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupTests.swift; sourceTree = "<group>"; };
|
||||
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributeProtocol.swift; sourceTree = "<group>"; };
|
||||
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelationshipProtocol.swift; sourceTree = "<group>"; };
|
||||
B5831B791F34ACBA00A9F647 /* Transformable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transformable.swift; sourceTree = "<group>"; };
|
||||
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+DynamicModel.swift"; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
@@ -823,6 +848,7 @@
|
||||
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>"; };
|
||||
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = "<group>"; };
|
||||
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .cocoapods.yml; sourceTree = SOURCE_ROOT; };
|
||||
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>"; };
|
||||
@@ -1019,6 +1045,7 @@
|
||||
B5E84ED91AFF82360064E85B /* LICENSE */,
|
||||
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */,
|
||||
B5BDC91A1C202269008147CD /* Cartfile */,
|
||||
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */,
|
||||
B5BDC9271C2024F2008147CD /* .travis.yml */,
|
||||
B5AD60CD1C90141E00F2B2E8 /* Package.swift */,
|
||||
);
|
||||
@@ -1108,7 +1135,7 @@
|
||||
B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */,
|
||||
B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */,
|
||||
B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */,
|
||||
B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */,
|
||||
B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */,
|
||||
);
|
||||
name = "Dynamic Schema";
|
||||
sourceTree = "<group>";
|
||||
@@ -1190,7 +1217,7 @@
|
||||
children = (
|
||||
B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */,
|
||||
B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */,
|
||||
B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */,
|
||||
B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */,
|
||||
);
|
||||
name = "Dynamic Schema";
|
||||
sourceTree = "<group>";
|
||||
@@ -1224,17 +1251,27 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */,
|
||||
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */,
|
||||
B5831B6E1F3355C300A9F647 /* Properties */,
|
||||
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>";
|
||||
};
|
||||
B5831B6E1F3355C300A9F647 /* Properties */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5D33A001E96012400C880DE /* Relationship.swift */,
|
||||
B5D339E11E948C3600C880DE /* Value.swift */,
|
||||
B5831B791F34ACBA00A9F647 /* Transformable.swift */,
|
||||
);
|
||||
name = Properties;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B5A5F26B1CAFF8D0004AB9AF /* Swift */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1423,18 +1460,21 @@
|
||||
B5E84F291AFF849C0064E85B /* Internal */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */,
|
||||
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */,
|
||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
|
||||
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
|
||||
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
|
||||
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
||||
B51260921E9B28F100402229 /* EntityIdentifier.swift */,
|
||||
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */,
|
||||
B5E834BA1B7691F3001D3D50 /* Functions.swift */,
|
||||
B5FAD6AB1B51285300714891 /* MigrationManager.swift */,
|
||||
B5E84F2B1AFF849C0064E85B /* NotificationObserver.swift */,
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
|
||||
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
|
||||
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
|
||||
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */,
|
||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
|
||||
B5E84F2C1AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift */,
|
||||
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */,
|
||||
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */,
|
||||
@@ -1788,7 +1828,7 @@
|
||||
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74411E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A9921F1EA898710091A2E3 /* UserInfo.swift in Sources */,
|
||||
B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||
@@ -1802,6 +1842,7 @@
|
||||
B5ECDC1D1CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
||||
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
|
||||
@@ -1820,6 +1861,7 @@
|
||||
B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */,
|
||||
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
|
||||
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
||||
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
||||
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -1875,6 +1917,7 @@
|
||||
B5E2222A1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
||||
B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */,
|
||||
B56923E81EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B275F1EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5D33A011E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B5E84EE81AFF84610064E85B /* CoreStoreLogger.swift in Sources */,
|
||||
B56923C91EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -1892,6 +1935,7 @@
|
||||
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
|
||||
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B5831B7A1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B53FBA1E1CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||
B549F65E1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
@@ -1900,13 +1944,14 @@
|
||||
B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56923FF1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B56923EC1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */,
|
||||
B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */,
|
||||
B53FBA041CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
B5E84EF41AFF846E0064E85B /* AsynchronousDataTransaction.swift in Sources */,
|
||||
B5831B701F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B546F95D1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||
B5D339E71E9493A500C880DE /* Entity.swift in Sources */,
|
||||
@@ -1972,7 +2017,7 @@
|
||||
B5E1B59A1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74421E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74421E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A992201EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||
@@ -1986,6 +2031,7 @@
|
||||
B5ECDC1F1CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
||||
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B53FBA141CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5E1B5AA1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5D339F21E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
@@ -2004,6 +2050,7 @@
|
||||
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
|
||||
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
|
||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2059,6 +2106,7 @@
|
||||
82BA18A71C4BBD2900A0916E /* CoreStore+Logging.swift in Sources */,
|
||||
82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */,
|
||||
B56923E91EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5D33A021E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B559CD4B1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||
B56923CA1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -2076,6 +2124,7 @@
|
||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
||||
B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B53FBA201CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||
82BA18A81C4BBD2900A0916E /* CoreStoreLogger.swift in Sources */,
|
||||
B549F65F1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
@@ -2084,13 +2133,14 @@
|
||||
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56924001EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
B56923ED1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */,
|
||||
B53FBA061CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
82BA18BE1C4BBD4A00A0916E /* Tweak.swift in Sources */,
|
||||
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B5831B711F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B546F95E1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||
B5ECDC0D1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||
B5D339E81E9493A500C880DE /* Entity.swift in Sources */,
|
||||
@@ -2156,7 +2206,7 @@
|
||||
B5ECDC211CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
||||
B52DD1C21BE1F94600949AFE /* MigrationManager.swift in Sources */,
|
||||
B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74441E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74441E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B5ECDC2D1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||
B5A992221EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */,
|
||||
@@ -2170,6 +2220,7 @@
|
||||
B5D3F6481C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B5220E1C1D130801009BC71E /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||
B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */,
|
||||
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */,
|
||||
B5D339F41E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5220E241D13085E009BC71E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
@@ -2188,6 +2239,7 @@
|
||||
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
|
||||
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
||||
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2243,6 +2295,7 @@
|
||||
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B546F96C1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B56923EB1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5D33A041E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B52DD1C61BE1F94600949AFE /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B56923CC1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -2260,6 +2313,7 @@
|
||||
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
||||
B5ECDC331CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||
B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */,
|
||||
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
B5220E151D130663009BC71E /* CoreStore+Observing.swift in Sources */,
|
||||
B549F6611E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
@@ -2268,13 +2322,14 @@
|
||||
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
|
||||
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56924021EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B56923EF1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
B53FBA081CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
B52DD1B91BE1F94000949AFE /* CoreStore+Migration.swift in Sources */,
|
||||
B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
|
||||
B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||
B5831B731F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||
B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
||||
B5D339EA1E9493A500C880DE /* Entity.swift in Sources */,
|
||||
@@ -2340,7 +2395,7 @@
|
||||
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||
B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74431E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74431E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A992211EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */,
|
||||
@@ -2354,6 +2409,7 @@
|
||||
B5C976E51C6C9F9B00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||
B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B5D339F31E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5E1B5A01CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
||||
@@ -2372,6 +2428,7 @@
|
||||
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
||||
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2427,6 +2484,7 @@
|
||||
B563219F1BD65216006C9394 /* ObjectMonitor.swift in Sources */,
|
||||
B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */,
|
||||
B56923EA1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5D33A031E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B559CD4C1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||
B56923CB1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -2444,6 +2502,7 @@
|
||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
||||
B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B53FBA211CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||
B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */,
|
||||
B549F6601E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
@@ -2452,13 +2511,14 @@
|
||||
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56924011EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
B56923EE1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */,
|
||||
B53FBA071CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
B56321841BD65216006C9394 /* DefaultLogger.swift in Sources */,
|
||||
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B5831B721F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B546F95F1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||
B5ECDC0E1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||
B5D339E91E9493A500C880DE /* Entity.swift in Sources */,
|
||||
@@ -2501,6 +2561,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
@@ -2559,6 +2620,7 @@
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
import CoreStore
|
||||
|
||||
// MARK: - AppDelegate
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" 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>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12078"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
@@ -459,8 +459,8 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="301.5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
|
||||
<rect key="frame" x="16" y="89.5" width="343" height="50"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" id="TIX-qi-B34"/>
|
||||
@@ -511,8 +511,8 @@
|
||||
<action selector="brightnessSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="F09-EP-2iD"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<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"/>
|
||||
<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">
|
||||
<rect key="frame" x="16" y="69" width="343" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -797,8 +797,8 @@
|
||||
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<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="375" height="536"/>
|
||||
<mapView verifyAmbiguity="ignoreSizes" 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="375" height="558"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="jPl-fH-NlD" id="Sjn-YC-haS"/>
|
||||
</connections>
|
||||
@@ -806,7 +806,7 @@
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<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="N9r-9J-68d"/>
|
||||
<constraint firstItem="V2U-0R-Ts0" firstAttribute="top" secondItem="k4s-iL-Krh" secondAttribute="top" id="S5Z-Da-V6J"/>
|
||||
<constraint firstAttribute="trailing" secondItem="V2U-0R-Ts0" secondAttribute="trailing" id="YPc-RK-5ib"/>
|
||||
<constraint firstItem="V2U-0R-Ts0" firstAttribute="leading" secondItem="k4s-iL-Krh" secondAttribute="leading" id="hk5-Rz-FyU"/>
|
||||
@@ -820,7 +820,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="YnG-TD-zxQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3694" y="2020"/>
|
||||
<point key="canvasLocation" x="3693.5" y="2019.5"/>
|
||||
</scene>
|
||||
<!--Logger-->
|
||||
<scene sceneID="n7W-0g-bbY">
|
||||
@@ -927,7 +927,7 @@
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bordered" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="YVj-dA-fyV">
|
||||
<rect key="frame" x="20" y="26" width="560" height="29"/>
|
||||
<rect key="frame" x="20" y="26" width="335" height="29"/>
|
||||
<segments>
|
||||
<segment title="Fetch"/>
|
||||
<segment title="Query"/>
|
||||
|
||||
@@ -1,36 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="10169.1" systemVersion="15D21" minimumToolsVersion="Automatic">
|
||||
<entity name="Palette" representedClassName="CoreStoreDemo.Palette">
|
||||
<attribute name="brightness" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="colorName" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="hue" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="saturation" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
|
||||
<userInfo/>
|
||||
</entity>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16F73" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Place" representedClassName="CoreStoreDemo.Place" syncable="YES">
|
||||
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="subtitle" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="TimeZone" representedClassName="CoreStoreDemo.TimeZone" syncable="YES">
|
||||
<attribute name="abbreviation" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" syncable="YES"/>
|
||||
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
</entity>
|
||||
<configuration name="FetchingAndQueryingDemo">
|
||||
<memberEntity name="TimeZone"/>
|
||||
</configuration>
|
||||
<configuration name="ObservingDemo">
|
||||
<memberEntity name="Palette"/>
|
||||
</configuration>
|
||||
<configuration name="TransactionsDemo">
|
||||
<memberEntity name="Place"/>
|
||||
</configuration>
|
||||
<elements>
|
||||
<element name="Palette" positionX="261" positionY="189" width="128" height="105"/>
|
||||
<element name="Place" positionX="261" positionY="225" width="128" height="105"/>
|
||||
<element name="TimeZone" positionX="297" positionY="270" width="128" height="120"/>
|
||||
</elements>
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.1</string>
|
||||
<string>4.0.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>4</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
|
||||
@@ -10,7 +10,7 @@ import UIKit
|
||||
import CoreStore
|
||||
|
||||
|
||||
private struct Static {
|
||||
struct ColorsDemo {
|
||||
|
||||
enum Filter: String {
|
||||
|
||||
@@ -33,8 +33,8 @@ private struct Static {
|
||||
switch self {
|
||||
|
||||
case .all: return Where(true)
|
||||
case .light: return Where("%K >= %@", #keyPath(Palette.brightness), 0.9)
|
||||
case .dark: return Where("%K <= %@", #keyPath(Palette.brightness), 0.4)
|
||||
case .light: return Palette.where({ $0.brightness >= 0.9 })
|
||||
case .dark: return Palette.where({ $0.brightness <= 0.4 })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,25 +45,38 @@ private struct Static {
|
||||
|
||||
self.palettes.refetch(
|
||||
self.filter.whereClause(),
|
||||
OrderBy(.ascending(#keyPath(Palette.hue)))
|
||||
Palette.orderBy(ascending: { $0.hue })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
static let stack: DataStack = {
|
||||
|
||||
return DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "ColorsDemo",
|
||||
entities: [
|
||||
Entity<Palette>("Palette"),
|
||||
],
|
||||
versionLock: [
|
||||
"Palette": [0x8c25aa53c7c90a28, 0xa243a34d25f1a3a7, 0x56565b6935b6055a, 0x4f988bb257bf274f]
|
||||
]
|
||||
)
|
||||
)
|
||||
}()
|
||||
|
||||
static let palettes: ListMonitor<Palette> = {
|
||||
|
||||
try! CoreStore.addStorageAndWait(
|
||||
try! ColorsDemo.stack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "ColorsDemo.sqlite",
|
||||
configuration: "ObservingDemo",
|
||||
localStorageOptions: .recreateStoreOnModelMismatch
|
||||
)
|
||||
)
|
||||
|
||||
return CoreStore.monitorSectionedList(
|
||||
return ColorsDemo.stack.monitorSectionedList(
|
||||
From<Palette>(),
|
||||
SectionBy(#keyPath(Palette.colorName)),
|
||||
OrderBy(.ascending(#keyPath(Palette.hue)))
|
||||
SectionBy(Palette.keyPath({ $0.colorName })),
|
||||
Palette.orderBy(ascending: { $0.hue })
|
||||
)
|
||||
}()
|
||||
}
|
||||
@@ -77,7 +90,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
deinit {
|
||||
|
||||
Static.palettes.removeObserver(self)
|
||||
ColorsDemo.palettes.removeObserver(self)
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +111,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
]
|
||||
|
||||
let filterBarButton = UIBarButtonItem(
|
||||
title: Static.filter.rawValue,
|
||||
title: ColorsDemo.filter.rawValue,
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(self.filterBarButtonItemTouched(_:))
|
||||
@@ -113,9 +126,9 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
]
|
||||
self.filterBarButton = filterBarButton
|
||||
|
||||
Static.palettes.addObserver(self)
|
||||
ColorsDemo.palettes.addObserver(self)
|
||||
|
||||
self.setTable(enabled: !Static.palettes.isPendingRefetch)
|
||||
self.setTable(enabled: !ColorsDemo.palettes.isPendingRefetch)
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
@@ -137,19 +150,19 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
|
||||
return Static.palettes.numberOfSections()
|
||||
return ColorsDemo.palettes.numberOfSections()
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
|
||||
return Static.palettes.numberOfObjectsInSection(section)
|
||||
return ColorsDemo.palettes.numberOfObjectsInSection(section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell
|
||||
|
||||
let palette = Static.palettes[indexPath]
|
||||
let palette = ColorsDemo.palettes[indexPath]
|
||||
cell.colorView?.backgroundColor = palette.color
|
||||
cell.label?.text = palette.colorText
|
||||
|
||||
@@ -165,7 +178,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
self.performSegue(
|
||||
withIdentifier: "ObjectObserverDemoViewController",
|
||||
sender: Static.palettes[indexPath]
|
||||
sender: ColorsDemo.palettes[indexPath]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -174,8 +187,8 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
switch editingStyle {
|
||||
|
||||
case .delete:
|
||||
let palette = Static.palettes[indexPath]
|
||||
CoreStore.perform(
|
||||
let palette = ColorsDemo.palettes[indexPath]
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
transaction.delete(palette)
|
||||
@@ -190,7 +203,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
|
||||
return Static.palettes.sectionInfoAtIndex(section).name
|
||||
return ColorsDemo.palettes.sectionInfoAtIndex(section).name
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +226,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
func listMonitorDidRefetch(_ monitor: ListMonitor<Palette>) {
|
||||
|
||||
self.filterBarButton?.title = Static.filter.rawValue
|
||||
self.filterBarButton?.title = ColorsDemo.filter.rawValue
|
||||
self.tableView.reloadData()
|
||||
self.setTable(enabled: true)
|
||||
}
|
||||
@@ -235,7 +248,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
if let cell = self.tableView.cellForRow(at: indexPath) as? PaletteTableViewCell {
|
||||
|
||||
let palette = Static.palettes[indexPath]
|
||||
let palette = ColorsDemo.palettes[indexPath]
|
||||
cell.colorView?.backgroundColor = palette.color
|
||||
cell.label?.text = palette.colorText
|
||||
}
|
||||
@@ -268,7 +281,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
transaction.deleteAll(From<Palette>())
|
||||
@@ -279,16 +292,16 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
Static.filter = Static.filter.next()
|
||||
ColorsDemo.filter = ColorsDemo.filter.next()
|
||||
}
|
||||
|
||||
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
let palette = transaction.create(Into<Palette>())
|
||||
palette.setInitialValues()
|
||||
palette.setInitialValues(in: transaction)
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
if let palette = newValue {
|
||||
|
||||
self.monitor = CoreStore.monitorObject(palette)
|
||||
self.monitor = ColorsDemo.stack.monitorObject(palette)
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -50,22 +50,22 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
||||
if let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue)))) {
|
||||
if let palette = ColorsDemo.stack.fetchOne(From<Palette>(), Palette.orderBy(ascending: { $0.hue })) {
|
||||
|
||||
self.monitor = CoreStore.monitorObject(palette)
|
||||
self.monitor = ColorsDemo.stack.monitorObject(palette)
|
||||
}
|
||||
else {
|
||||
|
||||
_ = try? CoreStore.perform(
|
||||
_ = try? ColorsDemo.stack.perform(
|
||||
synchronous: { (transaction) in
|
||||
|
||||
let palette = transaction.create(Into(Palette.self))
|
||||
palette.setInitialValues()
|
||||
let palette = transaction.create(Into<Palette>())
|
||||
palette.setInitialValues(in: transaction)
|
||||
}
|
||||
)
|
||||
|
||||
let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue))))!
|
||||
self.monitor = CoreStore.monitorObject(palette)
|
||||
let palette = ColorsDemo.stack.fetchOne(From<Palette>(), Palette.orderBy(ascending: { $0.hue }))!
|
||||
self.monitor = ColorsDemo.stack.monitorObject(palette)
|
||||
}
|
||||
|
||||
super.init(coder: aDecoder)
|
||||
@@ -85,7 +85,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
// MARK: ObjectObserver
|
||||
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPath>) {
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<RawKeyPath>) {
|
||||
|
||||
self.reloadPaletteInfo(object, changedKeys: changedPersistentKeys)
|
||||
}
|
||||
@@ -121,12 +121,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
|
||||
|
||||
let hue = self.hueSlider?.value ?? 0
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
if let palette = transaction.edit(self?.monitor?.object) {
|
||||
|
||||
palette.hue = Int32(hue)
|
||||
palette.hue .= Int(hue)
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
@@ -136,12 +136,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
|
||||
|
||||
let saturation = self.saturationSlider?.value ?? 0
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
if let palette = transaction.edit(self?.monitor?.object) {
|
||||
|
||||
palette.saturation = saturation
|
||||
palette.saturation .= saturation
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
@@ -151,12 +151,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
|
||||
|
||||
let brightness = self.brightnessSlider?.value ?? 0
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
if let palette = transaction.edit(self?.monitor?.object) {
|
||||
|
||||
palette.brightness = brightness
|
||||
palette.brightness .= brightness
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
@@ -165,7 +165,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
|
||||
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
transaction.delete(self?.monitor?.object)
|
||||
@@ -176,7 +176,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
|
||||
|
||||
self.colorNameLabel?.text = palette.colorName
|
||||
self.colorNameLabel?.text = palette.colorName.value
|
||||
|
||||
let color = palette.color
|
||||
self.colorNameLabel?.textColor = color
|
||||
@@ -184,17 +184,17 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
self.hsbLabel?.text = palette.colorText
|
||||
|
||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.hue)) == true {
|
||||
if changedKeys == nil || changedKeys?.contains(Palette.keyPath{ $0.hue }) == true {
|
||||
|
||||
self.hueSlider?.value = Float(palette.hue)
|
||||
self.hueSlider?.value = Float(palette.hue.value)
|
||||
}
|
||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.saturation)) == true {
|
||||
if changedKeys == nil || changedKeys?.contains(Palette.keyPath{ $0.saturation }) == true {
|
||||
|
||||
self.saturationSlider?.value = palette.saturation
|
||||
self.saturationSlider?.value = palette.saturation.value
|
||||
}
|
||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.brightness)) == true {
|
||||
if changedKeys == nil || changedKeys?.contains(Palette.keyPath{ $0.brightness }) == true {
|
||||
|
||||
self.brightnessSlider?.value = palette.brightness
|
||||
self.brightnessSlider?.value = palette.brightness.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,64 +14,65 @@ import CoreStore
|
||||
|
||||
// MARK: - Palette
|
||||
|
||||
class Palette: NSManagedObject {
|
||||
|
||||
@NSManaged var hue: Int32
|
||||
@NSManaged var saturation: Float
|
||||
@NSManaged var brightness: Float
|
||||
final class Palette: CoreStoreObject {
|
||||
|
||||
@objc dynamic var colorName: String {
|
||||
let hue = Value.Required<Int>("hue", initial: 0)
|
||||
let saturation = Value.Required<Float>("saturation", initial: 0)
|
||||
let brightness = Value.Required<Float>("brightness", initial: 0)
|
||||
|
||||
let colorName = Value.Optional<String>(
|
||||
"colorName",
|
||||
isTransient: true,
|
||||
customGetter: Palette.getColorName
|
||||
)
|
||||
|
||||
private static func getColorName(_ partialObject: PartialObject<Palette>) -> String? {
|
||||
|
||||
get {
|
||||
if let colorName = partialObject.primitiveValue(for: { $0.colorName }) {
|
||||
|
||||
let KVCKey = #keyPath(Palette.colorName)
|
||||
if let colorName = self.getValue(forKvcKey: KVCKey) as? String {
|
||||
|
||||
return colorName
|
||||
}
|
||||
|
||||
let colorName: String
|
||||
switch self.hue % 360 {
|
||||
|
||||
case 0 ..< 20: colorName = "Lower Reds"
|
||||
case 20 ..< 57: colorName = "Oranges and Browns"
|
||||
case 57 ..< 90: colorName = "Yellow-Greens"
|
||||
case 90 ..< 159: colorName = "Greens"
|
||||
case 159 ..< 197: colorName = "Blue-Greens"
|
||||
case 197 ..< 241: colorName = "Blues"
|
||||
case 241 ..< 297: colorName = "Violets"
|
||||
case 297 ..< 331: colorName = "Magentas"
|
||||
default: colorName = "Upper Reds"
|
||||
}
|
||||
|
||||
self.setPrimitiveValue(colorName, forKey: KVCKey)
|
||||
return colorName
|
||||
}
|
||||
set {
|
||||
|
||||
let colorName: String
|
||||
switch partialObject.value(for: { $0.hue }) % 360 {
|
||||
|
||||
self.setValue(newValue.cs_toImportableNativeType(), forKvcKey: #keyPath(Palette.colorName))
|
||||
case 0 ..< 20: colorName = "Lower Reds"
|
||||
case 20 ..< 57: colorName = "Oranges and Browns"
|
||||
case 57 ..< 90: colorName = "Yellow-Greens"
|
||||
case 90 ..< 159: colorName = "Greens"
|
||||
case 159 ..< 197: colorName = "Blue-Greens"
|
||||
case 197 ..< 241: colorName = "Blues"
|
||||
case 241 ..< 297: colorName = "Violets"
|
||||
case 297 ..< 331: colorName = "Magentas"
|
||||
default: colorName = "Upper Reds"
|
||||
}
|
||||
|
||||
partialObject.setPrimitiveValue(colorName, for: { $0.colorName })
|
||||
return colorName
|
||||
}
|
||||
}
|
||||
|
||||
extension Palette {
|
||||
|
||||
var color: UIColor {
|
||||
|
||||
return UIColor(
|
||||
hue: CGFloat(self.hue) / 360.0,
|
||||
saturation: CGFloat(self.saturation),
|
||||
brightness: CGFloat(self.brightness),
|
||||
hue: CGFloat(self.hue.value) / 360.0,
|
||||
saturation: CGFloat(self.saturation.value),
|
||||
brightness: CGFloat(self.brightness.value),
|
||||
alpha: 1.0
|
||||
)
|
||||
}
|
||||
|
||||
var colorText: String {
|
||||
|
||||
return "H: \(self.hue)˚, S: \(round(self.saturation * 100.0))%, B: \(round(self.brightness * 100.0))%"
|
||||
return "H: \(self.hue.value)˚, S: \(round(self.saturation.value * 100.0))%, B: \(round(self.brightness.value * 100.0))%"
|
||||
}
|
||||
|
||||
func setInitialValues() {
|
||||
func setInitialValues(in transaction: BaseDataTransaction) {
|
||||
|
||||
self.hue = Int32(arc4random_uniform(360))
|
||||
self.saturation = 1.0
|
||||
self.brightness = Float(arc4random_uniform(70) + 30) / 100.0
|
||||
self.hue .= Int(arc4random_uniform(360))
|
||||
self.saturation .= Float(1.0)
|
||||
self.brightness .= Float(arc4random_uniform(70) + 30) / 100.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
|
||||
case 2?:
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
|
||||
_ = self.dataStack.fetchOne(From<Palette>())
|
||||
_ = self.dataStack.fetchOne(From<Place>())
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -46,7 +46,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
||||
|
||||
let modelMetadata = withExtendedLifetime(DataStack(modelName: "MigrationDemo")) {
|
||||
let modelMetadata = withExtendedLifetime(DataStack(xcodeModelName: "MigrationDemo")) {
|
||||
(dataStack: DataStack) -> ModelMetadata in
|
||||
|
||||
let models = self.models
|
||||
@@ -91,6 +91,11 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
}
|
||||
}
|
||||
|
||||
func listMonitorDidRefetch(_ monitor: ListMonitor<NSManagedObject>) {
|
||||
|
||||
self.listMonitorDidChange(monitor)
|
||||
}
|
||||
|
||||
// MARK: UITableViewDataSource
|
||||
|
||||
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
@@ -148,7 +153,10 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
label: "Model V1",
|
||||
entityType: OrganismV1.self,
|
||||
schemaHistory: SchemaHistory(
|
||||
modelName: "MigrationDemo",
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "MigrationDemo",
|
||||
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
||||
),
|
||||
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
||||
)
|
||||
),
|
||||
@@ -156,7 +164,13 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
label: "Model V2",
|
||||
entityType: OrganismV2.self,
|
||||
schemaHistory: SchemaHistory(
|
||||
modelName: "MigrationDemo",
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "MigrationDemo",
|
||||
migrationChain: [
|
||||
"MigrationDemo": "MigrationDemoV2",
|
||||
"MigrationDemoV3": "MigrationDemoV2"
|
||||
]
|
||||
),
|
||||
migrationChain: [
|
||||
"MigrationDemo": "MigrationDemoV2",
|
||||
"MigrationDemoV3": "MigrationDemoV2"
|
||||
@@ -167,7 +181,10 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
label: "Model V3",
|
||||
entityType: OrganismV3.self,
|
||||
schemaHistory: SchemaHistory(
|
||||
modelName: "MigrationDemo",
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "MigrationDemo",
|
||||
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
||||
),
|
||||
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
||||
)
|
||||
)
|
||||
|
||||
@@ -17,7 +17,7 @@ private struct Static {
|
||||
|
||||
static let facebookStack: DataStack = {
|
||||
|
||||
let dataStack = DataStack(modelName: "StackSetupDemo")
|
||||
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
|
||||
try! dataStack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "AccountsDemo_FB_Male.sqlite",
|
||||
@@ -55,7 +55,7 @@ private struct Static {
|
||||
|
||||
static let twitterStack: DataStack = {
|
||||
|
||||
let dataStack = DataStack(modelName: "StackSetupDemo")
|
||||
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
|
||||
try! dataStack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "AccountsDemo_TW_Male.sqlite",
|
||||
|
||||
@@ -131,7 +131,7 @@ class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, Objec
|
||||
// none
|
||||
}
|
||||
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPath>) {
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<RawKeyPath>) {
|
||||
|
||||
if let mapView = self.mapView {
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class BaseTestCase: XCTestCase {
|
||||
func prepareStack<T>(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> T) -> T {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
- (void)test_ThatDataStacks_BridgeCorrectly {
|
||||
|
||||
CSDataStack *dataStack = [[CSDataStack alloc]
|
||||
initWithModelName:@"Model"
|
||||
initWithXcodeModelName:@"Model"
|
||||
bundle:[NSBundle bundleForClass:[self class]]
|
||||
versionChain:nil];
|
||||
XCTAssertNotNil(dataStack);
|
||||
@@ -201,7 +201,7 @@
|
||||
|
||||
[CSCoreStore
|
||||
setDefaultStack:[[CSDataStack alloc]
|
||||
initWithModelName:@"Model"
|
||||
initWithXcodeModelName:@"Model"
|
||||
bundle:[NSBundle bundleForClass:[self class]]
|
||||
versionChain:nil]];
|
||||
[CSCoreStore
|
||||
@@ -253,37 +253,5 @@
|
||||
}
|
||||
[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
|
||||
|
||||
@@ -28,32 +28,83 @@ 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 species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<UIColor>("color")
|
||||
let color = Transformable.Optional<Color>("color")
|
||||
}
|
||||
|
||||
class Dog: Animal {
|
||||
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let age = Value.Required<Int>("age", default: 1)
|
||||
let age = Value.Required<Int>("age", initial: 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 title = Value.Required<String>(
|
||||
"title",
|
||||
initial: "Mr.",
|
||||
customSetter: Person.setTitle
|
||||
)
|
||||
|
||||
let name = Value.Required<String>(
|
||||
"name",
|
||||
customGetter: { (`self`, getValue) in
|
||||
|
||||
return "\(self.title.value) \(getValue())"
|
||||
}
|
||||
initial: "",
|
||||
customSetter: Person.setName
|
||||
)
|
||||
|
||||
let displayName = Value.Optional<String>(
|
||||
"displayName",
|
||||
isTransient: true,
|
||||
customGetter: Person.getDisplayName(_:),
|
||||
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
|
||||
)
|
||||
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
|
||||
private static func setTitle(_ partialObject: PartialObject<Person>, _ newValue: String) {
|
||||
|
||||
partialObject.setPrimitiveValue(newValue, for: { $0.title })
|
||||
partialObject.setPrimitiveValue(nil, for: { $0.displayName })
|
||||
}
|
||||
|
||||
private static func setName(_ partialObject: PartialObject<Person>, _ newValue: String) {
|
||||
|
||||
partialObject.setPrimitiveValue(newValue, for: { $0.name })
|
||||
partialObject.setPrimitiveValue(nil, for: { $0.displayName })
|
||||
}
|
||||
|
||||
static func getDisplayName(_ partialObject: PartialObject<Person>) -> String? {
|
||||
|
||||
if let displayName = partialObject.primitiveValue(for: { $0.displayName }) {
|
||||
|
||||
return displayName
|
||||
}
|
||||
let title = partialObject.value(for: { $0.title })
|
||||
let name = partialObject.value(for: { $0.name })
|
||||
let displayName = "\(title) \(name)"
|
||||
partialObject.setPrimitiveValue(displayName, for: { $0.displayName })
|
||||
return displayName
|
||||
}
|
||||
|
||||
static func keyPathsAffectingDisplayName() -> Set<String> {
|
||||
|
||||
return [
|
||||
self.keyPath({ $0.title }),
|
||||
self.keyPath({ $0.name })
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +153,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(animal.species.value, "Sparrow")
|
||||
|
||||
animal.color .= .yellow
|
||||
XCTAssertEqual(animal.color.value, UIColor.yellow)
|
||||
XCTAssertEqual(animal.color.value, Color.yellow)
|
||||
|
||||
let dog = transaction.create(Into<Dog>())
|
||||
XCTAssertEqual(dog.species.value, "Swift")
|
||||
@@ -118,11 +169,25 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
let person = transaction.create(Into<Person>())
|
||||
XCTAssertTrue(person.pets.value.isEmpty)
|
||||
|
||||
XCTAssertEqual(
|
||||
object_getClass(person.rawObject!).keyPathsForValuesAffectingValue(forKey: "displayName"),
|
||||
["title", "name"]
|
||||
)
|
||||
|
||||
person.name .= "Joe"
|
||||
|
||||
XCTAssertEqual(person.rawObject!.value(forKey: "name") as! String?, "Joe")
|
||||
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "Mr. Joe")
|
||||
|
||||
person.rawObject!.setValue("AAAA", forKey: "displayName")
|
||||
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "AAAA")
|
||||
|
||||
person.name .= "John"
|
||||
XCTAssertEqual(person.name.value, "Mr. John") // Custom getter
|
||||
XCTAssertEqual(person.name.value, "John")
|
||||
XCTAssertEqual(person.displayName.value, "Mr. John") // Custom getter
|
||||
|
||||
person.title .= "Sir"
|
||||
XCTAssertEqual(person.name.value, "Sir John")
|
||||
XCTAssertEqual(person.displayName.value, "Sir John")
|
||||
|
||||
person.pets.value.insert(dog)
|
||||
XCTAssertEqual(person.pets.count, 1)
|
||||
@@ -168,7 +233,6 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
success: {
|
||||
|
||||
fetchDone.fulfill()
|
||||
withExtendedLifetime(stack, {})
|
||||
},
|
||||
failure: { _ in
|
||||
|
||||
|
||||
@@ -86,8 +86,10 @@ final class ErrorTests: XCTestCase {
|
||||
let dummyURL = URL(string: "file:///test1/test2.sqlite")!
|
||||
|
||||
let schemaHistory = SchemaHistory(
|
||||
modelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
)
|
||||
let version = "1.0.0"
|
||||
|
||||
|
||||
@@ -36,33 +36,33 @@ class ImportTests: BaseTestDataTestCase {
|
||||
@objc
|
||||
dynamic func test_ThatAttributeProtocols_BehaveCorrectly() {
|
||||
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: true))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: true))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
|
||||
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: true)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT))))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: true)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT))))
|
||||
|
||||
XCTAssertEqual(true.cs_toQueryableNativeType(), NSNumber(value: true))
|
||||
XCTAssertEqual(Int16.max.cs_toQueryableNativeType(), NSNumber(value: Int16.max))
|
||||
|
||||
@@ -198,60 +198,58 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
for _ in 1 ... 2 {
|
||||
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didUpdateObject:atIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didUpdateObject:atIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
|
||||
switch object?.testEntityID {
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
case NSNumber(value: 101)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
case NSNumber(value: 102)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
switch object?.testEntityID {
|
||||
|
||||
case NSNumber(value: 101)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||
|
||||
case NSNumber(value: 102)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
)
|
||||
}
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorDidChange:",
|
||||
object: observer,
|
||||
@@ -453,38 +451,35 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
for _ in 1 ... 2 {
|
||||
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didDeleteObject:fromIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didDeleteObject:fromIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.isDeleted, true)
|
||||
|
||||
defer {
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.isDeleted, true)
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
events += 1
|
||||
}
|
||||
)
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
let didDeleteSectionExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didDeleteSection:fromSectionIndex:",
|
||||
object: observer,
|
||||
@@ -531,10 +526,11 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
|
||||
transaction.deleteAll(
|
||||
let count = transaction.deleteAll(
|
||||
From<TestEntity1>(),
|
||||
Where(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
|
||||
)
|
||||
XCTAssertEqual(count, 2)
|
||||
return transaction.hasChanges
|
||||
},
|
||||
success: { (hasChanges) in
|
||||
|
||||
@@ -219,7 +219,7 @@ class TestObjectObserver: ObjectObserver {
|
||||
)
|
||||
}
|
||||
|
||||
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<KeyPath>) {
|
||||
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<String>) {
|
||||
|
||||
NotificationCenter.default.post(
|
||||
name: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
|
||||
|
||||
@@ -37,9 +37,10 @@ class SetupTests: BaseTestDataTestCase {
|
||||
do {
|
||||
|
||||
let schemaHistory = SchemaHistory(
|
||||
modelName: "Model",
|
||||
bundle: Bundle(for: type(of: self)),
|
||||
migrationChain: nil
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
)
|
||||
let stack = DataStack(schemaHistory: schemaHistory)
|
||||
XCTAssertEqual(stack.coordinator.managedObjectModel, schemaHistory.rawModel)
|
||||
@@ -66,7 +67,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
let stack = self.expectLogger([.logWarning]) {
|
||||
|
||||
DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self)),
|
||||
migrationChain: migrationChain
|
||||
)
|
||||
@@ -83,7 +84,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
dynamic func test_ThatInMemoryStores_SetupCorrectly() {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
@@ -138,7 +139,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
dynamic func test_ThatSQLiteStores_SetupCorrectly() {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
@@ -206,7 +207,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
do {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try! stack.addStorageAndWait(sqliteStore)
|
||||
@@ -225,10 +226,10 @@ class SetupTests: BaseTestDataTestCase {
|
||||
|
||||
let metadata = try createStore()
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try sqliteStore.eraseStorageAndWait(
|
||||
try sqliteStore.cs_eraseStorageAndWait(
|
||||
metadata: metadata,
|
||||
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
||||
)
|
||||
@@ -243,7 +244,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
do {
|
||||
|
||||
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.appending("-wal")))
|
||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||
@@ -258,7 +259,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
@@ -326,7 +327,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
do {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try! stack.addStorageAndWait(sqliteStore)
|
||||
@@ -345,10 +346,10 @@ class SetupTests: BaseTestDataTestCase {
|
||||
|
||||
let metadata = try createStore()
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try sqliteStore.eraseStorageAndWait(
|
||||
try sqliteStore.cs_eraseStorageAndWait(
|
||||
metadata: metadata,
|
||||
soureModelHint: stack.schemaHistory.schema(for: metadata)?.rawModel()
|
||||
)
|
||||
@@ -363,7 +364,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
do {
|
||||
|
||||
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.appending("-wal")))
|
||||
XCTAssertFalse(fileManager.fileExists(atPath: sqliteStore.fileURL.path.appending("-shm")))
|
||||
|
||||
@@ -256,6 +256,21 @@ final class WhereTests: XCTestCase {
|
||||
XCTAssertEqual(andWhere.predicate, andPredicate)
|
||||
XCTAssertEqual(andWhere, whereClause1 && whereClause2 && whereClause3)
|
||||
}
|
||||
do {
|
||||
|
||||
let andWhere = whereClause1 && whereClause2 && whereClause3
|
||||
let noneWhere: Where? = nil
|
||||
let someWhere: Where? = Where("key4", isEqualTo: "value4")
|
||||
|
||||
|
||||
let finalNoneWhere = andWhere && noneWhere
|
||||
let finalSomeWhere = andWhere && someWhere
|
||||
let unwrappedFinalSomeWhere = andWhere && someWhere!
|
||||
|
||||
|
||||
XCTAssertEqual(andWhere.predicate, finalNoneWhere.predicate)
|
||||
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let orWhere = whereClause1 || whereClause2 || whereClause3
|
||||
@@ -272,6 +287,21 @@ final class WhereTests: XCTestCase {
|
||||
XCTAssertEqual(orWhere.predicate, orPredicate)
|
||||
XCTAssertEqual(orWhere, whereClause1 || whereClause2 || whereClause3)
|
||||
}
|
||||
do {
|
||||
|
||||
let orWhere = whereClause1 || whereClause2 || whereClause3
|
||||
let noneWhere: Where? = nil
|
||||
let someWhere: Where? = Where("key4", isEqualTo: "value4")
|
||||
|
||||
|
||||
let finalNoneWhere = orWhere && noneWhere
|
||||
let finalSomeWhere = orWhere && someWhere
|
||||
let unwrappedFinalSomeWhere = orWhere && someWhere!
|
||||
|
||||
XCTAssertEqual(orWhere.predicate, finalNoneWhere.predicate)
|
||||
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@objc
|
||||
|
||||
@@ -30,17 +30,43 @@ import CoreData
|
||||
// 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 {
|
||||
|
||||
/**
|
||||
Cancels a transaction by throwing `CoreStoreError.userCancelled`.
|
||||
```
|
||||
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 cancel() throws -> Never {
|
||||
|
||||
throw CoreStoreError.userCancelled
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Result
|
||||
|
||||
/**
|
||||
The `Result` contains the success or failure information for a completed transaction
|
||||
*/
|
||||
public enum Result<T> {
|
||||
|
||||
/**
|
||||
`Result<T>.success` indicates that the transaction succeeded, either because the save succeeded or because there were no changes to save. The associated `userInfo` is the value returned from the transaction closure.
|
||||
*/
|
||||
case success(userInfo: T)
|
||||
|
||||
/**
|
||||
`Result<T>.failure` indicates that the transaction either failed or was cancelled. The associated object for this value is a `CoreStoreError` enum value.
|
||||
*/
|
||||
case failure(error: CoreStoreError)
|
||||
|
||||
/**
|
||||
Returns `true` if the result indicates `.success`, `false` if the result is `.failure`.
|
||||
*/
|
||||
public var boolValue: Bool {
|
||||
|
||||
switch self {
|
||||
@@ -64,22 +90,8 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: -
|
||||
|
||||
/**
|
||||
Cancels a transaction by throwing `CoreStoreError.userCancelled`.
|
||||
```
|
||||
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 cancel() throws -> Never {
|
||||
|
||||
throw CoreStoreError.userCancelled
|
||||
}
|
||||
|
||||
|
||||
// MARK: BaseDataTransaction
|
||||
|
||||
/**
|
||||
@@ -88,7 +100,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
|
||||
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
|
||||
*/
|
||||
public override func create<T: DynamicObject>(_ into: Into<T>) -> T {
|
||||
public override func create<T>(_ into: Into<T>) -> T {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
@@ -99,10 +111,10 @@ 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
|
||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
||||
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be edited
|
||||
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
|
||||
*/
|
||||
public override func edit<T: DynamicObject>(_ object: T?) -> T? {
|
||||
|
||||
@@ -115,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 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: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||
public override func edit<T>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
@@ -132,9 +144,9 @@ 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<T: DynamicObject>(_ object: T?) {
|
||||
|
||||
@@ -147,11 +159,11 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes the specified `NSManagedObject`s.
|
||||
Deletes the specified `DynamicObject`s.
|
||||
|
||||
- parameter object1: the `NSManagedObject` type to be deleted
|
||||
- parameter object2: another `NSManagedObject` type to be deleted
|
||||
- parameter objects: other `NSManagedObject`s type to be deleted
|
||||
- parameter object1: the `DynamicObject` to be deleted
|
||||
- parameter object2: another `DynamicObject` to be deleted
|
||||
- parameter objects: other `DynamicObject`s to be deleted
|
||||
*/
|
||||
public override func delete<T: DynamicObject>(_ object1: T?, _ object2: T?, _ objects: T?...) {
|
||||
|
||||
@@ -164,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(
|
||||
!self.isCommitted,
|
||||
@@ -198,16 +210,12 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
group.leave()
|
||||
}
|
||||
group.wait()
|
||||
self.context.reset()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Saves the transaction changes. This method should not be used after the `commit()` method was already called once.
|
||||
|
||||
- parameter completion: the block executed after the save completes. Success or failure is reported by the `SaveResult` argument of the block.
|
||||
*/
|
||||
@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 }) {
|
||||
|
||||
@@ -229,12 +237,6 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
- 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
|
||||
*/
|
||||
@available(*, deprecated, message: "Secondary tasks spawned from AsynchronousDataTransactions and SynchronousDataTransactions are no longer supported. ")
|
||||
@discardableResult
|
||||
public func beginSynchronous(_ closure: @escaping (_ transaction: SynchronousDataTransaction) -> Void) -> SaveResult? {
|
||||
@@ -265,9 +267,9 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
}
|
||||
switch childTransaction.result {
|
||||
|
||||
case nil: return nil
|
||||
case (let hasChanges, nil)?: return SaveResult(hasChanges: hasChanges)
|
||||
case (_, let error?)?: return SaveResult(error)
|
||||
case .none: return nil
|
||||
case .some(let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
|
||||
case .some(_, let error?): return SaveResult(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
47
Sources/AttributeProtocol.swift
Normal file
47
Sources/AttributeProtocol.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// AttributeProtocol.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: - AttributeProtocol
|
||||
|
||||
internal protocol AttributeProtocol: class {
|
||||
|
||||
static var attributeType: NSAttributeType { get }
|
||||
|
||||
var keyPath: RawKeyPath { get }
|
||||
var isOptional: Bool { get }
|
||||
var isIndexed: Bool { get }
|
||||
var isTransient: Bool { get }
|
||||
var versionHashModifier: () -> String? { get }
|
||||
var renamingIdentifier: () -> String? { get }
|
||||
var defaultValue: () -> Any? { get }
|
||||
var affectedByKeyPaths: () -> Set<String> { get }
|
||||
weak var parentObject: CoreStoreObject? { get set }
|
||||
var getter: CoreStoreManagedObject.CustomGetter? { get }
|
||||
var setter: CoreStoreManagedObject.CustomSetter? { get }
|
||||
}
|
||||
@@ -177,7 +177,7 @@ public extension BaseDataTransaction {
|
||||
/**
|
||||
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.
|
||||
- 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 sourceArray: the array of objects to import values from
|
||||
|
||||
@@ -32,14 +32,14 @@ import CoreData
|
||||
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 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
|
||||
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
|
||||
public func deleteAll<T>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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
|
||||
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
|
||||
public func deleteAll<T>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -71,10 +71,10 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
// 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
|
||||
- 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: DynamicObject>(_ object: T) -> T? {
|
||||
|
||||
@@ -82,10 +82,10 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
- 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: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||
|
||||
@@ -93,10 +93,10 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
- returns: the `NSManagedObject` array for objects that exists in the transaction
|
||||
- parameter objects: an array of `DynamicObject`s created/fetched outside the transaction
|
||||
- returns: the `DynamicObject` array for objects that exists in the transaction
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||
|
||||
@@ -104,10 +104,10 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
- 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: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||
|
||||
@@ -115,13 +115,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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
public func fetchOne<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
public func fetchOne<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
public func fetchAll<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
public func fetchAll<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
public func fetchCount<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
public func fetchCount<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -287,7 +287,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
public func queryValue<T, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -306,7 +306,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
public func queryValue<T, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -325,7 +325,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
public func queryAttributes<T>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -344,7 +344,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
public func queryAttributes<T>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -365,11 +365,11 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
// MARK: Obsoleted
|
||||
|
||||
@available(*, deprecated, renamed: "unsafeContext()")
|
||||
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
|
||||
public func internalContext() -> NSManagedObjectContext {
|
||||
|
||||
return self.unsafeContext()
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
|
||||
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
|
||||
*/
|
||||
public func create<T: DynamicObject>(_ into: Into<T>) -> T {
|
||||
public func create<T>(_ into: Into<T>) -> T {
|
||||
|
||||
let entityClass = into.entityClass
|
||||
CoreStore.assert(
|
||||
@@ -141,7 +141,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter objectID: the `NSManagedObjectID` for the object to be edited
|
||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
||||
*/
|
||||
public func edit<T: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||
public func edit<T>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -215,30 +215,12 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
// 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: a `Set` of pending `NSManagedObject`s that were inserted to the transaction.
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
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 `DynamicObject`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.
|
||||
- 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<T: NSManagedObject>(_ entity: T.Type) -> Set<T> {
|
||||
public func insertedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -248,7 +230,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.insertedObjects.flatMap { $0 as? T })
|
||||
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,10 +254,10 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
public func insertedObjectIDs<T: NSManagedObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
public func insertedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -285,15 +267,16 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.insertedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID })
|
||||
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
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(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -303,26 +286,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
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 })
|
||||
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,10 +310,10 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
public func updatedObjectIDs<T: NSManagedObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
public func updatedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -359,15 +323,16 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated object IDs from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.updatedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID })
|
||||
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
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(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -377,32 +342,13 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
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 })
|
||||
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
@@ -421,10 +367,10 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
public func deletedObjectIDs<T: NSManagedObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
public func deletedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -434,7 +380,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted object IDs from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.deletedObjects.filter { $0.isKind(of: entity) }.map { $0.objectID })
|
||||
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
}
|
||||
|
||||
|
||||
@@ -450,7 +396,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
*/
|
||||
private let userInfo = UserInfo()
|
||||
public let userInfo = UserInfo()
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
@@ -491,4 +437,54 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
|
||||
return self.bypassesQueueing || self.transactionQueue.cs_isCurrentExecutionContext()
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
self.context.reset()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use insertedObjects(_:) and pass the specific entity type")
|
||||
public func insertedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to access inserted objects from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return self.context.insertedObjects
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use updatedObjects(_:) and pass the specific entity type")
|
||||
public func updatedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to access updated objects from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return self.context.updatedObjects
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use deletedObjects(_:) and pass the specific entity type")
|
||||
public func deletedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
"Attempted to access deleted objects from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return self.context.deletedObjects
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +35,13 @@ import CoreData
|
||||
- SeeAlso: `AsynchronousDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
public final class CSAsynchronousDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
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
|
||||
public func commitWithSuccess(_ success: (() -> Void)?, failure: ((CSError) -> Void)?) {
|
||||
@@ -138,9 +139,9 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
public typealias SwiftType = AsynchronousDataTransaction
|
||||
|
||||
public override var bridgeToSwift: AsynchronousDataTransaction {
|
||||
public var bridgeToSwift: AsynchronousDataTransaction {
|
||||
|
||||
return super.bridgeToSwift as! AsynchronousDataTransaction
|
||||
return super.swiftTransaction as! AsynchronousDataTransaction
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: AsynchronousDataTransaction) {
|
||||
@@ -148,19 +149,14 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
super.init(swiftValue as BaseDataTransaction)
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
public required override init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
super.init(swiftValue as! AsynchronousDataTransaction)
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
@available(*, deprecated, message: "Use the new -[CSAsynchronousDataTransaction commitWithSuccess:failure:] method.")
|
||||
@objc
|
||||
public func commitWithCompletion(_ completion: ((_ result: CSSaveResult) -> Void)?) {
|
||||
@@ -179,12 +175,6 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
- 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
|
||||
*/
|
||||
@available(*, deprecated, message: "Secondary tasks spawned from CSAsynchronousDataTransactions and CSSynchronousDataTransactions are no longer supported. ")
|
||||
@objc
|
||||
@discardableResult
|
||||
|
||||
@@ -40,7 +40,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObject(_ object: NSManagedObject) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(object) as NSManagedObject?
|
||||
return self.swiftTransaction.context.fetchExisting(object) as NSManagedObject?
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(objectID) as NSManagedObject?
|
||||
return self.swiftTransaction.context.fetchExisting(objectID) as NSManagedObject?
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +64,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(objects) as [NSManagedObject]
|
||||
return self.swiftTransaction.context.fetchExisting(objects) as [NSManagedObject]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(objectIDs) as [NSManagedObject]
|
||||
return self.swiftTransaction.context.fetchExisting(objectIDs) as [NSManagedObject]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,10 +90,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchOneFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> Any? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.fetchOne(from, fetchClauses)
|
||||
return self.swiftTransaction.context.fetchOne(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,10 +107,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchAllFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> [Any]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.fetchAll(from, fetchClauses)
|
||||
return self.swiftTransaction.context.fetchAll(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,10 +124,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchCountFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSNumber? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context
|
||||
return self.swiftTransaction.context
|
||||
.fetchCount(from, fetchClauses)
|
||||
.flatMap { NSNumber(value: $0) }
|
||||
}
|
||||
@@ -143,10 +143,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchObjectIDFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.fetchObjectID(from, fetchClauses)
|
||||
return self.swiftTransaction.context.fetchObjectID(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,10 +163,10 @@ public extension CSBaseDataTransaction {
|
||||
public func queryValueFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> Any? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.queryValue(from, selectClause, queryClauses)
|
||||
return self.swiftTransaction.context.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,9 +183,9 @@ public extension CSBaseDataTransaction {
|
||||
public func queryAttributesFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.queryAttributes(from, selectClause, queryClauses)
|
||||
return self.swiftTransaction.context.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `BaseDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
public class CSBaseDataTransaction: NSObject {
|
||||
|
||||
// MARK: Object management
|
||||
|
||||
@@ -45,7 +45,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public var hasChanges: Bool {
|
||||
|
||||
return self.bridgeToSwift.hasChanges
|
||||
return self.swiftTransaction.hasChanges
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +57,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func createInto(_ into: CSInto) -> Any {
|
||||
|
||||
return self.bridgeToSwift.create(into.bridgeToSwift)
|
||||
return self.swiftTransaction.create(into.bridgeToSwift)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +69,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func editObject(_ object: NSManagedObject?) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.edit(object)
|
||||
return self.swiftTransaction.edit(object)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func editInto(_ into: CSInto, objectID: NSManagedObjectID) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.edit(into.bridgeToSwift, objectID)
|
||||
return self.swiftTransaction.edit(into.bridgeToSwift, objectID)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +93,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deleteObject(_ object: NSManagedObject?) {
|
||||
|
||||
self.bridgeToSwift.delete(object)
|
||||
self.swiftTransaction.delete(object)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deleteObjects(_ objects: [NSManagedObject]) {
|
||||
|
||||
self.bridgeToSwift.delete(objects)
|
||||
self.swiftTransaction.delete(objects)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,23 +113,12 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func refreshAndMergeAllObjects() {
|
||||
|
||||
self.bridgeToSwift.refreshAndMergeAllObjects()
|
||||
self.swiftTransaction.refreshAndMergeAllObjects()
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -139,7 +128,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func insertedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.insertedObjects(entity)
|
||||
return self.swiftTransaction.insertedObjects(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,7 +139,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func insertedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.insertedObjectIDs()
|
||||
return self.swiftTransaction.insertedObjectIDs()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,18 +151,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func insertedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
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()
|
||||
return self.swiftTransaction.insertedObjectIDs(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +163,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func updatedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.updatedObjects(entity)
|
||||
return self.swiftTransaction.updatedObjects(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +174,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func updatedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.updatedObjectIDs()
|
||||
return self.swiftTransaction.updatedObjectIDs()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,18 +186,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func updatedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
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()
|
||||
return self.swiftTransaction.updatedObjectIDs(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,19 +198,18 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deletedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.deletedObjects(entity)
|
||||
return self.swiftTransaction.deletedObjects(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
@objc
|
||||
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.deletedObjectIDs()
|
||||
return self.swiftTransaction.deletedObjectIDs()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,7 +221,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deletedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.deletedObjectIDs(entity)
|
||||
return self.swiftTransaction.deletedObjectIDs(entity)
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +229,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
public override var hash: Int {
|
||||
|
||||
return ObjectIdentifier(self.bridgeToSwift).hashValue
|
||||
return ObjectIdentifier(self.swiftTransaction).hashValue
|
||||
}
|
||||
|
||||
public override func isEqual(_ object: Any?) -> Bool {
|
||||
@@ -272,25 +238,41 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
return false
|
||||
}
|
||||
return self.bridgeToSwift === object.bridgeToSwift
|
||||
return self.swiftTransaction === object.swiftTransaction
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
// MARK: Internal
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
internal let swiftTransaction: BaseDataTransaction
|
||||
|
||||
internal init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
self.swiftTransaction = swiftValue
|
||||
super.init()
|
||||
}
|
||||
|
||||
public var bridgeToSwift: BaseDataTransaction {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use -[insertedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func insertedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.swiftTransaction
|
||||
return self.swiftTransaction.insertedObjects()
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use -[updatedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func updatedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.swiftTransaction.updatedObjects()
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let swiftTransaction: BaseDataTransaction
|
||||
@available(*, deprecated, message: "Use -[deletedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func deletedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.swiftTransaction.deletedObjects()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,23 +129,14 @@ public extension CSCoreStore {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Returns the entity name-to-class type mapping from the `defaultStack`'s model.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the new +entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@available(*, deprecated, message: "Use the new +entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public static var entityClassesByName: [EntityName: NSManagedObject.Type] {
|
||||
|
||||
return CoreStore.entityTypesByName
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the new +entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@available(*, deprecated, message: "Use the new +entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public static func entityClassWithName(_ name: EntityName) -> NSManagedObject.Type? {
|
||||
|
||||
|
||||
@@ -95,12 +95,6 @@ public extension CSCoreStore {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
|
||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- returns: a `CSSaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
||||
*/
|
||||
@available(*, deprecated, message: "Use the new +[CSCoreStore beginSynchronous:error:] API that reports failure using an error instance.")
|
||||
@objc
|
||||
@discardableResult
|
||||
|
||||
@@ -135,12 +135,6 @@ public extension CSDataStack {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
|
||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- returns: a `CSSaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
||||
*/
|
||||
@available(*, deprecated, message: "Use the new -[CSDataStack beginSynchronous:error:] API that reports failure using an error instance.")
|
||||
@objc
|
||||
@discardableResult
|
||||
|
||||
@@ -49,41 +49,22 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
||||
/**
|
||||
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 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
|
||||
public convenience init(modelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) {
|
||||
public convenience init(xcodeModelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
modelName: modelName ?? DataStack.applicationName,
|
||||
xcodeModelName: xcodeModelName ?? DataStack.applicationName,
|
||||
bundle: bundle ?? Bundle.main,
|
||||
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: XcodeDataModelFileName?, bundle: Bundle?, versionTree: [String: String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
modelName: modelName ?? DataStack.applicationName,
|
||||
bundle: bundle ?? Bundle.main,
|
||||
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.
|
||||
*/
|
||||
@@ -227,13 +208,20 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the -[initWithModelName:bundle:versionChain:] initializer.")
|
||||
@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]?) {
|
||||
|
||||
@@ -245,13 +233,7 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the -[initWithModelName:bundle:versionTree:] initializer.")
|
||||
@available(*, deprecated, message: "Use the -[initWithModelName:bundle:versionTree:] initializer.")
|
||||
@objc
|
||||
public convenience init(model: NSManagedObjectModel, versionTree: [String]?) {
|
||||
|
||||
@@ -263,22 +245,14 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the entity name-to-class type mapping from the stack's model.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the new -entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@available(*, deprecated, message: "Use the new -entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public var entityClassesByName: [EntityName: NSManagedObject.Type] {
|
||||
|
||||
return self.bridgeToSwift.entityTypesByName
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the new -entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@available(*, deprecated, message: "Use the new -entityTypesByNameForType: method passing `[NSManagedObject class]` as argument.")
|
||||
@objc
|
||||
public func entityClassWithName(_ name: EntityName) -> NSManagedObject.Type? {
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ public final class CSFrom: NSObject {
|
||||
MyPersonEntity *people = [transaction fetchAllFrom:
|
||||
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.
|
||||
*/
|
||||
@objc
|
||||
@@ -107,7 +108,7 @@ public final class CSFrom: NSObject {
|
||||
CSFromClass([MyPersonEntity class],
|
||||
@[[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.
|
||||
*/
|
||||
@objc
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
The list of key path strings to group results with
|
||||
*/
|
||||
@objc
|
||||
public var keyPaths: [KeyPath] {
|
||||
public var keyPaths: [RawKeyPath] {
|
||||
|
||||
return self.bridgeToSwift.keyPaths
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
- parameter keyPath: a key path string to group results with
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath) {
|
||||
public convenience init(keyPath: RawKeyPath) {
|
||||
|
||||
self.init(GroupBy(keyPath))
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
- parameter keyPaths: a list of key path strings to group results with
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPaths: [KeyPath]) {
|
||||
public convenience init(keyPaths: [RawKeyPath]) {
|
||||
|
||||
self.init(GroupBy(keyPaths))
|
||||
}
|
||||
|
||||
@@ -560,7 +560,6 @@ extension ListMonitor where ListMonitor.ObjectType: NSManagedObject {
|
||||
|
||||
fileprivate func downcast() -> ListMonitor<NSManagedObject> {
|
||||
|
||||
@inline(__always)
|
||||
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
|
||||
|
||||
return unsafeBitCast(x, to: type)
|
||||
|
||||
@@ -42,7 +42,7 @@ import CoreData
|
||||
*/
|
||||
@available(OSX 10.12, *)
|
||||
@objc
|
||||
public protocol CSListObserver: class, AnyObject {
|
||||
public protocol CSListObserver: class {
|
||||
|
||||
/**
|
||||
Handles processing just before a change to the observed list occurs
|
||||
|
||||
@@ -152,7 +152,6 @@ extension ObjectMonitor where ObjectMonitor.ObjectType: NSManagedObject {
|
||||
|
||||
fileprivate func downcast() -> ObjectMonitor<NSManagedObject> {
|
||||
|
||||
@inline(__always)
|
||||
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
|
||||
|
||||
return unsafeBitCast(x, to: type)
|
||||
|
||||
@@ -40,7 +40,7 @@ import CoreData
|
||||
*/
|
||||
@available(OSX 10.12, *)
|
||||
@objc
|
||||
public protocol CSObjectObserver: class, AnyObject {
|
||||
public protocol CSObjectObserver: class {
|
||||
|
||||
/**
|
||||
Handles processing just before a change to the observed `object` occurs
|
||||
|
||||
@@ -78,7 +78,7 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
||||
}
|
||||
|
||||
/**
|
||||
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 `[CSLocalStorageOptions none]`.
|
||||
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]`.
|
||||
|
||||
- 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.
|
||||
*/
|
||||
@@ -151,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.
|
||||
*/
|
||||
@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) {
|
||||
|
||||
try self.bridgeToSwift.eraseStorageAndWait(metadata: metadata as! [String: Any], soureModelHint: soureModelHint)
|
||||
try self.bridgeToSwift.cs_eraseStorageAndWait(metadata: metadata as! [String: Any], soureModelHint: soureModelHint)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,52 +193,20 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
// MARK: Obsoleted
|
||||
|
||||
/**
|
||||
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 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`.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileURL:configuration:localStorageOptions:]) initializer instead.")
|
||||
@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) {
|
||||
|
||||
self.init(
|
||||
SQLiteStore(
|
||||
fileURL: fileURL,
|
||||
configuration: configuration,
|
||||
mappingModelBundles: mappingModelBundles ?? Bundle.allBundles,
|
||||
localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions)
|
||||
)
|
||||
)
|
||||
fatalError()
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
- 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 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]`.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileName:configuration:localStorageOptions:]) initializer instead.")
|
||||
@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) {
|
||||
|
||||
self.init(
|
||||
SQLiteStore(
|
||||
fileName: fileName,
|
||||
configuration: configuration,
|
||||
mappingModelBundles: mappingModelBundles ?? Bundle.allBundles,
|
||||
localStorageOptions: LocalStorageOptions(rawValue: localStorageOptions)
|
||||
)
|
||||
)
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,36 +29,22 @@ import CoreData
|
||||
|
||||
// MARK: - CSSaveResult
|
||||
|
||||
/**
|
||||
The `CSSaveResult` serves as the Objective-C bridging type for `SaveResult`.
|
||||
|
||||
- SeeAlso: `SaveResult`
|
||||
*/
|
||||
@available(*, deprecated, message: "Use APIs that report failures with `CSError`s instead.")
|
||||
@objc
|
||||
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
|
||||
public var isSuccess: Bool {
|
||||
|
||||
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
|
||||
public var isFailure: Bool {
|
||||
|
||||
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
|
||||
public var hasChanges: Bool {
|
||||
|
||||
@@ -69,9 +55,6 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
||||
return hasChanges
|
||||
}
|
||||
|
||||
/**
|
||||
The `NSError` for a failed `commit` operation, or `nil` if the `commit` succeeded
|
||||
*/
|
||||
@objc
|
||||
public var error: NSError? {
|
||||
|
||||
@@ -82,14 +65,6 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
||||
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
|
||||
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void, failure: (_ error: NSError) -> Void) {
|
||||
|
||||
@@ -103,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
|
||||
public func handleSuccess(_ success: (_ hasChanges: Bool) -> Void) {
|
||||
|
||||
@@ -120,13 +88,6 @@ public final class CSSaveResult: NSObject, CoreStoreObjectiveCType {
|
||||
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
|
||||
public func handleFailure(_ failure: (_ error: NSError) -> Void) {
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
*/
|
||||
@objc
|
||||
public static func keyPath(_ sectionKeyPath: KeyPath) -> CSSectionBy {
|
||||
public static func keyPath(_ sectionKeyPath: RawKeyPath) -> CSSectionBy {
|
||||
|
||||
return self.init(SectionBy(sectionKeyPath))
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
*/
|
||||
@objc
|
||||
public static func keyPath(_ sectionKeyPath: KeyPath, sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> CSSectionBy {
|
||||
public static func keyPath(_ sectionKeyPath: RawKeyPath, sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> CSSectionBy {
|
||||
|
||||
return self.init(SectionBy(sectionKeyPath, sectionIndexTransformer))
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- parameter keyPath: the attribute name
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath) {
|
||||
public convenience init(keyPath: RawKeyPath) {
|
||||
|
||||
self.init(.attribute(keyPath))
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the average value of an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func average(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func average(_ keyPath: RawKeyPath, as alias: RawKeyPath?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.average(keyPath, as: alias))
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `SelectTerm` to a `Select` clause for a count query
|
||||
*/
|
||||
@objc
|
||||
public static func count(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func count(_ keyPath: RawKeyPath, as alias: RawKeyPath?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.count(keyPath, as: alias))
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the maximum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func maximum(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func maximum(_ keyPath: RawKeyPath, as alias: RawKeyPath?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.maximum(keyPath, as: alias))
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the minimum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func minimum(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func minimum(_ keyPath: RawKeyPath, as alias: RawKeyPath?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.minimum(keyPath, as: alias))
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the sum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func sum(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func sum(_ keyPath: RawKeyPath, as alias: RawKeyPath?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.sum(keyPath, as: alias))
|
||||
}
|
||||
@@ -146,12 +146,11 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
select:[CSSelect objectIDForTerm:[CSSelectTerm objectIDAs:nil]]
|
||||
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
|
||||
- returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func objectIDAs(_ alias: KeyPath? = nil) -> CSSelectTerm {
|
||||
public static func objectIDAs(_ alias: RawKeyPath? = nil) -> CSSelectTerm {
|
||||
|
||||
return self.init(.objectID(as: alias))
|
||||
}
|
||||
@@ -217,7 +216,7 @@ public final class CSSelect: NSObject {
|
||||
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) {
|
||||
|
||||
@@ -232,7 +231,7 @@ public final class CSSelect: NSObject {
|
||||
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) {
|
||||
|
||||
@@ -247,7 +246,7 @@ public final class CSSelect: NSObject {
|
||||
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) {
|
||||
|
||||
@@ -262,7 +261,7 @@ public final class CSSelect: NSObject {
|
||||
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) {
|
||||
|
||||
@@ -277,7 +276,7 @@ public final class CSSelect: NSObject {
|
||||
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) {
|
||||
|
||||
@@ -292,7 +291,6 @@ public final class CSSelect: NSObject {
|
||||
select:CSSelectObjectID()
|
||||
// ...
|
||||
```
|
||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||
*/
|
||||
public convenience init(objectIDTerm: ()) {
|
||||
|
||||
@@ -367,7 +365,7 @@ public final class CSSelect: NSObject {
|
||||
super.init()
|
||||
}
|
||||
|
||||
public init<T: SelectResultType>(_ swiftValue: Select<T>) {
|
||||
public init<T>(_ swiftValue: Select<T>) {
|
||||
|
||||
self.attributeType = .undefinedAttributeType
|
||||
self.selectTerms = swiftValue.selectTerms
|
||||
|
||||
@@ -152,7 +152,7 @@ public final class CSSetupResult: NSObject {
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public required init<T: StorageInterface>(_ swiftValue: SetupResult<T>) where T: CoreStoreSwiftType, T.ObjectiveCType: CSStorageInterface {
|
||||
public required init<T>(_ swiftValue: SetupResult<T>) where T: CoreStoreSwiftType, T.ObjectiveCType: CSStorageInterface {
|
||||
|
||||
switch swiftValue {
|
||||
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
@objc
|
||||
func eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool
|
||||
func cs_eraseStorageAndWait(metadata: NSDictionary, soureModelHint: NSManagedObjectModel?, error: NSErrorPointer) -> Bool
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `SynchronousDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||
public final class CSSynchronousDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
Saves the transaction changes and waits for completion synchronously. This method should not be used after the `-commitAndWaitWithError:` method was already called once.
|
||||
@@ -129,9 +129,9 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
public typealias SwiftType = SynchronousDataTransaction
|
||||
|
||||
public override var bridgeToSwift: SynchronousDataTransaction {
|
||||
public var bridgeToSwift: SynchronousDataTransaction {
|
||||
|
||||
return super.bridgeToSwift as! SynchronousDataTransaction
|
||||
return super.swiftTransaction as! SynchronousDataTransaction
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: SynchronousDataTransaction) {
|
||||
@@ -139,19 +139,14 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||
super.init(swiftValue as BaseDataTransaction)
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
public required override init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
super.init(swiftValue as! SynchronousDataTransaction)
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Saves the transaction changes and waits for completion synchronously. This method should not be used after the `-commitAndWait` method was already called once.
|
||||
|
||||
- returns: a `CSSaveResult` containing the success or failure information
|
||||
*/
|
||||
@available(*, deprecated, message: "Use the new -[CSSynchronousDataTransaction commitAndWaitWithError:] method")
|
||||
@objc
|
||||
public func commitAndWait() -> CSSaveResult {
|
||||
@@ -162,12 +157,6 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
*/
|
||||
@available(*, deprecated, message: "Secondary tasks spawned from CSAsynchronousDataTransactions and CSSynchronousDataTransactions are no longer supported. ")
|
||||
@objc
|
||||
@discardableResult
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// CSLegacyXcodeDataModelSchema.swift
|
||||
// CSUnsafeDataModelSchema.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
@@ -27,20 +27,26 @@ import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: - CSLegacyXcodeDataModelSchema
|
||||
// MARK: - CSUnsafeDataModelSchema
|
||||
|
||||
/**
|
||||
The `CSLegacyXcodeDataModelSchema` serves as the Objective-C bridging type for `LegacyXcodeDataModelSchema`.
|
||||
The `CSUnsafeDataModelSchema` serves as the Objective-C bridging type for `UnsafeDataModelSchema`.
|
||||
|
||||
- SeeAlso: `LegacyXcodeDataModelSchema`
|
||||
- SeeAlso: `UnsafeDataModelSchema`
|
||||
*/
|
||||
@objc
|
||||
public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType {
|
||||
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 = LegacyXcodeDataModelSchema(
|
||||
self.bridgeToSwift = UnsafeDataModelSchema(
|
||||
modelName: modelName,
|
||||
model: model
|
||||
)
|
||||
@@ -56,7 +62,7 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core
|
||||
|
||||
public override func isEqual(_ object: Any?) -> Bool {
|
||||
|
||||
guard let object = object as? CSLegacyXcodeDataModelSchema else {
|
||||
guard let object = object as? CSUnsafeDataModelSchema else {
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -86,9 +92,9 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: LegacyXcodeDataModelSchema
|
||||
public let bridgeToSwift: UnsafeDataModelSchema
|
||||
|
||||
public required init(_ swiftValue: LegacyXcodeDataModelSchema) {
|
||||
public required init(_ swiftValue: UnsafeDataModelSchema) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
super.init()
|
||||
@@ -96,14 +102,14 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core
|
||||
}
|
||||
|
||||
|
||||
// MARK: - LegacyXcodeDataModelSchema
|
||||
// MARK: - UnsafeDataModelSchema
|
||||
|
||||
extension LegacyXcodeDataModelSchema: CoreStoreSwiftType {
|
||||
extension UnsafeDataModelSchema: CoreStoreSwiftType {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
public var bridgeToObjectiveC: CSLegacyXcodeDataModelSchema {
|
||||
public var bridgeToObjectiveC: CSUnsafeDataModelSchema {
|
||||
|
||||
return CSLegacyXcodeDataModelSchema(self)
|
||||
return CSUnsafeDataModelSchema(self)
|
||||
}
|
||||
}
|
||||
@@ -35,17 +35,22 @@ import CoreData
|
||||
- SeeAlso: `UnsafeDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
public final class CSUnsafeDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType {
|
||||
/**
|
||||
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 `error` 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
|
||||
public func commitWithSuccess(_ success: (() -> Void)?, _ failure: ((CSError) -> Void)?) {
|
||||
|
||||
self.bridgeToSwift.context.saveAsynchronouslyWithCompletion { (_, error) in
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
if let error = error {
|
||||
|
||||
failure?(error.bridgeToObjectiveC)
|
||||
@@ -54,7 +59,6 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
success?()
|
||||
}
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,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.
|
||||
|
||||
- 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
|
||||
public func flush(_ block: () -> Void) {
|
||||
@@ -185,9 +189,9 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
public typealias SwiftType = UnsafeDataTransaction
|
||||
|
||||
public override var bridgeToSwift: UnsafeDataTransaction {
|
||||
public var bridgeToSwift: UnsafeDataTransaction {
|
||||
|
||||
return super.bridgeToSwift as! UnsafeDataTransaction
|
||||
return super.swiftTransaction as! UnsafeDataTransaction
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: UnsafeDataTransaction) {
|
||||
@@ -195,9 +199,9 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
super.init(swiftValue as BaseDataTransaction)
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
public required override init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
super.init(swiftValue as! UnsafeDataTransaction)
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
@@ -210,17 +214,16 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
return self.bridgeToSwift.context
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
@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)
|
||||
@@ -229,15 +232,9 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
completion?(SaveResult(hasChanges: hasChanges).bridgeToObjectiveC)
|
||||
}
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
*/
|
||||
@available(*, deprecated, message: "Use the new -[CSUnsafeDataTransaction commitAndWaitWithError:] method")
|
||||
@objc
|
||||
public func commitAndWait() -> CSSaveResult {
|
||||
|
||||
@@ -85,7 +85,7 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
|
||||
- parameter value: the arguments for the `==` operator
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath, isEqualTo value: CoreDataNativeType?) {
|
||||
public convenience init(keyPath: RawKeyPath, isEqualTo value: CoreDataNativeType?) {
|
||||
|
||||
self.init(value == nil || value is NSNull
|
||||
? Where("\(keyPath) == nil")
|
||||
@@ -99,7 +99,7 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
|
||||
- parameter list: the array to check membership of
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath, isMemberOf list: [CoreDataNativeType]) {
|
||||
public convenience init(keyPath: RawKeyPath, isMemberOf list: [CoreDataNativeType]) {
|
||||
|
||||
self.init(Where("\(keyPath) IN %@", list as NSArray))
|
||||
}
|
||||
|
||||
@@ -37,6 +37,12 @@ import Foundation
|
||||
@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) {
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import CoreData
|
||||
*/
|
||||
public protocol FetchClause {
|
||||
|
||||
func applyToFetchRequest<T: NSFetchRequestResult>(_ fetchRequest: NSFetchRequest<T>)
|
||||
func applyToFetchRequest<T>(_ fetchRequest: NSFetchRequest<T>)
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public protocol FetchClause {
|
||||
*/
|
||||
public protocol QueryClause {
|
||||
|
||||
func applyToFetchRequest<T: NSFetchRequestResult>(_ fetchRequest: NSFetchRequest<T>)
|
||||
func applyToFetchRequest<T>(_ fetchRequest: NSFetchRequest<T>)
|
||||
}
|
||||
|
||||
|
||||
@@ -56,5 +56,5 @@ public protocol QueryClause {
|
||||
*/
|
||||
public protocol DeleteClause {
|
||||
|
||||
func applyToFetchRequest<T: NSFetchRequestResult>(_ fetchRequest: NSFetchRequest<T>)
|
||||
func applyToFetchRequest<T>(_ fetchRequest: NSFetchRequest<T>)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import CoreData
|
||||
Objective-C Foundation types that are natively supported by Core Data managed attributes all conform to `CoreDataNativeType`.
|
||||
*/
|
||||
@objc
|
||||
public protocol CoreDataNativeType: class, NSObjectProtocol, AnyObject {}
|
||||
public protocol CoreDataNativeType: class, NSObjectProtocol {}
|
||||
|
||||
|
||||
// MARK: - NSNumber
|
||||
|
||||
@@ -231,7 +231,9 @@ extension Entity: CustomDebugStringConvertible, CoreStoreDebugStringConvertible
|
||||
return createFormattedString(
|
||||
"(", ")",
|
||||
("type", self.type),
|
||||
("entityName", self.entityName)
|
||||
("entityName", self.entityName),
|
||||
("isAbstract", self.isAbstract),
|
||||
("versionHashModifier", self.versionHashModifier as Any)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -372,9 +374,9 @@ extension Into: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
}
|
||||
|
||||
|
||||
// MARK: - LegacyXcodeDataModelSchema
|
||||
// MARK: - UnsafeDataModelSchema
|
||||
|
||||
extension LegacyXcodeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
extension UnsafeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
@@ -866,7 +868,8 @@ extension SQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringConvert
|
||||
("storeOptions", self.storeOptions as Any),
|
||||
("fileURL", self.fileURL),
|
||||
("migrationMappingProviders", self.migrationMappingProviders),
|
||||
("localStorageOptions", self.localStorageOptions)
|
||||
("localStorageOptions", self.localStorageOptions),
|
||||
("fileSize", self.fileSize() as Any)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -983,7 +986,7 @@ extension VersionLock: CustomStringConvertible, CustomDebugStringConvertible, Co
|
||||
string.append(":]")
|
||||
return string
|
||||
}
|
||||
for (index, keyValue) in self.hashesByEntityName.enumerated() {
|
||||
for (index, keyValue) in self.hashesByEntityName.sorted(by: { $0.key < $1.key }).enumerated() {
|
||||
|
||||
let data = keyValue.value
|
||||
let count = data.count
|
||||
@@ -1212,6 +1215,8 @@ extension NSAttributeType: CoreStoreDebugStringConvertible {
|
||||
case .binaryDataAttributeType: return ".binaryDataAttributeType"
|
||||
case .transformableAttributeType: return ".transformableAttributeType"
|
||||
case .objectIDAttributeType: return ".objectIDAttributeType"
|
||||
case .UUIDAttributeType: return ".UUIDAttributeType"
|
||||
case .URIAttributeType: return ".URIAttributeType"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public extension CoreStore {
|
||||
- parameter storage: the storage
|
||||
- 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>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
public static func addStorage<T>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
|
||||
self.defaultStack.addStorage(storage, completion: completion)
|
||||
}
|
||||
|
||||
@@ -33,112 +33,112 @@ import CoreData
|
||||
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`
|
||||
*/
|
||||
public static func monitorObject<T: DynamicObject>(_ object: T) -> ObjectMonitor<T> {
|
||||
public static func monitorObject<T>(_ object: T) -> ObjectMonitor<T> {
|
||||
|
||||
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 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
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public static func monitorList<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
|
||||
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 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
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public static func monitorList<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
|
||||
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 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.
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||
public static func monitorList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||
|
||||
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 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.
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||
public static func monitorList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
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 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public static func monitorSectionedList<T>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
|
||||
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 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public static func monitorSectionedList<T>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
|
||||
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 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 fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||
public static func monitorSectionedList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||
|
||||
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 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 fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||
public static func monitorSectionedList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ import CoreData
|
||||
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`
|
||||
- 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: DynamicObject>(_ object: T) -> T? {
|
||||
|
||||
@@ -43,10 +43,10 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
- 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: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||
|
||||
@@ -54,10 +54,10 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
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`
|
||||
- returns: the `NSManagedObject` array for objects that exists in the `DataStack`
|
||||
- parameter objects: an array of `DynamicObject`s created/fetched outside the `DataStack`
|
||||
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||
*/
|
||||
public static func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||
|
||||
@@ -65,10 +65,10 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
- 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: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||
|
||||
@@ -76,121 +76,121 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
public static func fetchOne<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
public static func fetchOne<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
public static func fetchAll<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
public static func fetchAll<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
public static func fetchCount<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
public static func fetchCount<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
public static func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
public static func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
public static func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
public static func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
|
||||
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
|
||||
}
|
||||
@@ -205,7 +205,7 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
public static func queryValue<T, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
|
||||
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
@@ -220,7 +220,7 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
public static func queryValue<T, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
|
||||
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
@@ -235,7 +235,7 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
public static func queryAttributes<T>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
|
||||
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
@@ -250,7 +250,7 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
public static func queryAttributes<T>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
|
||||
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
@@ -143,10 +143,7 @@ public extension CoreStore {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Returns the entity name-to-class type mapping from the `defaultStack`'s model.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the new CoreStore.entityTypesByName(for:) method passing `NSManagedObject.self` as argument.")
|
||||
@available(*, deprecated, message: "Use the new CoreStore.entityTypesByName(for:) method passing `NSManagedObject.self` as argument.")
|
||||
public static var entityTypesByName: [EntityName: NSManagedObject.Type] {
|
||||
|
||||
return self.defaultStack.entityTypesByName
|
||||
|
||||
@@ -31,10 +31,10 @@ import Foundation
|
||||
public extension CoreStore {
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` 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 `TransactionResult.success(userInfo: T)` in the `completion`'s `TransactionResult<T>`. Any errors thrown from inside the `task` will be reported as `TransactionResult.failure(error: Error)`. To cancel/rollback changes, call `transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(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 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 `TransactionResult` 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 `CoreStoreError.userCancelled`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||
- 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 perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, completion: @escaping (AsynchronousDataTransaction.Result<T>) -> Void) {
|
||||
|
||||
@@ -42,11 +42,11 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` 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 `transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the 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 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 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)`.
|
||||
- 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)`.
|
||||
*/
|
||||
public static func perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, success: @escaping (T) -> Void, failure: @escaping (CoreStoreError) -> Void) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, performs a transaction synchronously where `NSManagedObject` 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 `transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
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 thrown 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`.
|
||||
@@ -67,7 +67,7 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
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`, 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.
|
||||
- returns: a `UnsafeDataTransaction` instance where creates, updates, and deletes can be made.
|
||||
@@ -78,7 +78,7 @@ 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() {
|
||||
|
||||
@@ -88,23 +88,12 @@ public extension CoreStore {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, begins a transaction asynchronously 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`.
|
||||
*/
|
||||
@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)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
|
||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- returns: a `SaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
||||
*/
|
||||
@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? {
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#define CORESTORE_RETURNS_RETAINED __attribute__((ns_returns_retained))
|
||||
|
||||
|
||||
#pragma mark - KeyPath Utilities
|
||||
#pragma mark - RawKeyPath Utilities
|
||||
|
||||
#define CSKeyPath(type, property) ({ \
|
||||
type *_je_keypath_dummy __attribute__((unused)); \
|
||||
@@ -156,7 +156,7 @@ CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray<id> *_Nonnull c
|
||||
@abstract
|
||||
Initializes a <tt>CSGroupBy</tt> clause with a key path string
|
||||
|
||||
@param keyPaths
|
||||
@param keyPath
|
||||
a key path string to group results with
|
||||
|
||||
@result
|
||||
@@ -169,7 +169,7 @@ CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CORESTORE_RETUR
|
||||
@abstract
|
||||
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
|
||||
|
||||
@result
|
||||
@@ -328,7 +328,7 @@ CSOrderBy *_Nonnull CSOrderByKey(NSSortDescriptor *_Nonnull sortDescriptor) CORE
|
||||
fetchClauses:@[CSOrderByKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]];
|
||||
@endcode
|
||||
|
||||
@param sortDescriptors
|
||||
@param sortDescriptor
|
||||
a nil-terminated array of <tt>NSSortDescriptor</tt>s
|
||||
|
||||
@result
|
||||
@@ -473,9 +473,6 @@ CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RET
|
||||
// ...
|
||||
@endcode
|
||||
|
||||
@param selectTerm
|
||||
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
|
||||
|
||||
@result
|
||||
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
|
||||
|
||||
@param format
|
||||
the format string for the predicate
|
||||
|
||||
@param argumentArray
|
||||
the arguments for <tt>format</tt>
|
||||
the format string for the predicate, followed by an optional comma-separated argument list
|
||||
|
||||
@result
|
||||
a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments
|
||||
|
||||
@@ -235,15 +235,15 @@ CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RE
|
||||
|
||||
- (void)setAffectedStores:(NSArray<NSPersistentStore *> *_Nullable)affectedStores {
|
||||
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
|
||||
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0) {
|
||||
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0
|
||||
|| [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){ 11, 0, 0 }]) {
|
||||
|
||||
self.safeAffectedStores = affectedStores;
|
||||
[super setAffectedStores:affectedStores];
|
||||
return;
|
||||
}
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
if (self.releaseArray != NULL) {
|
||||
|
||||
CFRelease(self.releaseArray);
|
||||
|
||||
@@ -31,7 +31,7 @@ import Foundation
|
||||
/**
|
||||
`CoreStoreObjectiveCType`s are Objective-C accessible classes that represent CoreStore's Swift types.
|
||||
*/
|
||||
public protocol CoreStoreObjectiveCType: class, AnyObject {
|
||||
public protocol CoreStoreObjectiveCType: class {
|
||||
|
||||
/**
|
||||
The corresponding Swift type
|
||||
|
||||
@@ -294,7 +294,8 @@ public extension NSError {
|
||||
}
|
||||
switch CocoaError.Code(rawValue: self.code) {
|
||||
|
||||
case CocoaError.Code.persistentStoreIncompatibleVersionHash,
|
||||
case CocoaError.Code.persistentStoreIncompatibleSchema,
|
||||
CocoaError.Code.persistentStoreIncompatibleVersionHash,
|
||||
CocoaError.Code.migrationMissingSourceModel,
|
||||
CocoaError.Code.migration:
|
||||
return true
|
||||
|
||||
@@ -34,7 +34,7 @@ internal extension CoreStoreFetchRequest {
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchRequest<U> {
|
||||
internal func dynamicCast<U>() -> NSFetchRequest<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal convenience init<T: DynamicObject>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal convenience init<T>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
@@ -47,33 +47,18 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal init<T: DynamicObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal init<T>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
_ = from?.applyToFetchRequest(
|
||||
_ = from.applyToFetchRequest(
|
||||
fetchRequest,
|
||||
context: context,
|
||||
applyAffectedStores: false
|
||||
)
|
||||
applyFetchClauses(fetchRequest)
|
||||
|
||||
if let from = from {
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
}
|
||||
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)).")
|
||||
}
|
||||
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
|
||||
super.init(
|
||||
@@ -98,7 +83,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchedResultsController<U> {
|
||||
internal func dynamicCast<U>() -> NSFetchedResultsController<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchedResultsController<U>.self)
|
||||
}
|
||||
|
||||
@@ -47,12 +47,6 @@ public enum LogLevel {
|
||||
*/
|
||||
public protocol CoreStoreLogger {
|
||||
|
||||
/**
|
||||
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false` if not implemented.
|
||||
*/
|
||||
// TODO: test before release (rolled back)
|
||||
// var enableObjectConcurrencyDebugging: Bool { get set }
|
||||
|
||||
/**
|
||||
Handles log messages sent by the `CoreStore` framework.
|
||||
|
||||
@@ -100,13 +94,6 @@ public protocol CoreStoreLogger {
|
||||
|
||||
extension CoreStoreLogger {
|
||||
|
||||
// TODO: test before release (rolled back)
|
||||
// public var enableObjectConcurrencyDebugging: Bool {
|
||||
//
|
||||
// get { return false }
|
||||
// set {}
|
||||
// }
|
||||
|
||||
public func abort(_ message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
|
||||
|
||||
Swift.fatalError(message, file: fileName, line: UInt(lineNumber))
|
||||
|
||||
34
Sources/CoreStoreManagedObject.swift
Normal file
34
Sources/CoreStoreManagedObject.swift
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// CoreStoreManagedObject.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Created by John Rommel Estropia on 2017/06/04.
|
||||
// Copyright © 2017 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - CoreStoreManagedObject
|
||||
|
||||
@objc internal class CoreStoreManagedObject: NSManagedObject {
|
||||
|
||||
internal typealias CustomGetter = @convention(block) (_ rawObject: Any) -> Any?
|
||||
internal typealias CustomSetter = @convention(block) (_ rawObject: Any, _ newValue: Any?) -> Void
|
||||
internal typealias CustomGetterSetter = (getter: CustomGetter?, setter: CustomSetter?)
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal static func cs_subclassName(for entity: DynamicEntity, in modelVersion: ModelVersion) -> String {
|
||||
|
||||
return "_\(NSStringFromClass(CoreStoreManagedObject.self))__\(modelVersion)__\(NSStringFromClass(entity.type))__\(entity.entityName)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private enum Static {
|
||||
|
||||
static let queue = DispatchQueue.concurrent("com.coreStore.coreStoreManagerObjectBarrierQueue")
|
||||
static var cache: [ObjectIdentifier: [RawKeyPath: Set<RawKeyPath>]] = [:]
|
||||
}
|
||||
@@ -31,27 +31,127 @@ import Foundation
|
||||
|
||||
public extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
public static func keyPath<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Required<V>) -> String {
|
||||
/**
|
||||
Extracts the keyPath string from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let keyPath: String = Person.keyPath { $0.nickname }
|
||||
```
|
||||
*/
|
||||
public static func keyPath<O, V>(_ attribute: (Self) -> ValueContainer<O>.Required<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
public static func keyPath<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> String {
|
||||
/**
|
||||
Extracts the keyPath string from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let keyPath: String = Person.keyPath { $0.nickname }
|
||||
```
|
||||
*/
|
||||
public static func keyPath<O, V>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from a `CoreStoreObject.Relationship` property.
|
||||
```
|
||||
let keyPath: String = Person.keyPath { $0.pets }
|
||||
```
|
||||
*/
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToOne<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from a `CoreStoreObject.Relationship` property.
|
||||
```
|
||||
let keyPath: String = Person.keyPath { $0.pets }
|
||||
```
|
||||
*/
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToManyOrdered<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from a `CoreStoreObject.Relationship` property.
|
||||
```
|
||||
let keyPath: String = Person.keyPath { $0.pets }
|
||||
```
|
||||
*/
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToManyUnordered<D>) -> String {
|
||||
|
||||
return relationship(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)
|
||||
}
|
||||
|
||||
public static func ascending<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||
/**
|
||||
Creates an `OrderBy` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let person = CoreStore.fetchAll(From<Person>(), Person.orderBy(ascending: { $0.age }))
|
||||
```
|
||||
*/
|
||||
public static func orderBy<O, V>(ascending attribute: (Self) -> ValueContainer<O>.Required<V>) -> OrderBy {
|
||||
|
||||
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
public static func descending<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||
/**
|
||||
Creates an `OrderBy` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let person = CoreStore.fetchAll(From<Person>(), Person.orderBy(ascending: { $0.age }))
|
||||
```
|
||||
*/
|
||||
public static func orderBy<O, V>(ascending 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.orderBy(descending: { $0.age }))
|
||||
```
|
||||
*/
|
||||
public static func orderBy<O, V>(descending attribute: (Self) -> ValueContainer<O>.Required<V>) -> OrderBy {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
/**
|
||||
Creates an `OrderBy` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let person = CoreStore.fetchAll(From<Person>(), Person.orderBy(descending: { $0.age }))
|
||||
```
|
||||
*/
|
||||
public static func orderBy<O, V>(descending attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, renamed: "orderBy(ascending:)")
|
||||
public static func ascending<O, V>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||
|
||||
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
@available(*, deprecated, renamed: "orderBy(descending:)")
|
||||
public static func descending<O, V>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
@@ -62,40 +162,88 @@ public extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>(), Dog.where { ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname })
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func != (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||
public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Required<V>) -> Where where S.Iterator.Element == V {
|
||||
|
||||
return !Where(attribute.keyPath, isEqualTo: value)
|
||||
return Where(attribute.keyPath, isMemberOf: sequence)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,15 +252,169 @@ public extension ValueContainer.Required {
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
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>.Optional<V>, _ value: V?) -> Where {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K < %@", attribute.keyPath, value)
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K < nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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>.Optional<V>, _ value: V?) -> Where {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K > %@", attribute.keyPath, value)
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K > nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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>.Optional<V>, _ value: V?) -> Where {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K <= %@", attribute.keyPath, value)
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K <= nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
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>.Optional<V>, _ value: V?) -> Where {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K >= %@", attribute.keyPath, value)
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K >= nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>(), Dog.where { ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname })
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Optional<V>) -> Where where S.Iterator.Element == V {
|
||||
|
||||
return Where(attribute.keyPath, isMemberOf: sequence)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - RelationshipContainer.ToOne
|
||||
|
||||
public extension RelationshipContainer.ToOne {
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Relationship` property.
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>(), Dog.where { $0.master == me })
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func == (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where {
|
||||
|
||||
return Where(relationship.keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Relationship` property.
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>(), Dog.where { $0.master != me })
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func != (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where {
|
||||
|
||||
return !Where(relationship.keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Relationship` property.
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>(), Dog.where { $0.master ~= me })
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func ~= (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where {
|
||||
|
||||
return Where(relationship.keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Relationship` property.
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>(), Dog.where { [john, joe, bob] ~= $0.master })
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func ~= <S: Sequence>(_ sequence: S, _ relationship: RelationshipContainer<O>.ToOne<D>) -> Where where S.Iterator.Element == D {
|
||||
|
||||
return Where(relationship.keyPath, isMemberOf: sequence)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ import Foundation
|
||||
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 species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
```
|
||||
@@ -68,8 +68,8 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
public required init(rawObject: NSManagedObject) {
|
||||
|
||||
self.isMeta = false
|
||||
self.rawObject = rawObject
|
||||
self.initializeAttributes(Mirror(reflecting: self), { [unowned self] in self })
|
||||
self.rawObject = (rawObject as! CoreStoreManagedObject)
|
||||
self.initializeAttributes(Mirror(reflecting: self), self)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,13 +110,13 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal let rawObject: NSManagedObject?
|
||||
internal let rawObject: CoreStoreManagedObject?
|
||||
internal let isMeta: Bool
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private func initializeAttributes(_ mirror: Mirror, _ parentObject: @escaping () -> CoreStoreObject) {
|
||||
private func initializeAttributes(_ mirror: Mirror, _ parentObject: CoreStoreObject) {
|
||||
|
||||
_ = mirror.superclassMirror.flatMap({ self.initializeAttributes($0, parentObject) })
|
||||
for child in mirror.children {
|
||||
@@ -135,3 +135,26 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - DynamicObject where Self: CoreStoreObject
|
||||
|
||||
public extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Returns the `PartialObject` instance for the object, which acts as a fast, type-safe KVC interface for `CoreStoreObject`.
|
||||
*/
|
||||
public func partialObject() -> PartialObject<Self> {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isMeta,
|
||||
"Attempted to create a \(cs_typeName(PartialObject<Self>.self)) from a meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return PartialObject<Self>(self.rawObject!)
|
||||
}
|
||||
|
||||
internal static var meta: Self {
|
||||
|
||||
return self.init(asMeta: ())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ import Foundation
|
||||
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 species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
|
||||
@@ -66,13 +66,13 @@ 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 species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
|
||||
@@ -112,12 +112,12 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
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 species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
}
|
||||
|
||||
CoreStore.defaultStack = DataStack(
|
||||
@@ -187,7 +187,7 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
#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:\n\(VersionLock(entityVersionHashesByName: self.rawModel().entityVersionHashesByName))"
|
||||
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
|
||||
}
|
||||
@@ -200,35 +200,44 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
|
||||
public func rawModel() -> NSManagedObjectModel {
|
||||
|
||||
if let cachedRawModel = self.cachedRawModel {
|
||||
return CoreStoreSchema.barrierQueue.sync(flags: .barrier) {
|
||||
|
||||
return cachedRawModel
|
||||
}
|
||||
let rawModel = NSManagedObjectModel()
|
||||
var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||
for entity in self.allEntities {
|
||||
|
||||
let entityDescription = self.entityDescription(
|
||||
for: entity,
|
||||
initializer: CoreStoreSchema.firstPassCreateEntityDescription
|
||||
if let cachedRawModel = self.cachedRawModel {
|
||||
|
||||
return cachedRawModel
|
||||
}
|
||||
let rawModel = NSManagedObjectModel()
|
||||
var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||
var allCustomGettersSetters: [DynamicEntity: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter]] = [:]
|
||||
for entity in self.allEntities {
|
||||
|
||||
let (entityDescription, customGetterSetterByKeyPaths) = self.entityDescription(
|
||||
for: entity,
|
||||
initializer: CoreStoreSchema.firstPassCreateEntityDescription(from:in:)
|
||||
)
|
||||
entityDescriptionsByEntity[entity] = (entityDescription.copy() as! NSEntityDescription)
|
||||
allCustomGettersSetters[entity] = customGetterSetterByKeyPaths
|
||||
}
|
||||
CoreStoreSchema.secondPassConnectRelationshipAttributes(for: entityDescriptionsByEntity)
|
||||
CoreStoreSchema.thirdPassConnectInheritanceTree(for: entityDescriptionsByEntity)
|
||||
CoreStoreSchema.fourthPassSynthesizeManagedObjectClasses(
|
||||
for: entityDescriptionsByEntity,
|
||||
allCustomGettersSetters: allCustomGettersSetters
|
||||
)
|
||||
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
|
||||
)
|
||||
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
|
||||
}
|
||||
self.cachedRawModel = rawModel
|
||||
return rawModel
|
||||
}
|
||||
|
||||
|
||||
@@ -244,28 +253,33 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
private let allEntities: Set<DynamicEntity>
|
||||
|
||||
private var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||
private var customGettersSettersByEntity: [DynamicEntity: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter]] = [:]
|
||||
private weak var cachedRawModel: NSManagedObjectModel?
|
||||
|
||||
private func entityDescription(for entity: DynamicEntity, initializer: (DynamicEntity) -> NSEntityDescription) -> NSEntityDescription {
|
||||
private func entityDescription(for entity: DynamicEntity, initializer: (DynamicEntity, ModelVersion) -> (entity: NSEntityDescription, customGetterSetterByKeyPaths: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter])) -> (entity: NSEntityDescription, customGetterSetterByKeyPaths: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter]) {
|
||||
|
||||
if let cachedEntityDescription = self.entityDescriptionsByEntity[entity] {
|
||||
|
||||
return cachedEntityDescription
|
||||
return (cachedEntityDescription, self.customGettersSettersByEntity[entity] ?? [:])
|
||||
}
|
||||
let entityDescription = withoutActuallyEscaping(initializer, do: { $0(entity) })
|
||||
let modelVersion = self.modelVersion
|
||||
let (entityDescription, customGetterSetterByKeyPaths) = withoutActuallyEscaping(initializer, do: { $0(entity, modelVersion) })
|
||||
self.entityDescriptionsByEntity[entity] = entityDescription
|
||||
return entityDescription
|
||||
self.customGettersSettersByEntity[entity] = customGetterSetterByKeyPaths
|
||||
return (entityDescription, customGetterSetterByKeyPaths)
|
||||
}
|
||||
|
||||
private static func firstPassCreateEntityDescription(from entity: DynamicEntity) -> NSEntityDescription {
|
||||
private static func firstPassCreateEntityDescription(from entity: DynamicEntity, in modelVersion: ModelVersion) -> (entity: NSEntityDescription, customGetterSetterByKeyPaths: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter]) {
|
||||
|
||||
let entityDescription = NSEntityDescription()
|
||||
entityDescription.coreStoreEntity = entity
|
||||
entityDescription.name = entity.entityName
|
||||
entityDescription.isAbstract = entity.isAbstract
|
||||
entityDescription.versionHashModifier = entity.versionHashModifier
|
||||
entityDescription.managedObjectClassName = NSStringFromClass(NSManagedObject.self)
|
||||
entityDescription.managedObjectClassName = CoreStoreManagedObject.cs_subclassName(for: entity, in: modelVersion)
|
||||
|
||||
var keyPathsByAffectedKeyPaths: [RawKeyPath: Set<RawKeyPath>] = [:]
|
||||
var customGetterSetterByKeyPaths: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter] = [:]
|
||||
func createProperties(for type: CoreStoreObject.Type) -> [NSPropertyDescription] {
|
||||
|
||||
var propertyDescriptions: [NSPropertyDescription] = []
|
||||
@@ -279,11 +293,13 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
description.attributeType = type(of: attribute).attributeType
|
||||
description.isOptional = attribute.isOptional
|
||||
description.isIndexed = attribute.isIndexed
|
||||
description.defaultValue = attribute.defaultValue
|
||||
description.defaultValue = attribute.defaultValue()
|
||||
description.isTransient = attribute.isTransient
|
||||
description.versionHashModifier = attribute.versionHashModifier
|
||||
description.renamingIdentifier = attribute.renamingIdentifier
|
||||
description.versionHashModifier = attribute.versionHashModifier()
|
||||
description.renamingIdentifier = attribute.renamingIdentifier()
|
||||
propertyDescriptions.append(description)
|
||||
keyPathsByAffectedKeyPaths[attribute.keyPath] = attribute.affectedByKeyPaths()
|
||||
customGetterSetterByKeyPaths[attribute.keyPath] = (attribute.getter, attribute.setter)
|
||||
|
||||
case let relationship as RelationshipProtocol:
|
||||
let description = NSRelationshipDescription()
|
||||
@@ -292,9 +308,10 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
description.maxCount = relationship.maxCount
|
||||
description.isOrdered = relationship.isOrdered
|
||||
description.deleteRule = relationship.deleteRule
|
||||
description.versionHashModifier = relationship.versionHashModifier
|
||||
description.renamingIdentifier = relationship.renamingIdentifier
|
||||
description.versionHashModifier = relationship.versionHashModifier()
|
||||
description.renamingIdentifier = relationship.renamingIdentifier()
|
||||
propertyDescriptions.append(description)
|
||||
keyPathsByAffectedKeyPaths[relationship.keyPath] = relationship.affectedByKeyPaths()
|
||||
|
||||
default:
|
||||
continue
|
||||
@@ -302,9 +319,9 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
}
|
||||
return propertyDescriptions
|
||||
}
|
||||
|
||||
entityDescription.properties = createProperties(for: entity.type as! CoreStoreObject.Type)
|
||||
return entityDescription
|
||||
entityDescription.keyPathsByAffectedKeyPaths = keyPathsByAffectedKeyPaths
|
||||
return (entityDescription, customGetterSetterByKeyPaths)
|
||||
}
|
||||
|
||||
private static func secondPassConnectRelationshipAttributes(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription]) {
|
||||
@@ -425,4 +442,112 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private static func fourthPassSynthesizeManagedObjectClasses(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription], allCustomGettersSetters: [DynamicEntity: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter]]) {
|
||||
|
||||
func createManagedObjectSubclass(for entityDescription: NSEntityDescription, customGetterSetterByKeyPaths: [RawKeyPath: CoreStoreManagedObject.CustomGetterSetter]?) {
|
||||
|
||||
let superEntity = entityDescription.superentity
|
||||
let className = entityDescription.managedObjectClassName!
|
||||
guard case nil = NSClassFromString(className) as! CoreStoreManagedObject.Type? else {
|
||||
|
||||
return
|
||||
}
|
||||
if let superEntity = superEntity {
|
||||
|
||||
createManagedObjectSubclass(
|
||||
for: superEntity,
|
||||
customGetterSetterByKeyPaths: superEntity.coreStoreEntity.flatMap({ allCustomGettersSetters[$0] })
|
||||
)
|
||||
}
|
||||
let superClass = cs_lazy { () -> CoreStoreManagedObject.Type in
|
||||
|
||||
if let superClassName = superEntity?.managedObjectClassName,
|
||||
let superClass = NSClassFromString(superClassName) {
|
||||
|
||||
return superClass as! CoreStoreManagedObject.Type
|
||||
}
|
||||
return CoreStoreManagedObject.self
|
||||
}
|
||||
let managedObjectClass: AnyClass = className.withCString {
|
||||
|
||||
return objc_allocateClassPair(superClass, $0, 0)!
|
||||
}
|
||||
defer {
|
||||
|
||||
objc_registerClassPair(managedObjectClass)
|
||||
}
|
||||
|
||||
func capitalize(_ string: String) -> String {
|
||||
|
||||
return string.replacingCharacters(
|
||||
in: Range(uncheckedBounds: (string.startIndex, string.index(after: string.startIndex))),
|
||||
with: String(string[string.startIndex]).uppercased()
|
||||
)
|
||||
}
|
||||
for (attributeName, customGetterSetters) in (customGetterSetterByKeyPaths ?? [:])
|
||||
where customGetterSetters.getter != nil || customGetterSetters.setter != nil {
|
||||
|
||||
if let getter = customGetterSetters.getter {
|
||||
|
||||
let getterName = "\(attributeName)"
|
||||
guard class_addMethod(
|
||||
managedObjectClass,
|
||||
NSSelectorFromString(getterName),
|
||||
imp_implementationWithBlock(getter),
|
||||
"@@:") else {
|
||||
|
||||
CoreStore.abort("Could not dynamically add getter method \"\(getterName)\" to class \(cs_typeName(managedObjectClass))")
|
||||
}
|
||||
}
|
||||
if let setter = customGetterSetters.setter {
|
||||
|
||||
let setterName = "set\(capitalize(attributeName)):"
|
||||
guard class_addMethod(
|
||||
managedObjectClass,
|
||||
NSSelectorFromString(setterName),
|
||||
imp_implementationWithBlock(setter),
|
||||
"v@:@") else {
|
||||
|
||||
CoreStore.abort("Could not dynamically add setter method \"\(setterName)\" to class \(cs_typeName(managedObjectClass))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let newSelector = NSSelectorFromString("cs_keyPathsForValuesAffectingValueForKey:")
|
||||
let keyPathsByAffectedKeyPaths = entityDescription.keyPathsByAffectedKeyPaths
|
||||
let keyPathsForValuesAffectingValue: @convention(block) (Any, String) -> Set<String> = { (instance, keyPath) in
|
||||
|
||||
if let keyPaths = keyPathsByAffectedKeyPaths[keyPath] {
|
||||
|
||||
return keyPaths
|
||||
}
|
||||
return []
|
||||
}
|
||||
let origSelector = #selector(NSManagedObject.keyPathsForValuesAffectingValue(forKey:))
|
||||
|
||||
let metaClass: AnyClass = object_getClass(managedObjectClass)!
|
||||
let origMethod = class_getClassMethod(managedObjectClass, origSelector)
|
||||
|
||||
let origImp = method_getImplementation(origMethod)
|
||||
let newImp = imp_implementationWithBlock(keyPathsForValuesAffectingValue)
|
||||
|
||||
if class_addMethod(metaClass, origSelector, newImp, method_getTypeEncoding(origMethod)) {
|
||||
|
||||
class_replaceMethod(metaClass, newSelector, origImp, method_getTypeEncoding(origMethod))
|
||||
}
|
||||
else {
|
||||
|
||||
let newMethod = class_getClassMethod(managedObjectClass, newSelector)
|
||||
method_exchangeImplementations(origMethod, newMethod)
|
||||
}
|
||||
}
|
||||
for (dynamicEntity, entityDescription) in entityDescriptionsByEntity {
|
||||
|
||||
createManagedObjectSubclass(
|
||||
for: entityDescription,
|
||||
customGetterSetterByKeyPaths: allCustomGettersSetters[dynamicEntity]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,28 @@ import Foundation
|
||||
|
||||
// MARK: - CustomSchemaMappingProvider
|
||||
|
||||
open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
/**
|
||||
A `SchemaMappingProvider` that accepts custom mappings for some entities. Mappings of entities with no `CustomMapping` provided will be automatically calculated if possible.
|
||||
*/
|
||||
public 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(
|
||||
@@ -54,16 +71,42 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
// 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 {
|
||||
|
||||
public typealias Transformer = (_ sourceObject: UnsafeSourceObject, _ createDestinationObject: () -> UnsafeDestinationObject) throws -> Void
|
||||
|
||||
/**
|
||||
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)
|
||||
|
||||
static func inferredTransformation(_ sourceObject: UnsafeSourceObject, _ createDestinationObject: () -> UnsafeDestinationObject) throws -> Void {
|
||||
/**
|
||||
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
|
||||
@@ -75,34 +118,6 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
}
|
||||
}
|
||||
|
||||
var entityMappingSourceEntity: EntityName? {
|
||||
|
||||
switch self {
|
||||
|
||||
case .deleteEntity(let sourceEntity),
|
||||
.copyEntity(let sourceEntity, _),
|
||||
.transformEntity(let sourceEntity, _, _):
|
||||
return sourceEntity
|
||||
|
||||
case .insertEntity:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var entityMappingDestinationEntity: EntityName? {
|
||||
|
||||
switch self {
|
||||
|
||||
case .insertEntity(let destinationEntity),
|
||||
.copyEntity(_, let destinationEntity),
|
||||
.transformEntity(_, let destinationEntity, _):
|
||||
return destinationEntity
|
||||
|
||||
case .deleteEntity:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
@@ -151,29 +166,80 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
^ 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 {
|
||||
|
||||
public subscript(attribute: KeyPath) -> Any? {
|
||||
/**
|
||||
Accesses the property value via its keyPath.
|
||||
*/
|
||||
public subscript(attribute: RawKeyPath) -> 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) {
|
||||
|
||||
for case let attribute as NSAttributeDescription in self.rawObject.entity.properties {
|
||||
func enumerate(_ entity: NSEntityDescription, _ closure: (NSAttributeDescription) -> Void) {
|
||||
|
||||
closure(attribute)
|
||||
if let superEntity = entity.superentity {
|
||||
|
||||
enumerate(superEntity, closure)
|
||||
}
|
||||
for case let attribute as NSAttributeDescription in entity.properties {
|
||||
|
||||
closure(attribute)
|
||||
}
|
||||
}
|
||||
enumerate(self.rawObject.entity, closure)
|
||||
}
|
||||
|
||||
|
||||
@@ -193,42 +259,62 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
// 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 {
|
||||
|
||||
public subscript(attribute: KeyPath) -> Any? {
|
||||
/**
|
||||
Accesses or mutates the property value via its keyPath.
|
||||
*/
|
||||
public subscript(attribute: RawKeyPath) -> 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) {
|
||||
|
||||
for case let attribute as NSAttributeDescription in self.rawObject.entity.properties {
|
||||
func enumerate(_ entity: NSEntityDescription, _ closure: (_ attribute: NSAttributeDescription, _ sourceAttribute: NSAttributeDescription?) -> Void) {
|
||||
|
||||
closure(attribute, self.sourceAttributesByDestinationKey[attribute.name])
|
||||
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]) {
|
||||
internal init(_ rawObject: NSManagedObject, _ sourceAttributesByDestinationKey: [RawKeyPath: NSAttributeDescription]) {
|
||||
|
||||
self.rawObject = rawObject
|
||||
self.sourceAttributesByDestinationKey = sourceAttributesByDestinationKey
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
// MARK: FilePrivate
|
||||
|
||||
private let rawObject: NSManagedObject
|
||||
private let sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription]
|
||||
fileprivate let rawObject: NSManagedObject
|
||||
fileprivate let sourceAttributesByDestinationKey: [RawKeyPath: NSAttributeDescription]
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +339,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
// MARK: SchemaMappingProvider
|
||||
|
||||
public func createMappingModel(from sourceSchema: DynamicSchema, to destinationSchema: DynamicSchema, storage: LocalStorage) throws -> (mappingModel: NSMappingModel, migrationType: MigrationType) {
|
||||
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()
|
||||
@@ -266,7 +352,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
)
|
||||
func expression(forSource sourceEntity: NSEntityDescription) -> NSExpression {
|
||||
|
||||
return NSExpression(format: "FETCH(FUNCTION($\(NSMigrationManagerKey), \"fetchRequestForSourceEntityNamed:predicateString:\" , \"\(sourceEntity.name!)\", \"\(NSPredicate(value: true))\"), $\(NSMigrationManagerKey).\(#keyPath(NSMigrationManager.sourceContext)), \(false))")
|
||||
return NSExpression(format: "FETCH(FUNCTION($\(NSMigrationManagerKey), \"fetchRequestForSourceEntityNamed:predicateString:\" , \"\(sourceEntity.name!)\", \"\(NSPredicate(value: true))\"), FUNCTION($\(NSMigrationManagerKey), \"\(#selector(getter: NSMigrationManager.sourceContext))\"), \(false))")
|
||||
}
|
||||
|
||||
let sourceEntitiesByName = sourceModel.entitiesByName
|
||||
@@ -341,22 +427,25 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
let destinationAttribute = destination.attribute
|
||||
let propertyMapping = NSPropertyMapping()
|
||||
propertyMapping.name = destinationAttribute.name
|
||||
propertyMapping.valueExpression = NSExpression(format: "$\(NSMigrationSourceObjectKey).\(sourceAttribute.name)")
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceAttribute.name)\")")
|
||||
attributeMappings.append(propertyMapping)
|
||||
}
|
||||
return attributeMappings
|
||||
}
|
||||
let entityMappingName = entityMapping.name!
|
||||
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||
|
||||
let sourceRelationships = sourceEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
var relationshipMappings: [NSPropertyMapping] = []
|
||||
for (_, destination) in destinationRelationships {
|
||||
for (renamingIdentifier, destination) in destinationRelationships {
|
||||
|
||||
let sourceRelationship = sourceRelationships[renamingIdentifier]!.relationship
|
||||
let destinationRelationship = destination.relationship
|
||||
let sourceRelationshipName = sourceRelationship.name
|
||||
|
||||
let propertyMapping = NSPropertyMapping()
|
||||
propertyMapping.name = destinationRelationship.name
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"\(#selector(NSMigrationManager.destinationInstances(forEntityMappingName:sourceInstances:)))\" , \"\(entityMappingName)\", $\(NSMigrationSourceObjectKey))[0]")
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"destinationInstancesForSourceRelationshipNamed:sourceInstances:\", \"\(sourceRelationshipName)\", FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceRelationshipName)\"))")
|
||||
relationshipMappings.append(propertyMapping)
|
||||
}
|
||||
return relationshipMappings
|
||||
@@ -388,7 +477,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
let transformedRenamingIdentifiers = Set(destinationAttributes.keys)
|
||||
.intersection(sourceAttributes.keys)
|
||||
|
||||
var sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription] = [:]
|
||||
var sourceAttributesByDestinationKey: [RawKeyPath: NSAttributeDescription] = [:]
|
||||
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||
|
||||
let sourceAttribute = sourceAttributes[renamingIdentifier]!.attribute
|
||||
@@ -397,17 +486,24 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
}
|
||||
userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] = sourceAttributesByDestinationKey
|
||||
}
|
||||
let entityMappingName = entityMapping.name!
|
||||
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||
|
||||
let sourceRelationships = sourceEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
let transformedRenamingIdentifiers = Set(destinationRelationships.keys)
|
||||
.intersection(sourceRelationships.keys)
|
||||
|
||||
var relationshipMappings: [NSPropertyMapping] = []
|
||||
for (_, destination) in destinationRelationships {
|
||||
|
||||
let destinationRelationship = destination.relationship
|
||||
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||
|
||||
let sourceRelationship = sourceRelationships[renamingIdentifier]!.relationship
|
||||
let destinationRelationship = destinationRelationships[renamingIdentifier]!.relationship
|
||||
let sourceRelationshipName = sourceRelationship.name
|
||||
let destinationRelationshipName = destinationRelationship.name
|
||||
|
||||
let propertyMapping = NSPropertyMapping()
|
||||
propertyMapping.name = destinationRelationship.name
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"\(#selector(NSMigrationManager.destinationInstances(forEntityMappingName:sourceInstances:)))\" , \"\(entityMappingName)\", $\(NSMigrationSourceObjectKey))[0]")
|
||||
propertyMapping.name = destinationRelationshipName
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"destinationInstancesForSourceRelationshipNamed:sourceInstances:\", \"\(sourceRelationshipName)\", FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceRelationshipName)\"))")
|
||||
relationshipMappings.append(propertyMapping)
|
||||
}
|
||||
return relationshipMappings
|
||||
@@ -439,27 +535,27 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
let userInfo = mapping.userInfo!
|
||||
let transformer = userInfo[CustomEntityMigrationPolicy.UserInfoKey.transformer]! as! CustomMapping.Transformer
|
||||
let sourceAttributesByDestinationKey = userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] as! [KeyPath: NSAttributeDescription]
|
||||
let sourceAttributesByDestinationKey = userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] as! [RawKeyPath: NSAttributeDescription]
|
||||
|
||||
var dInstance: NSManagedObject?
|
||||
var destinationObject: UnsafeDestinationObject?
|
||||
try transformer(
|
||||
UnsafeSourceObject(sInstance),
|
||||
{
|
||||
if let destinationObject = destinationObject {
|
||||
|
||||
return destinationObject
|
||||
}
|
||||
let rawObject = NSEntityDescription.insertNewObject(
|
||||
forEntityName: mapping.destinationEntityName!,
|
||||
into: manager.destinationContext
|
||||
)
|
||||
dInstance = rawObject
|
||||
return UnsafeDestinationObject(rawObject, sourceAttributesByDestinationKey)
|
||||
destinationObject = UnsafeDestinationObject(rawObject, sourceAttributesByDestinationKey)
|
||||
return destinationObject!
|
||||
}
|
||||
)
|
||||
if let dInstance = dInstance {
|
||||
if let dInstance = destinationObject?.rawObject {
|
||||
|
||||
manager.associate(
|
||||
sourceInstance: sInstance,
|
||||
withDestinationInstance: dInstance,
|
||||
for: mapping
|
||||
)
|
||||
manager.associate(sourceInstance: sInstance, withDestinationInstance: dInstance, for: mapping)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,8 +585,8 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
var insertMappings: Set<CustomMapping> = []
|
||||
var copyMappings: Set<CustomMapping> = []
|
||||
var transformMappings: Set<CustomMapping> = []
|
||||
var allMappedSourceKeys: [KeyPath: KeyPath] = [:]
|
||||
var allMappedDestinationKeys: [KeyPath: KeyPath] = [:]
|
||||
var allMappedSourceKeys: [RawKeyPath: RawKeyPath] = [:]
|
||||
var allMappedDestinationKeys: [RawKeyPath: RawKeyPath] = [:]
|
||||
|
||||
let sourceRenamingIdentifiers = sourceModel.cs_resolvedRenamingIdentities()
|
||||
let sourceEntityNames = sourceModel.entitiesByName
|
||||
@@ -580,77 +676,76 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
allMappedSourceKeys[sourceEntity] = destinationEntity
|
||||
allMappedDestinationKeys[destinationEntity] = sourceEntity
|
||||
}
|
||||
}
|
||||
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||
|
||||
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]) {
|
||||
|
||||
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 {
|
||||
|
||||
case (nil, nil):
|
||||
if sourceEntity.versionHash == destinationEntity.versionHash {
|
||||
|
||||
copyMappings.insert(
|
||||
.copyEntity(
|
||||
sourceEntity: sourceEntityName,
|
||||
destinationEntity: destinationEntityName
|
||||
)
|
||||
copyMappings.insert(
|
||||
.copyEntity(
|
||||
sourceEntity: sourceEntityName,
|
||||
destinationEntity: destinationEntityName
|
||||
)
|
||||
}
|
||||
else {
|
||||
|
||||
transformMappings.insert(
|
||||
.transformEntity(
|
||||
sourceEntity: sourceEntityName,
|
||||
destinationEntity: destinationEntityName,
|
||||
transformer: CustomMapping.inferredTransformation
|
||||
)
|
||||
)
|
||||
}
|
||||
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 {
|
||||
allMappedSourceKeys[sourceEntityName] = destinationEntityName
|
||||
allMappedDestinationKeys[destinationEntityName] = sourceEntityName
|
||||
|
||||
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 {
|
||||
case (""?, nil):
|
||||
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||
allMappedDestinationKeys[destinationEntityName] = ""
|
||||
|
||||
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let destinationEntityName = destinationEntity.name!
|
||||
switch allMappedDestinationKeys[destinationEntityName] {
|
||||
|
||||
case nil:
|
||||
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||
allMappedDestinationKeys[destinationEntityName] = ""
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
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)
|
||||
|
||||
@@ -47,7 +47,7 @@ public extension DataStack {
|
||||
- parameter storage: the storage
|
||||
- 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>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
public func addStorage<T>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
|
||||
self.coordinator.performAsynchronously {
|
||||
|
||||
@@ -173,7 +173,7 @@ public extension DataStack {
|
||||
|
||||
do {
|
||||
|
||||
try storage.eraseStorageAndWait(
|
||||
try storage.cs_eraseStorageAndWait(
|
||||
metadata: metadata,
|
||||
soureModelHint: self.schemaHistory.schema(for: metadata)?.rawModel()
|
||||
)
|
||||
@@ -341,7 +341,7 @@ public extension DataStack {
|
||||
)
|
||||
_ = try self.schemaHistory
|
||||
.schema(for: metadata)
|
||||
.flatMap({ try storage.eraseStorageAndWait(soureModel: $0.rawModel()) })
|
||||
.flatMap({ try storage.cs_eraseStorageAndWait(soureModel: $0.rawModel()) })
|
||||
_ = try self.createPersistentStoreFromStorage(
|
||||
storage,
|
||||
finalURL: cacheFileURL,
|
||||
@@ -575,6 +575,7 @@ public extension DataStack {
|
||||
sourceModel: sourceModel,
|
||||
destinationModel: destinationModel,
|
||||
mappingModel: mappingModel,
|
||||
migrationType: migrationType,
|
||||
progress: childProgress
|
||||
)
|
||||
}
|
||||
@@ -679,10 +680,66 @@ public extension DataStack {
|
||||
return nil
|
||||
}
|
||||
|
||||
private func startMigrationForStorage<T: LocalStorage>(_ storage: T, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, progress: Progress) throws {
|
||||
private func startMigrationForStorage<T: LocalStorage>(_ storage: T, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType, progress: Progress) throws {
|
||||
|
||||
let fileURL = storage.fileURL
|
||||
|
||||
if case .lightweight = migrationType {
|
||||
|
||||
do {
|
||||
|
||||
let timerQueue = DispatchQueue(
|
||||
label: "DataStack.lightweightMigration.timerQueue",
|
||||
qos: .utility,
|
||||
attributes: []
|
||||
)
|
||||
let estimatedTime: TimeInterval = 60 * 3 // 3 mins
|
||||
let interval: TimeInterval = 1
|
||||
let fakeTotalUnitCount: Float = 0.9 * Float(progress.totalUnitCount)
|
||||
var fakeProgress: Float = 0
|
||||
|
||||
var recursiveCheck: () -> Void = {}
|
||||
recursiveCheck = {
|
||||
|
||||
guard fakeProgress < 1 else {
|
||||
|
||||
return
|
||||
}
|
||||
progress.completedUnitCount = Int64(fakeTotalUnitCount * fakeProgress)
|
||||
fakeProgress += Float(interval / estimatedTime)
|
||||
|
||||
timerQueue.asyncAfter(
|
||||
deadline: .now() + interval,
|
||||
execute: recursiveCheck
|
||||
)
|
||||
}
|
||||
timerQueue.async(execute: recursiveCheck)
|
||||
|
||||
_ = try storage.cs_finalizeStorageAndWait(soureModelHint: sourceModel)
|
||||
_ = try withExtendedLifetime(NSPersistentStoreCoordinator(managedObjectModel: destinationModel)) { (coordinator: NSPersistentStoreCoordinator) in
|
||||
|
||||
try coordinator.addPersistentStoreSynchronously(
|
||||
type(of: storage).storeType,
|
||||
configuration: storage.configuration,
|
||||
URL: fileURL,
|
||||
options: storage.dictionary(
|
||||
forOptions: storage.localStorageOptions.union(.allowSynchronousLightweightMigration)
|
||||
)
|
||||
)
|
||||
}
|
||||
timerQueue.sync {
|
||||
|
||||
fakeProgress = 1
|
||||
}
|
||||
_ = try? storage.cs_finalizeStorageAndWait(soureModelHint: destinationModel)
|
||||
progress.completedUnitCount = progress.totalUnitCount
|
||||
return
|
||||
}
|
||||
catch {
|
||||
|
||||
// try manual migration
|
||||
}
|
||||
}
|
||||
|
||||
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
||||
.appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack")
|
||||
.appendingPathComponent(ProcessInfo().globallyUniqueString)
|
||||
@@ -707,6 +764,7 @@ public extension DataStack {
|
||||
|
||||
do {
|
||||
|
||||
try storage.cs_finalizeStorageAndWait(soureModelHint: sourceModel)
|
||||
try migrationManager.migrateStore(
|
||||
from: fileURL,
|
||||
sourceType: type(of: storage).storeType,
|
||||
@@ -716,6 +774,13 @@ public extension DataStack {
|
||||
destinationType: type(of: storage).storeType,
|
||||
destinationOptions: nil
|
||||
)
|
||||
let temporaryStorage = SQLiteStore(
|
||||
fileURL: temporaryFileURL,
|
||||
configuration: storage.configuration,
|
||||
migrationMappingProviders: storage.migrationMappingProviders,
|
||||
localStorageOptions: storage.localStorageOptions
|
||||
)
|
||||
try temporaryStorage.cs_finalizeStorageAndWait(soureModelHint: destinationModel)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -756,17 +821,17 @@ fileprivate extension Array where Element == SchemaMappingProvider {
|
||||
|
||||
case let element as CustomSchemaMappingProvider
|
||||
where element.sourceVersion == sourceSchema.modelVersion && element.destinationVersion == destinationSchema.modelVersion:
|
||||
return try element.createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||
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.createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||
return try element.cs_createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return try InferredSchemaMappingProvider()
|
||||
.createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||
.cs_createMappingModel(from: sourceSchema, to: destinationSchema, storage: storage)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@ import CoreData
|
||||
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`
|
||||
*/
|
||||
public func monitorObject<T: DynamicObject>(_ object: T) -> ObjectMonitor<T> {
|
||||
public func monitorObject<T>(_ object: T) -> ObjectMonitor<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -48,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 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
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public func monitorList<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
|
||||
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 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
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public func monitorList<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -89,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 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.
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||
public func monitorList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||
|
||||
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 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.
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||
public func monitorList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -131,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 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public func monitorSectionedList<T>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
|
||||
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 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public func monitorSectionedList<T>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -175,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 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 fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||
public func monitorSectionedList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||
|
||||
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 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 fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||
public func monitorSectionedList<T>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
|
||||
@@ -34,10 +34,10 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
// 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`
|
||||
- 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: DynamicObject>(_ object: T) -> T? {
|
||||
|
||||
@@ -45,10 +45,10 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
- 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: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||
|
||||
@@ -56,10 +56,10 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
/**
|
||||
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`
|
||||
- returns: the `NSManagedObject` array for objects that exists in the `DataStack`
|
||||
- parameter objects: an array of `DynamicObject`s created/fetched outside the `DataStack`
|
||||
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||
|
||||
@@ -67,10 +67,10 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
- 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: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||
|
||||
@@ -78,13 +78,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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
public func fetchOne<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
public func fetchOne<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
public func fetchAll<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
public func fetchAll<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
public func fetchCount<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
public func fetchCount<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
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 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: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -250,7 +250,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
public func queryValue<T, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -269,7 +269,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
public func queryValue<T, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -288,7 +288,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
public func queryAttributes<T>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -307,7 +307,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
public func queryAttributes<T>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -328,11 +328,11 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
// MARK: Obsoleted
|
||||
|
||||
@available(*, deprecated, renamed: "unsafeContext()")
|
||||
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
|
||||
public func internalContext() -> NSManagedObjectContext {
|
||||
|
||||
return self.unsafeContext()
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ import CoreData
|
||||
public extension DataStack {
|
||||
|
||||
/**
|
||||
Performs a transaction asynchronously where `NSManagedObject` 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 `TransactionResult.success(userInfo: T)` in the `completion`'s `TransactionResult<T>`. Any errors thrown from inside the `task` will be reported as `TransactionResult.failure(error: Error)`. To cancel/rollback changes, call `transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(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 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 `TransactionResult` 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 `CoreStoreError.userCancelled`. Custom errors thrown by the user will be wrapped in `CoreStoreError.userError(error: Error)`.
|
||||
- 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 perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, completion: @escaping (AsynchronousDataTransaction.Result<T>) -> Void) {
|
||||
|
||||
@@ -47,11 +47,11 @@ public extension DataStack {
|
||||
}
|
||||
|
||||
/**
|
||||
Performs a transaction asynchronously where `NSManagedObject` 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 `transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the 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 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 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)`.
|
||||
- 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)`.
|
||||
*/
|
||||
public func perform<T>(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, success: @escaping (T) -> Void, failure: @escaping (CoreStoreError) -> Void) {
|
||||
|
||||
@@ -78,6 +78,10 @@ public extension DataStack {
|
||||
}
|
||||
transaction.autoCommit { (_, error) in
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime((self, transaction), {})
|
||||
}
|
||||
if let error = error {
|
||||
|
||||
failure(error)
|
||||
@@ -91,7 +95,7 @@ public extension DataStack {
|
||||
}
|
||||
|
||||
/**
|
||||
Performs a transaction synchronously where `NSManagedObject` 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 `transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
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 thrown 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`.
|
||||
@@ -106,6 +110,10 @@ public extension DataStack {
|
||||
)
|
||||
return try transaction.transactionQueue.cs_sync {
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime((self, transaction), {})
|
||||
}
|
||||
let userInfo: T
|
||||
do {
|
||||
|
||||
@@ -131,7 +139,7 @@ public extension DataStack {
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
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.
|
||||
- returns: a `UnsafeDataTransaction` instance where creates, updates, and deletes can be made.
|
||||
@@ -146,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() {
|
||||
|
||||
@@ -160,11 +168,6 @@ public extension DataStack {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Begins a transaction asynchronously 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`.
|
||||
*/
|
||||
@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) {
|
||||
|
||||
@@ -186,12 +189,6 @@ public extension DataStack {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Begins a transaction synchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
|
||||
- parameter closure: the block where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- returns: a `SaveResult` value indicating success or failure, or `nil` if the transaction was not comitted synchronously
|
||||
*/
|
||||
@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? {
|
||||
@@ -214,9 +211,9 @@ public extension DataStack {
|
||||
}
|
||||
switch transaction.result {
|
||||
|
||||
case nil: return nil
|
||||
case (let hasChanges, nil)?: return SaveResult(hasChanges: hasChanges)
|
||||
case (_, let error?)?: return SaveResult(error)
|
||||
case .none: return nil
|
||||
case .some(let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
|
||||
case .some(_, let error?): return SaveResult(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,16 +37,19 @@ public final class DataStack: Equatable {
|
||||
/**
|
||||
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 (e.g. in Unit Tests).
|
||||
- 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 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: XcodeDataModelFileName = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
||||
public convenience init(xcodeModelName: XcodeDataModelFileName = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
||||
|
||||
self.init(
|
||||
schemaHistory: SchemaHistory(
|
||||
modelName: modelName,
|
||||
bundle: bundle,
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: xcodeModelName,
|
||||
bundle: bundle,
|
||||
migrationChain: migrationChain
|
||||
),
|
||||
migrationChain: migrationChain
|
||||
)
|
||||
)
|
||||
@@ -102,9 +105,6 @@ public final class DataStack: Equatable {
|
||||
*/
|
||||
public required init(schemaHistory: SchemaHistory) {
|
||||
|
||||
// TODO: test before release (rolled back)
|
||||
// _ = DataStack.isGloballyInitialized
|
||||
|
||||
self.coordinator = NSPersistentStoreCoordinator(managedObjectModel: schemaHistory.rawModel)
|
||||
self.rootSavingContext = NSManagedObjectContext.rootSavingContextForCoordinator(self.coordinator)
|
||||
self.mainContext = NSManagedObjectContext.mainContextForRootContext(self.rootSavingContext)
|
||||
@@ -328,7 +328,7 @@ public final class DataStack: Equatable {
|
||||
at: fileURL,
|
||||
options: storeOptions
|
||||
)
|
||||
try storage.eraseStorageAndWait(
|
||||
try storage.cs_eraseStorageAndWait(
|
||||
metadata: metadata,
|
||||
soureModelHint: self.schemaHistory.schema(for: metadata)?.rawModel()
|
||||
)
|
||||
@@ -425,7 +425,7 @@ public final class DataStack: Equatable {
|
||||
)
|
||||
_ = try self.schemaHistory
|
||||
.schema(for: metadata)
|
||||
.flatMap({ try storage.eraseStorageAndWait(soureModel: $0.rawModel()) })
|
||||
.flatMap({ try storage.cs_eraseStorageAndWait(soureModel: $0.rawModel()) })
|
||||
_ = try self.createPersistentStoreFromStorage(
|
||||
storage,
|
||||
finalURL: cacheFileURL,
|
||||
@@ -459,7 +459,7 @@ public final class DataStack: Equatable {
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
*/
|
||||
private let userInfo = UserInfo()
|
||||
public let userInfo = UserInfo()
|
||||
|
||||
|
||||
// MARK: Equatable
|
||||
@@ -570,7 +570,7 @@ public final class DataStack: Equatable {
|
||||
self.finalConfigurationsByEntityIdentifier[entityIdentifier]?.insert(configurationName)
|
||||
}
|
||||
}
|
||||
storage.didAddToDataStack(self)
|
||||
storage.cs_didAddToDataStack(self)
|
||||
return persistentStore
|
||||
}
|
||||
|
||||
@@ -582,13 +582,6 @@ public final class DataStack: Equatable {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
// TODO: test before release (rolled back)
|
||||
// private static let isGloballyInitialized: Bool = {
|
||||
//
|
||||
// NSManagedObject.cs_swizzleMethodsForLogging()
|
||||
// return true
|
||||
// }()
|
||||
|
||||
private var persistentStoresByFinalConfiguration = [String: NSPersistentStore]()
|
||||
private var finalConfigurationsByEntityIdentifier = [EntityIdentifier: Set<String>]()
|
||||
|
||||
@@ -610,20 +603,25 @@ public final class DataStack: Equatable {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
/**
|
||||
Initializes a `DataStack` from an `NSManagedObjectModel`.
|
||||
|
||||
- parameter model: the `NSManagedObjectModel` for the 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.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the new DataStack.init(schemaHistory:) initializer passing a LegacyXcodeDataModelSchema instance as argument")
|
||||
@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: [
|
||||
LegacyXcodeDataModelSchema(
|
||||
UnsafeDataModelSchema(
|
||||
modelName: modelVersion,
|
||||
model: model
|
||||
)
|
||||
@@ -634,10 +632,7 @@ public final class DataStack: Equatable {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the entity name-to-class type mapping from the `DataStack`'s model.
|
||||
*/
|
||||
@available(*, deprecated: 3.1, message: "Use the new DataStack.entityTypesByName(for:) method passing `NSManagedObject.self` as argument.")
|
||||
@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)
|
||||
|
||||
@@ -33,12 +33,6 @@ import Foundation
|
||||
*/
|
||||
public final class DefaultLogger: CoreStoreLogger {
|
||||
|
||||
/**
|
||||
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false`.
|
||||
*/
|
||||
// TODO: test before release (rolled back)
|
||||
// public var enableObjectConcurrencyDebugging: Bool = false
|
||||
|
||||
/**
|
||||
Creates a `DefaultLogger`.
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,16 @@ public protocol DynamicObject: class {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@@ -68,12 +78,17 @@ extension NSManagedObject: DynamicObject {
|
||||
|
||||
public class func cs_fromRaw(object: NSManagedObject) -> Self {
|
||||
|
||||
@inline(__always)
|
||||
func forceCast<T: NSManagedObject>(_ value: Any) -> T {
|
||||
|
||||
return value as! T
|
||||
}
|
||||
return forceCast(object)
|
||||
return unsafeDowncast(object, to: self)
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -104,31 +119,33 @@ extension CoreStoreObject {
|
||||
|
||||
if let coreStoreObject = object.coreStoreObject {
|
||||
|
||||
@inline(__always)
|
||||
func forceCast<T: CoreStoreObject>(_ value: CoreStoreObject) -> T {
|
||||
|
||||
return value as! T
|
||||
}
|
||||
return forceCast(coreStoreObject)
|
||||
return unsafeDowncast(coreStoreObject, to: self)
|
||||
}
|
||||
let coreStoreObject = self.init(rawObject: object)
|
||||
func forceTypeCast<T: CoreStoreObject>(_ type: AnyClass, to: T.Type) -> T.Type {
|
||||
|
||||
return type as! T.Type
|
||||
}
|
||||
let coreStoreObject = forceTypeCast(object.entity.dynamicObjectType!, to: 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: ())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,12 @@ import Foundation
|
||||
|
||||
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()
|
||||
@@ -90,72 +96,62 @@ public extension DynamicSchema {
|
||||
|
||||
case .integer16AttributeType:
|
||||
valueType = Int16.self
|
||||
if let defaultValue = (attribute.defaultValue as! Int16.ImportableNativeType?).flatMap(Int16.cs_fromImportableNativeType),
|
||||
defaultValue != Int16.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Int16.QueryableNativeType?).flatMap(Int16.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .integer32AttributeType:
|
||||
valueType = Int32.self
|
||||
if let defaultValue = (attribute.defaultValue as! Int32.ImportableNativeType?).flatMap(Int32.cs_fromImportableNativeType),
|
||||
defaultValue != Int32.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Int32.QueryableNativeType?).flatMap(Int32.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .integer64AttributeType:
|
||||
valueType = Int64.self
|
||||
if let defaultValue = (attribute.defaultValue as! Int64.ImportableNativeType?).flatMap(Int64.cs_fromImportableNativeType),
|
||||
defaultValue != Int64.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Int64.QueryableNativeType?).flatMap(Int64.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .decimalAttributeType:
|
||||
valueType = NSDecimalNumber.self
|
||||
if let defaultValue = (attribute.defaultValue as! NSDecimalNumber.ImportableNativeType?).flatMap(NSDecimalNumber.cs_fromImportableNativeType),
|
||||
defaultValue != NSDecimalNumber.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! NSDecimalNumber?) {
|
||||
|
||||
defaultString = ", default: NSDecimalNumber(string: \"\(defaultValue.description(withLocale: nil))\")"
|
||||
defaultString = ", initial: 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() {
|
||||
if let defaultValue = (attribute.defaultValue as! Double.QueryableNativeType?).flatMap(Double.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .floatAttributeType:
|
||||
valueType = Float.self
|
||||
if let defaultValue = (attribute.defaultValue as! Float.ImportableNativeType?).flatMap(Float.cs_fromImportableNativeType),
|
||||
defaultValue != Float.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Float.QueryableNativeType?).flatMap(Float.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .stringAttributeType:
|
||||
valueType = String.self
|
||||
if let defaultValue = (attribute.defaultValue as! String.ImportableNativeType?).flatMap(String.cs_fromImportableNativeType),
|
||||
defaultValue != String.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! String.QueryableNativeType?).flatMap(String.cs_fromQueryableNativeType) {
|
||||
|
||||
// TODO: escape strings
|
||||
defaultString = ", default: \"\(defaultValue)\""
|
||||
defaultString = ", initial: \"\(defaultValue)\""
|
||||
}
|
||||
case .booleanAttributeType:
|
||||
valueType = Bool.self
|
||||
if let defaultValue = (attribute.defaultValue as! Bool.ImportableNativeType?).flatMap(Bool.cs_fromImportableNativeType),
|
||||
defaultValue != Bool.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Bool.QueryableNativeType?).flatMap(Bool.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue ? "true" : "false")"
|
||||
defaultString = ", initial: \(defaultValue ? "true" : "false")"
|
||||
}
|
||||
case .dateAttributeType:
|
||||
valueType = Date.self
|
||||
if let defaultValue = (attribute.defaultValue as! Date.ImportableNativeType?).flatMap(Date.cs_fromImportableNativeType),
|
||||
defaultValue != Date.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Date.QueryableNativeType?).flatMap(Date.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: Date(timeIntervalSinceReferenceDate: \(defaultValue.timeIntervalSinceReferenceDate))"
|
||||
defaultString = ", initial: 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() {
|
||||
if let defaultValue = (attribute.defaultValue as! Data.QueryableNativeType?).flatMap(Data.cs_fromQueryableNativeType) {
|
||||
|
||||
let count = defaultValue.count
|
||||
let bytes = defaultValue.withUnsafeBytes { (pointer: UnsafePointer<UInt8>) in
|
||||
@@ -163,7 +159,7 @@ public extension DynamicSchema {
|
||||
return (0 ..< (count / MemoryLayout<UInt8>.size))
|
||||
.map({ "\("0x\(String(pointer[$0], radix: 16, uppercase: false))")" })
|
||||
}
|
||||
defaultString = ", default: Data(bytes: [\(bytes.joined(separator: ", "))])"
|
||||
defaultString = ", initial: Data(bytes: [\(bytes.joined(separator: ", "))])"
|
||||
}
|
||||
case .transformableAttributeType:
|
||||
if let attributeValueClassName = attribute.attributeValueClassName {
|
||||
@@ -176,11 +172,11 @@ public extension DynamicSchema {
|
||||
}
|
||||
if let defaultValue = attribute.defaultValue {
|
||||
|
||||
defaultString = ", default: /* \"\(defaultValue)\" */"
|
||||
defaultString = ", initial: /* \"\(defaultValue)\" */"
|
||||
}
|
||||
else if !attribute.isOptional {
|
||||
|
||||
defaultString = ", default: /* required */"
|
||||
defaultString = ", initial: /* required */"
|
||||
}
|
||||
default:
|
||||
fatalError("Unsupported attribute type: \(attribute.attributeType.rawValue)")
|
||||
@@ -188,9 +184,11 @@ public extension DynamicSchema {
|
||||
let indexedString = attribute.isIndexed ? ", isIndexed: true" : ""
|
||||
let transientString = attribute.isTransient ? ", isTransient: true" : ""
|
||||
// TODO: escape strings
|
||||
let versionHashModifierString = attribute.versionHashModifier.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||
let versionHashModifierString = attribute.versionHashModifier
|
||||
.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||
// TODO: escape strings
|
||||
let renamingIdentifierString = attribute.renamingIdentifier.flatMap({ ", renamingIdentifier: \"\($0)\"" }) ?? ""
|
||||
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")
|
||||
}
|
||||
}
|
||||
@@ -255,8 +253,10 @@ public extension DynamicSchema {
|
||||
fatalError("Unsupported delete rule \((relationship.deleteRule)) for relationship \"\(relationshipQualifier)\"")
|
||||
}
|
||||
}
|
||||
let versionHashModifierString = relationship.versionHashModifier.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||
let renamingIdentifierString = relationship.renamingIdentifier.flatMap({ ", renamingIdentifier: \"\($0)\"" }) ?? ""
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import Foundation
|
||||
/**
|
||||
`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.
|
||||
- `LegacyXcodeDataModelSchema`: 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.
|
||||
- `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 {
|
||||
|
||||
@@ -34,13 +34,13 @@ import ObjectiveC
|
||||
The `Entity<O>` contains `NSEntityDescription` metadata for `CoreStoreObject` subclasses. Pass the `Entity` instances to `CoreStoreSchema` initializer.
|
||||
```
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species")
|
||||
let species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ internal struct EntityIdentifier: Hashable {
|
||||
internal init(_ type: CoreStoreObject.Type) {
|
||||
|
||||
self.category = .coreStore
|
||||
self.interfacedClassName = String(reflecting: type)
|
||||
self.interfacedClassName = NSStringFromClass(type)
|
||||
}
|
||||
|
||||
internal init(_ type: DynamicObject.Type) {
|
||||
|
||||
@@ -35,135 +35,129 @@ import CoreData
|
||||
public protocol FetchableSource: class {
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instance in the `FetchableSource`'s context from a reference created from another managed object context.
|
||||
Fetches the `DynamicObject` instance in the `FetchableSource`'s context from a reference created from another managed object context.
|
||||
|
||||
- parameter object: a reference to the object created/fetched outside the `FetchableSource`'s context
|
||||
- returns: the `NSManagedObject` instance if the object exists in the `FetchableSource`'s context, or `nil` if not found.
|
||||
- returns: the `DynamicObject` instance if the object exists in the `FetchableSource`'s context, or `nil` if not found.
|
||||
*/
|
||||
func fetchExisting<T: DynamicObject>(_ object: T) -> T?
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instance in the `FetchableSource`'s context from an `NSManagedObjectID`.
|
||||
Fetches the `DynamicObject` instance in the `FetchableSource`'s context from an `NSManagedObjectID`.
|
||||
|
||||
- parameter objectID: the `NSManagedObjectID` for the object
|
||||
- returns: the `NSManagedObject` instance if the object exists in the `FetchableSource`, or `nil` if not found.
|
||||
- returns: the `DynamicObject` instance if the object exists in the `FetchableSource`, or `nil` if not found.
|
||||
*/
|
||||
func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T?
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instances in the `FetchableSource`'s context from references created from another managed object context.
|
||||
Fetches the `DynamicObject` instances in the `FetchableSource`'s context from references created from another managed object context.
|
||||
|
||||
- parameter objects: an array of `NSManagedObject`s created/fetched outside the `FetchableSource`'s context
|
||||
- returns: the `NSManagedObject` array for objects that exists in the `FetchableSource`
|
||||
- parameter objects: an array of `DynamicObject`s created/fetched outside the `FetchableSource`'s context
|
||||
- returns: the `DynamicObject` array for objects that exists in the `FetchableSource`
|
||||
*/
|
||||
func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instances in the `FetchableSource`'s context from a list of `NSManagedObjectID`.
|
||||
Fetches the `DynamicObject` instances in the `FetchableSource`'s context from a list of `NSManagedObjectID`.
|
||||
|
||||
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
||||
- returns: the `NSManagedObject` array for objects that exists in the `FetchableSource`'s context
|
||||
- returns: the `DynamicObject` array for objects that exists in the `FetchableSource`'s context
|
||||
*/
|
||||
func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID
|
||||
|
||||
/**
|
||||
Fetches the first `NSManagedObject` instance that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
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 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
|
||||
*/
|
||||
func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T?
|
||||
func fetchOne<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T?
|
||||
func fetchOne<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]?
|
||||
func fetchAll<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]?
|
||||
func fetchAll<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int?
|
||||
func fetchCount<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int?
|
||||
func fetchCount<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID?
|
||||
func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID?
|
||||
func fetchObjectID<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]?
|
||||
func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]?
|
||||
|
||||
/**
|
||||
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 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
|
||||
*/
|
||||
func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]?
|
||||
func fetchObjectIDs<T>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]?
|
||||
|
||||
/**
|
||||
The internal `NSManagedObjectContext` managed by this `FetchableSource`. Using this context directly should typically be avoided, and is provided by CoreStore only for extremely specialized cases.
|
||||
*/
|
||||
func unsafeContext() -> NSManagedObjectContext
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, renamed: "unsafeContext()")
|
||||
func internalContext() -> NSManagedObjectContext
|
||||
}
|
||||
|
||||
@@ -185,6 +185,10 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
)
|
||||
return
|
||||
}
|
||||
guard #available(iOS 9.0, tvOS 9.0, watchOS 9.0, *) else {
|
||||
|
||||
return
|
||||
}
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
|
||||
@@ -32,11 +32,11 @@ import CoreData
|
||||
/**
|
||||
A `From` clause specifies the source entity and source persistent store for fetch and query methods. A common usage is to just indicate the entity:
|
||||
```
|
||||
let person = transaction.fetchOne(From<MyPersonEntity>())
|
||||
let person = transaction.fetchOne(From<Person>())
|
||||
```
|
||||
For cases where multiple `NSPersistentStore`s contain the same entity, the source configuration's name needs to be specified as well:
|
||||
```
|
||||
let person = transaction.fetchOne(From<MyPersonEntity>("Configuration1"))
|
||||
let person = transaction.fetchOne(From<Person>("Configuration1"))
|
||||
```
|
||||
*/
|
||||
public struct From<T: DynamicObject> {
|
||||
@@ -139,7 +139,7 @@ public struct From<T: DynamicObject> {
|
||||
self.findPersistentStores = findPersistentStores
|
||||
}
|
||||
|
||||
internal func applyToFetchRequest<ResultType: NSFetchRequestResult>(_ fetchRequest: NSFetchRequest<ResultType>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) -> Bool {
|
||||
internal func applyToFetchRequest<ResultType>(_ fetchRequest: NSFetchRequest<ResultType>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) -> Bool {
|
||||
|
||||
fetchRequest.entity = context.parentStack!.entityDescription(for: EntityIdentifier(self.entityClass))!
|
||||
guard applyAffectedStores else {
|
||||
@@ -157,7 +157,7 @@ public struct From<T: DynamicObject> {
|
||||
return false
|
||||
}
|
||||
|
||||
internal func applyAffectedStoresForFetchedRequest<U: NSFetchRequestResult>(_ fetchRequest: NSFetchRequest<U>, context: NSManagedObjectContext) -> Bool {
|
||||
internal func applyAffectedStoresForFetchedRequest<U>(_ fetchRequest: NSFetchRequest<U>, context: NSManagedObjectContext) -> Bool {
|
||||
|
||||
let stores = self.findPersistentStores(context)
|
||||
fetchRequest.affectedStores = stores
|
||||
|
||||
@@ -37,7 +37,7 @@ public struct GroupBy: QueryClause, Hashable {
|
||||
/**
|
||||
The list of key path strings to group results with
|
||||
*/
|
||||
public let keyPaths: [KeyPath]
|
||||
public let keyPaths: [RawKeyPath]
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with an empty list of key path strings
|
||||
@@ -53,7 +53,7 @@ public struct GroupBy: QueryClause, Hashable {
|
||||
- parameter keyPath: a key path string to group results with
|
||||
- parameter keyPaths: a series of key path strings to group results with
|
||||
*/
|
||||
public init(_ keyPath: KeyPath, _ keyPaths: KeyPath...) {
|
||||
public init(_ keyPath: RawKeyPath, _ keyPaths: RawKeyPath...) {
|
||||
|
||||
self.init([keyPath] + keyPaths)
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public struct GroupBy: QueryClause, Hashable {
|
||||
|
||||
- parameter keyPaths: a list of key path strings to group results with
|
||||
*/
|
||||
public init(_ keyPaths: [KeyPath]) {
|
||||
public init(_ keyPaths: [RawKeyPath]) {
|
||||
|
||||
self.keyPaths = keyPaths
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public struct GroupBy: QueryClause, Hashable {
|
||||
|
||||
// MARK: QueryClause
|
||||
|
||||
public func applyToFetchRequest<ResultType: NSFetchRequestResult>(_ fetchRequest: NSFetchRequest<ResultType>) {
|
||||
public func applyToFetchRequest<ResultType>(_ fetchRequest: NSFetchRequest<ResultType>) {
|
||||
|
||||
if let keyPaths = fetchRequest.propertiesToGroupBy as? [String], keyPaths != self.keyPaths {
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ public final class ICloudStore: CloudStorage {
|
||||
- parameter ubiquitousContainerID: a container if your app has multiple ubiquity container identifiers in its entitlements
|
||||
- parameter ubiquitousPeerToken: a per-application salt to allow multiple apps on the same device to share a Core Data store integrated with iCloud
|
||||
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `ubiquitousContentName` explicitly for each of them.
|
||||
- parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration.
|
||||
- parameter cloudStorageOptions: When the `ICloudStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
|
||||
*/
|
||||
public required init?(ubiquitousContentName: String, ubiquitousContentTransactionLogsSubdirectory: String, ubiquitousContainerID: String? = nil, ubiquitousPeerToken: String? = nil, configuration: ModelConfiguration = nil, cloudStorageOptions: CloudStorageOptions = nil) {
|
||||
@@ -271,9 +270,9 @@ public final class ICloudStore: CloudStorage {
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func didAddToDataStack(_ dataStack: DataStack) {
|
||||
public func cs_didAddToDataStack(_ dataStack: DataStack) {
|
||||
|
||||
self.didRemoveFromDataStack(dataStack)
|
||||
self.cs_didRemoveFromDataStack(dataStack)
|
||||
|
||||
self.dataStack = dataStack
|
||||
let coordinator = dataStack.coordinator
|
||||
@@ -367,7 +366,7 @@ public final class ICloudStore: CloudStorage {
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func didRemoveFromDataStack(_ dataStack: DataStack) {
|
||||
public func cs_didRemoveFromDataStack(_ dataStack: DataStack) {
|
||||
|
||||
let coordinator = dataStack.coordinator
|
||||
let nilValue: AnyObject? = nil
|
||||
@@ -424,9 +423,7 @@ public final class ICloudStore: CloudStorage {
|
||||
/**
|
||||
Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
|
||||
*/
|
||||
public func eraseStorageAndWait(soureModel: NSManagedObjectModel) throws {
|
||||
|
||||
// TODO: check if attached to persistent store
|
||||
public func cs_eraseStorageAndWait(soureModel: NSManagedObjectModel) throws {
|
||||
|
||||
let cacheFileURL = self.cacheFileURL
|
||||
try autoreleasepool {
|
||||
|
||||
@@ -31,7 +31,7 @@ import CoreGraphics
|
||||
// MARK: - ImportableAttributeType
|
||||
|
||||
/**
|
||||
Types supported by CoreStore as `NSManagedObject` attribute types.
|
||||
Types supported by CoreStore as `NSManagedObject` and `CoreStoreObject` property types.
|
||||
Supported default types:
|
||||
- Bool
|
||||
- CGFloat
|
||||
@@ -54,550 +54,124 @@ import CoreGraphics
|
||||
- String
|
||||
- URL
|
||||
- UUID
|
||||
|
||||
In addition, `RawRepresentable` types whose `RawValue` already implements `ImportableAttributeType` only need to declare conformance to `ImportableAttributeType`.
|
||||
*/
|
||||
public protocol ImportableAttributeType: QueryableAttributeType {
|
||||
|
||||
associatedtype ImportableNativeType: QueryableNativeType
|
||||
|
||||
@inline(__always)
|
||||
static func cs_emptyValue() -> Self
|
||||
|
||||
@inline(__always)
|
||||
static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self?
|
||||
|
||||
@inline(__always)
|
||||
func cs_toImportableNativeType() -> ImportableNativeType
|
||||
}
|
||||
public protocol ImportableAttributeType: QueryableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Bool
|
||||
|
||||
extension Bool: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
|
||||
extension Bool: ImportableAttributeType {}
|
||||
|
||||
// MARK: - CGFloat
|
||||
|
||||
extension CGFloat: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSNumber
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_emptyValue() -> CGFloat {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> CGFloat? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension CGFloat: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Data
|
||||
|
||||
extension Data: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Data: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Date
|
||||
|
||||
extension Date: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Date: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Double
|
||||
|
||||
extension Double: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Double: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Float
|
||||
|
||||
extension Float: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Float: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Int
|
||||
|
||||
extension Int: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSNumber
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_emptyValue() -> Int {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Int: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Int8
|
||||
|
||||
extension Int8: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSNumber
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_emptyValue() -> Int8 {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int8? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Int8: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Int16
|
||||
|
||||
extension Int16: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Int16: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Int32
|
||||
|
||||
extension Int32: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Int32: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - Int64
|
||||
|
||||
extension Int64: ImportableAttributeType {
|
||||
|
||||
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 self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension Int64: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - NSData
|
||||
|
||||
extension NSData: ImportableAttributeType {
|
||||
|
||||
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? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension NSData: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - NSDate
|
||||
|
||||
extension NSDate: ImportableAttributeType {
|
||||
|
||||
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? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension NSDate: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - NSNumber
|
||||
|
||||
extension NSNumber: ImportableAttributeType {
|
||||
|
||||
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? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension NSNumber: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - NSString
|
||||
|
||||
extension NSString: ImportableAttributeType {
|
||||
|
||||
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? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension NSString: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - NSURL
|
||||
|
||||
extension NSURL: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSString
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public class func cs_emptyValue() -> Self {
|
||||
|
||||
return self.init(string: "")!
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension NSURL: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - NSUUID
|
||||
|
||||
extension NSUUID: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSString
|
||||
|
||||
public class func cs_emptyValue() -> Self {
|
||||
|
||||
enum Static {
|
||||
|
||||
static var zero = Array<UInt8>(repeating: 0, count: 16)
|
||||
}
|
||||
return self.init(uuidBytes: &Static.zero)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension NSUUID: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - String
|
||||
|
||||
extension String: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSString
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_emptyValue() -> String {
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> String? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension String: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - URL
|
||||
|
||||
extension URL: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSString
|
||||
|
||||
public static func cs_emptyValue() -> URL {
|
||||
|
||||
enum Static {
|
||||
|
||||
static let empty = URL(string: "")!
|
||||
}
|
||||
return Static.empty
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> URL? {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
extension URL: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - UUID
|
||||
|
||||
extension UUID: ImportableAttributeType {
|
||||
extension UUID: ImportableAttributeType {}
|
||||
|
||||
|
||||
// MARK: - RawRepresentable
|
||||
|
||||
extension RawRepresentable where RawValue: ImportableAttributeType {
|
||||
|
||||
public typealias ImportableNativeType = NSString
|
||||
|
||||
public static func cs_emptyValue() -> UUID {
|
||||
@inline(__always)
|
||||
public static func cs_fromQueryableNativeType(_ value: QueryableNativeType) -> Self? {
|
||||
|
||||
enum Static {
|
||||
|
||||
static let empty: UUID = cs_lazy {
|
||||
|
||||
var zero = Array<UInt8>(repeating: 0, count: 16)
|
||||
return NSUUID(uuidBytes: &zero) as UUID
|
||||
}
|
||||
}
|
||||
return Static.empty
|
||||
return RawValue.cs_fromQueryableNativeType(value).flatMap({ self.init(rawValue: $0) })
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> UUID? {
|
||||
public func cs_toQueryableNativeType() -> QueryableNativeType {
|
||||
|
||||
return self.cs_fromQueryableNativeType(value)
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
public func cs_toImportableNativeType() -> ImportableNativeType {
|
||||
|
||||
return self.cs_toQueryableNativeType()
|
||||
return self.rawValue.cs_toQueryableNativeType()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,28 +30,32 @@ import CoreData
|
||||
// MARK: - ImportableObject
|
||||
|
||||
/**
|
||||
`NSManagedObject` subclasses that conform to the `ImportableObject` protocol can be imported from a specified `ImportSource`. This allows transactions to create and insert instances this way:
|
||||
`NSManagedObject` and `CoreStoreObject` subclasses that conform to the `ImportableObject` protocol can be imported from a specified `ImportSource`. This allows transactions to create and insert instances this way:
|
||||
```
|
||||
class MyPersonEntity: NSManagedObject, ImportableObject {
|
||||
class Person: NSManagedObject, ImportableObject {
|
||||
typealias ImportSource = NSDictionary
|
||||
// ...
|
||||
}
|
||||
|
||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
||||
let json: NSDictionary = // ...
|
||||
let person = try! transaction.importObject(
|
||||
Into<MyPersonEntity>(),
|
||||
source: json
|
||||
)
|
||||
// ...
|
||||
transaction.commit()
|
||||
}
|
||||
CoreStore.perform(
|
||||
asynchronous: { (transaction) -> Void in
|
||||
let json: NSDictionary = // ...
|
||||
let person = try transaction.importObject(
|
||||
Into<Person>(),
|
||||
source: json
|
||||
)
|
||||
// ...
|
||||
},
|
||||
completion: { (result) in
|
||||
// ...
|
||||
}
|
||||
)
|
||||
```
|
||||
*/
|
||||
public protocol ImportableObject: class {
|
||||
public protocol ImportableObject: DynamicObject {
|
||||
|
||||
/**
|
||||
The data type for the import source. This is most commonly an `NSDictionary` or another external source such as an `NSUserDefaults`.
|
||||
The data type for the import source. This is most commonly an json type, `NSDictionary`, or another external source such as `NSUserDefaults`.
|
||||
*/
|
||||
associatedtype ImportSource
|
||||
|
||||
|
||||
@@ -32,30 +32,29 @@ import CoreData
|
||||
/**
|
||||
`NSManagedObject` subclasses that conform to the `ImportableUniqueObject` protocol can be imported from a specified `ImportSource`. This allows transactions to either update existing objects or create new instances this way:
|
||||
```
|
||||
class MyPersonEntity: NSManagedObject, ImportableUniqueObject {
|
||||
class Person: NSManagedObject, ImportableObject {
|
||||
typealias ImportSource = NSDictionary
|
||||
typealias UniqueIDType = NSString
|
||||
// ...
|
||||
}
|
||||
|
||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
||||
let json: NSDictionary = // ...
|
||||
let person = try! transaction.importUniqueObject(
|
||||
Into<MyPersonEntity>(),
|
||||
source: json
|
||||
)
|
||||
// ...
|
||||
transaction.commit()
|
||||
}
|
||||
CoreStore.perform(
|
||||
asynchronous: { (transaction) -> Void in
|
||||
let json: NSDictionary = // ...
|
||||
let person = try transaction.importUniqueObject(
|
||||
Into<Person>(),
|
||||
source: json
|
||||
)
|
||||
// ...
|
||||
},
|
||||
completion: { (result) in
|
||||
// ...
|
||||
}
|
||||
)
|
||||
```
|
||||
*/
|
||||
public protocol ImportableUniqueObject: ImportableObject {
|
||||
|
||||
/**
|
||||
The data type for the import source. This is most commonly an `NSDictionary` or another external source such as an `NSUserDefaults`.
|
||||
*/
|
||||
associatedtype ImportSource
|
||||
|
||||
/**
|
||||
The data type for the entity's unique ID attribute
|
||||
*/
|
||||
@@ -119,6 +118,29 @@ public protocol ImportableUniqueObject: ImportableObject {
|
||||
|
||||
// MARK: - ImportableUniqueObject (Default Implementations)
|
||||
|
||||
public extension ImportableUniqueObject where UniqueIDType.QueryableNativeType: CoreDataNativeType {
|
||||
|
||||
var uniqueIDValue: UniqueIDType {
|
||||
|
||||
get {
|
||||
|
||||
return self.cs_toRaw().getValue(
|
||||
forKvcKey: type(of: self).uniqueIDKeyPath,
|
||||
didGetValue: { UniqueIDType.cs_fromQueryableNativeType($0 as! UniqueIDType.QueryableNativeType)! }
|
||||
)
|
||||
}
|
||||
set {
|
||||
|
||||
self.cs_toRaw()
|
||||
.setValue(
|
||||
newValue,
|
||||
forKvcKey: type(of: self).uniqueIDKeyPath,
|
||||
willSetValue: { ($0.cs_toQueryableNativeType() as CoreDataNativeType) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension ImportableUniqueObject {
|
||||
|
||||
static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool {
|
||||
@@ -139,59 +161,33 @@ public extension ImportableUniqueObject {
|
||||
|
||||
// MARK: Obsolete
|
||||
|
||||
@available(*, obsoleted: 3.0.0, renamed: "shouldInsert(from:in:)")
|
||||
@available(*, obsoleted: 3.1, renamed: "shouldInsert(from:in:)")
|
||||
static func shouldInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
|
||||
|
||||
return Self.shouldInsert(from: source, in: transaction)
|
||||
}
|
||||
|
||||
@available(*, obsoleted: 3.0.0, renamed: "shouldUpdate(from:in:)")
|
||||
@available(*, obsoleted: 3.1, renamed: "shouldUpdate(from:in:)")
|
||||
static func shouldUpdateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
|
||||
|
||||
return Self.shouldUpdate(from: source, in: transaction)
|
||||
}
|
||||
|
||||
@available(*, obsoleted: 3.0.0, renamed: "uniqueID(from:in:)")
|
||||
@available(*, obsoleted: 3.1, renamed: "uniqueID(from:in:)")
|
||||
static func uniqueIDFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -> UniqueIDType? {
|
||||
|
||||
return try Self.uniqueID(from: source, in: transaction)
|
||||
}
|
||||
|
||||
@available(*, obsoleted: 3.0.0, renamed: "didInsert(from:in:)")
|
||||
@available(*, obsoleted: 3.1, renamed: "didInsert(from:in:)")
|
||||
func didInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
|
||||
|
||||
try self.didInsert(from: source, in: transaction)
|
||||
}
|
||||
|
||||
@available(*, obsoleted: 3.0.0, renamed: "update(from:in:)")
|
||||
@available(*, obsoleted: 3.1, renamed: "update(from:in:)")
|
||||
func updateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
|
||||
|
||||
try self.update(from: source, in: transaction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ImportableUniqueObject (Default Implementations)
|
||||
|
||||
public extension ImportableUniqueObject where Self: DynamicObject {
|
||||
|
||||
var uniqueIDValue: UniqueIDType {
|
||||
|
||||
get {
|
||||
|
||||
return self.cs_toRaw().getValue(
|
||||
forKvcKey: type(of: self).uniqueIDKeyPath,
|
||||
didGetValue: { UniqueIDType.cs_fromImportableNativeType($0 as! UniqueIDType.ImportableNativeType)! }
|
||||
)
|
||||
}
|
||||
set {
|
||||
|
||||
self.cs_toRaw()
|
||||
.setValue(
|
||||
newValue,
|
||||
forKvcKey: type(of: self).uniqueIDKeyPath,
|
||||
willSetValue: { ($0.cs_toImportableNativeType() as! CoreDataNativeType) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import CoreData
|
||||
// MARK: - InMemoryStore
|
||||
|
||||
/**
|
||||
A storage interface that is backed only by memory.
|
||||
A storage interface that is backed only in memory.
|
||||
*/
|
||||
public final class InMemoryStore: StorageInterface {
|
||||
|
||||
@@ -71,7 +71,7 @@ public final class InMemoryStore: StorageInterface {
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func didAddToDataStack(_ dataStack: DataStack) {
|
||||
public func cs_didAddToDataStack(_ dataStack: DataStack) {
|
||||
|
||||
self.dataStack = dataStack
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public final class InMemoryStore: StorageInterface {
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func didRemoveFromDataStack(_ dataStack: DataStack) {
|
||||
public func cs_didRemoveFromDataStack(_ dataStack: DataStack) {
|
||||
|
||||
self.dataStack = nil
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ import Foundation
|
||||
|
||||
// MARK: - InferredSchemaMappingProvider
|
||||
|
||||
final class InferredSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
/**
|
||||
A `SchemaMappingProvider` that tries to infer model migration between two `DynamicSchema` versions by searching all `xcmappingmodel`s from `Bundle.allBundles` or by relying on lightweight migration if possible. Throws an error if lightweight migration is impossible for the two `DynamicSchema`. This mapping is automatically used as a fallback mapping provider, even if no mapping providers are explicitly declared in the `StorageInterface`.
|
||||
*/
|
||||
public final class InferredSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
@@ -49,7 +52,7 @@ final class InferredSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
// MARK: SchemaMappingProvider
|
||||
|
||||
public func createMappingModel(from sourceSchema: DynamicSchema, to destinationSchema: DynamicSchema, storage: LocalStorage) throws -> (mappingModel: NSMappingModel, migrationType: MigrationType) {
|
||||
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()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>4.0.0</string>
|
||||
<string>4.2.4</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -103,7 +103,7 @@ public struct Into<T: DynamicObject>: Hashable {
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
public static func == <U: DynamicObject, V: DynamicObject>(lhs: Into<U>, rhs: Into<V>) -> Bool {
|
||||
public static func == <U, V>(lhs: Into<U>, rhs: Into<V>) -> Bool {
|
||||
|
||||
return lhs.entityClass == rhs.entityClass
|
||||
&& lhs.configuration == rhs.configuration
|
||||
|
||||
@@ -31,47 +31,23 @@ import CoreData
|
||||
|
||||
/**
|
||||
A storage interface backed by an SQLite database that was created before CoreStore 2.0.0.
|
||||
|
||||
- Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was depending on CoreStore's default directories prior to 2.0.0, make sure to use `LegacySQLiteStore` instead of `SQLiteStore`.
|
||||
*/
|
||||
@available(*, obsoleted: 3.1, message: "`LegacySQLiteStore` previous users should now use `SQLiteStore`'s new SQLiteStore.legacy(fileName:configuration:migrationMappingProviders:localStorageOptions:) or SQLiteStore.legacy() methods to create an `SQLiteStore` with legacy paths.")
|
||||
public final class LegacySQLiteStore: LocalStorage {
|
||||
|
||||
/**
|
||||
Initializes an SQLite store interface from the given SQLite file URL. When this instance is passed to the `DataStack`'s `addStorage()` methods, a new SQLite file will be created if it does not exist.
|
||||
|
||||
- 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 mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration.
|
||||
- parameter localStorageOptions: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
|
||||
*/
|
||||
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.init(fileURL:configuration:migrationMappingProviders:localStorageOptions:) initializer")
|
||||
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.init(fileURL:configuration:migrationMappingProviders:localStorageOptions:) initializer.")
|
||||
public init(fileURL: URL, configuration: ModelConfiguration = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
|
||||
|
||||
fatalError()
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes an SQLite store interface from the given SQLite file name. When this instance is passed to the `DataStack`'s `addStorage()` methods, a new SQLite file will be created if it does not exist.
|
||||
|
||||
- Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was depending on CoreStore's default directories prior to 2.0.0, make sure to use `LegacySQLiteStore` instead of `SQLiteStore`.
|
||||
- parameter fileName: the local filename for the SQLite persistent store in the "Application Support" directory (or the "Caches" 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 mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration.
|
||||
- parameter localStorageOptions: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
|
||||
*/
|
||||
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy(fileName:configuration:migrationMappingProviders:localStorageOptions:) method.")
|
||||
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy(fileName:configuration:migrationMappingProviders:localStorageOptions:) factory method.")
|
||||
public init(fileName: String, configuration: ModelConfiguration = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
|
||||
|
||||
fatalError()
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes an `LegacySQLiteStore` with an all-default settings: a `fileURL` pointing to a "<Application name>.sqlite" file in the "Application Support" directory (or the "Caches" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `mappingModelBundles` set to search all `NSBundle`s, and `localStorageOptions` set to `.AllowProgresiveMigration`.
|
||||
|
||||
- Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was depending on CoreStore's default directories prior to 2.0.0, make sure to use `LegacySQLiteStore` instead of `SQLiteStore`.
|
||||
*/
|
||||
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy() method.")
|
||||
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy(...) factory method.")
|
||||
public init() {
|
||||
|
||||
fatalError()
|
||||
@@ -80,143 +56,44 @@ public final class LegacySQLiteStore: LocalStorage {
|
||||
|
||||
// MARK: StorageInterface
|
||||
|
||||
/**
|
||||
The string identifier for the `NSPersistentStore`'s `type` property. For `SQLiteStore`s, this is always set to `NSSQLiteStoreType`.
|
||||
*/
|
||||
public static let storeType = NSSQLiteStoreType
|
||||
|
||||
/**
|
||||
The options dictionary for the specified `LocalStorageOptions`
|
||||
*/
|
||||
public func dictionary(forOptions options: LocalStorageOptions) -> [AnyHashable: Any]? {
|
||||
|
||||
if options == .none {
|
||||
|
||||
return self.storeOptions
|
||||
}
|
||||
|
||||
var storeOptions = self.storeOptions ?? [:]
|
||||
if options.contains(.allowSynchronousLightweightMigration) {
|
||||
|
||||
storeOptions[NSMigratePersistentStoresAutomaticallyOption] = true
|
||||
storeOptions[NSInferMappingModelAutomaticallyOption] = true
|
||||
}
|
||||
return storeOptions
|
||||
fatalError()
|
||||
}
|
||||
|
||||
/**
|
||||
The configuration name in the model file
|
||||
*/
|
||||
public let configuration: ModelConfiguration
|
||||
|
||||
/**
|
||||
The options dictionary for the `NSPersistentStore`. For `SQLiteStore`s, this is always set to
|
||||
```
|
||||
[NSSQLitePragmasOption: ["journal_mode": "WAL"]]
|
||||
```
|
||||
*/
|
||||
public let storeOptions: [AnyHashable: Any]? = [NSSQLitePragmasOption: ["journal_mode": "WAL"]]
|
||||
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func didAddToDataStack(_ dataStack: DataStack) {
|
||||
public func cs_didAddToDataStack(_ dataStack: DataStack) {
|
||||
|
||||
self.dataStack = dataStack
|
||||
fatalError()
|
||||
}
|
||||
|
||||
/**
|
||||
Do not call directly. Used by the `DataStack` internally.
|
||||
*/
|
||||
public func didRemoveFromDataStack(_ dataStack: DataStack) {
|
||||
public func cs_didRemoveFromDataStack(_ dataStack: DataStack) {
|
||||
|
||||
self.dataStack = nil
|
||||
fatalError()
|
||||
}
|
||||
|
||||
|
||||
// MAKR: LocalStorage
|
||||
|
||||
/**
|
||||
The `NSURL` that points to the SQLite file
|
||||
*/
|
||||
public let fileURL: URL
|
||||
|
||||
/**
|
||||
An array of `SchemaMappingProviders` that provides the complete mapping models for custom migrations.
|
||||
*/
|
||||
public let migrationMappingProviders: [SchemaMappingProvider]
|
||||
|
||||
/**
|
||||
Options that tell the `DataStack` how to setup the persistent store
|
||||
*/
|
||||
public var localStorageOptions: LocalStorageOptions
|
||||
|
||||
/**
|
||||
Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
|
||||
*/
|
||||
public func eraseStorageAndWait(metadata: [String: Any], soureModelHint: NSManagedObjectModel?) throws {
|
||||
public func cs_finalizeStorageAndWait(soureModelHint: NSManagedObjectModel) throws {
|
||||
|
||||
// TODO: check if attached to persistent store
|
||||
fatalError()
|
||||
}
|
||||
|
||||
public func cs_eraseStorageAndWait(metadata: [String: Any], soureModelHint: NSManagedObjectModel?) throws {
|
||||
|
||||
func deleteFiles(storeURL: URL, extraFiles: [String] = []) throws {
|
||||
|
||||
let fileManager = FileManager.default
|
||||
let extraFiles: [String] = [
|
||||
storeURL.path.appending("-wal"),
|
||||
storeURL.path.appending("-shm")
|
||||
]
|
||||
do {
|
||||
|
||||
let trashURL = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first!)
|
||||
.appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack", isDirectory: true)
|
||||
.appendingPathComponent("trash", isDirectory: true)
|
||||
try fileManager.createDirectory(
|
||||
at: trashURL,
|
||||
withIntermediateDirectories: true,
|
||||
attributes: nil
|
||||
)
|
||||
|
||||
let temporaryFileURL = trashURL.appendingPathComponent(UUID().uuidString, isDirectory: false)
|
||||
try fileManager.moveItem(at: storeURL, to: temporaryFileURL)
|
||||
|
||||
let extraTemporaryFiles = extraFiles.map { (extraFile) -> String in
|
||||
|
||||
let temporaryFile = trashURL.appendingPathComponent(UUID().uuidString, isDirectory: false).path
|
||||
if let _ = try? fileManager.moveItem(atPath: extraFile, toPath: temporaryFile) {
|
||||
|
||||
return temporaryFile
|
||||
}
|
||||
return extraFile
|
||||
}
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
|
||||
_ = try? fileManager.removeItem(at: temporaryFileURL)
|
||||
extraTemporaryFiles.forEach({ _ = try? fileManager.removeItem(atPath: $0) })
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
||||
try fileManager.removeItem(at: storeURL)
|
||||
extraFiles.forEach({ _ = try? fileManager.removeItem(atPath: $0) })
|
||||
}
|
||||
}
|
||||
|
||||
let fileURL = self.fileURL
|
||||
try autoreleasepool {
|
||||
|
||||
if let soureModel = soureModelHint ?? NSManagedObjectModel.mergedModel(from: nil, forStoreMetadata: metadata) {
|
||||
|
||||
let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel)
|
||||
let store = try journalUpdatingCoordinator.addPersistentStore(
|
||||
ofType: type(of: self).storeType,
|
||||
configurationName: self.configuration,
|
||||
at: fileURL,
|
||||
options: [NSSQLitePragmasOption: ["journal_mode": "DELETE"]]
|
||||
)
|
||||
try journalUpdatingCoordinator.remove(store)
|
||||
}
|
||||
try deleteFiles(storeURL: fileURL)
|
||||
}
|
||||
fatalError()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@ import CoreData
|
||||
// MARK: - ListMonitor
|
||||
|
||||
/**
|
||||
The `ListMonitor` monitors changes to a list of `NSManagedObject` instances. Observers that implement the `ListObserver` protocol may then register themselves to the `ListMonitor`'s `addObserver(_:)` method:
|
||||
The `ListMonitor` monitors changes to a list of `DynamicObject` instances. Observers that implement the `ListObserver` protocol may then register themselves to the `ListMonitor`'s `addObserver(_:)` method:
|
||||
```
|
||||
let monitor = CoreStore.monitorList(
|
||||
From<MyPersonEntity>(),
|
||||
From<Person>(),
|
||||
Where("title", isEqualTo: "Engineer"),
|
||||
OrderBy(.ascending("lastName"))
|
||||
)
|
||||
@@ -51,16 +51,16 @@ import CoreData
|
||||
Creating a sectioned-list is also possible with the `monitorSectionedList(...)` method:
|
||||
```
|
||||
let monitor = CoreStore.monitorSectionedList(
|
||||
From<MyPersonEntity>(),
|
||||
From<Person>(),
|
||||
SectionBy("age") { "Age \($0)" },
|
||||
Where("title", isEqualTo: "Engineer"),
|
||||
OrderBy(.ascending("lastName"))
|
||||
)
|
||||
monitor.addObserver(self)
|
||||
```
|
||||
Objects from `ListMonitor`s created this way can be accessed either by an `NSIndexPath` or a tuple:
|
||||
Objects from `ListMonitor`s created this way can be accessed either by an `IndexPath` or a tuple:
|
||||
```
|
||||
let indexPath = NSIndexPath(forItem: 3, inSection: 2)
|
||||
let indexPath = IndexPath(forItem: 3, inSection: 2)
|
||||
let person1 = monitor[indexPath]
|
||||
let person2 = monitor[2, 3]
|
||||
```
|
||||
@@ -80,7 +80,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
Returns the object at the given index within the first section. This subscript indexer is typically used for `ListMonitor`s created with `monitorList(_:)`.
|
||||
|
||||
- parameter index: the index of the object. Using an index above the valid range will raise an exception.
|
||||
- returns: the `NSManagedObject` at the specified index
|
||||
- returns: the `DynamicObject` at the specified index
|
||||
*/
|
||||
public subscript(index: Int) -> ObjectType {
|
||||
|
||||
@@ -99,7 +99,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
Returns the object at the given index, or `nil` if out of bounds. This subscript indexer is typically used for `ListMonitor`s created with `monitorList(_:)`.
|
||||
|
||||
- parameter index: the index for the object. Using an index above the valid range will return `nil`.
|
||||
- returns: the `NSManagedObject` at the specified index, or `nil` if out of bounds
|
||||
- returns: the `DynamicObject` at the specified index, or `nil` if out of bounds
|
||||
*/
|
||||
public subscript(safeIndex index: Int) -> ObjectType? {
|
||||
|
||||
@@ -120,11 +120,11 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
|
||||
- parameter sectionIndex: the section index for the object. Using a `sectionIndex` with an invalid range will raise an exception.
|
||||
- parameter itemIndex: the index for the object within the section. Using an `itemIndex` with an invalid range will raise an exception.
|
||||
- returns: the `NSManagedObject` at the specified section and item index
|
||||
- returns: the `DynamicObject` at the specified section and item index
|
||||
*/
|
||||
public subscript(sectionIndex: Int, itemIndex: Int) -> ObjectType {
|
||||
|
||||
return self[NSIndexPath(indexes: [sectionIndex, itemIndex], length: 2) as IndexPath]
|
||||
return self[IndexPath(indexes: [sectionIndex, itemIndex])]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,7 +132,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
|
||||
- parameter sectionIndex: the section index for the object. Using a `sectionIndex` with an invalid range will return `nil`.
|
||||
- parameter itemIndex: the index for the object within the section. Using an `itemIndex` with an invalid range will return `nil`.
|
||||
- returns: the `NSManagedObject` at the specified section and item index, or `nil` if out of bounds
|
||||
- returns: the `DynamicObject` at the specified section and item index, or `nil` if out of bounds
|
||||
*/
|
||||
public subscript(safeSectionIndex sectionIndex: Int, safeItemIndex itemIndex: Int) -> ObjectType? {
|
||||
|
||||
@@ -148,10 +148,10 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object at the given `NSIndexPath`. This subscript indexer is typically used for `ListMonitor`s created with `monitorSectionedList(_:)`.
|
||||
Returns the object at the given `IndexPath`. This subscript indexer is typically used for `ListMonitor`s created with `monitorSectionedList(_:)`.
|
||||
|
||||
- parameter indexPath: the `NSIndexPath` for the object. Using an `indexPath` with an invalid range will raise an exception.
|
||||
- returns: the `NSManagedObject` at the specified index path
|
||||
- parameter indexPath: the `IndexPath` for the object. Using an `indexPath` with an invalid range will raise an exception.
|
||||
- returns: the `DynamicObject` at the specified index path
|
||||
*/
|
||||
public subscript(indexPath: IndexPath) -> ObjectType {
|
||||
|
||||
@@ -163,10 +163,10 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object at the given `NSIndexPath`, or `nil` if out of bounds. This subscript indexer is typically used for `ListMonitor`s created with `monitorSectionedList(_:)`.
|
||||
Returns the object at the given `IndexPath`, or `nil` if out of bounds. This subscript indexer is typically used for `ListMonitor`s created with `monitorSectionedList(_:)`.
|
||||
|
||||
- parameter indexPath: the `NSIndexPath` for the object. Using an `indexPath` with an invalid range will return `nil`.
|
||||
- returns: the `NSManagedObject` at the specified index path, or `nil` if out of bounds
|
||||
- parameter indexPath: the `IndexPath` for the object. Using an `indexPath` with an invalid range will return `nil`.
|
||||
- returns: the `DynamicObject` at the specified index path, or `nil` if out of bounds
|
||||
*/
|
||||
public subscript(safeIndexPath indexPath: IndexPath) -> ObjectType? {
|
||||
|
||||
@@ -340,10 +340,10 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the index of the `NSManagedObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
Returns the index of the `DynamicObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
|
||||
- parameter object: the `NSManagedObject` to search the index of
|
||||
- returns: the index of the `NSManagedObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
- parameter object: the `DynamicObject` to search the index of
|
||||
- returns: the index of the `DynamicObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
*/
|
||||
public func indexOf(_ object: ObjectType) -> Int? {
|
||||
|
||||
@@ -359,10 +359,10 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the `NSIndexPath` of the `NSManagedObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
Returns the `IndexPath` of the `DynamicObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
|
||||
- parameter object: the `NSManagedObject` to search the index of
|
||||
- returns: the `NSIndexPath` of the `NSManagedObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
- parameter object: the `DynamicObject` to search the index of
|
||||
- returns: the `IndexPath` of the `DynamicObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
*/
|
||||
public func indexPathOf(_ object: ObjectType) -> IndexPath? {
|
||||
|
||||
@@ -590,7 +590,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
```
|
||||
- Important: Do not use this method to store thread-sensitive data.
|
||||
*/
|
||||
private let userInfo = UserInfo()
|
||||
public let userInfo = UserInfo()
|
||||
|
||||
|
||||
// MARK: Equatable
|
||||
@@ -600,7 +600,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
return lhs.fetchedResultsController === rhs.fetchedResultsController
|
||||
}
|
||||
|
||||
public static func == <T: DynamicObject, U: DynamicObject>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
|
||||
public static func == <T, U>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
|
||||
|
||||
return lhs.fetchedResultsController === rhs.fetchedResultsController
|
||||
}
|
||||
@@ -610,7 +610,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
return lhs.fetchedResultsController === rhs.fetchedResultsController
|
||||
}
|
||||
|
||||
public static func ~= <T: DynamicObject, U: DynamicObject>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
|
||||
public static func ~= <T, U>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
|
||||
|
||||
return lhs.fetchedResultsController === rhs.fetchedResultsController
|
||||
}
|
||||
@@ -704,13 +704,13 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
|
||||
guard let `self` = self,
|
||||
let userInfo = note.userInfo,
|
||||
let object = userInfo[String(describing: NSManagedObject.self)] as? ObjectType else {
|
||||
let rawObject = userInfo[String(describing: NSManagedObject.self)] as? NSManagedObject else {
|
||||
|
||||
return
|
||||
}
|
||||
callback(
|
||||
self,
|
||||
object,
|
||||
ObjectType.cs_fromRaw(object: rawObject),
|
||||
userInfo[String(describing: IndexPath.self)] as? IndexPath,
|
||||
userInfo["\(String(describing: IndexPath.self)).New"] as? IndexPath
|
||||
)
|
||||
@@ -997,7 +997,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
|
||||
fileprivate var fetchedResultsController: CoreStoreFetchedResultsController
|
||||
fileprivate let taskGroup = DispatchGroup()
|
||||
fileprivate let sectionIndexTransformer: (_ sectionName: KeyPath?) -> String?
|
||||
fileprivate let sectionIndexTransformer: (_ sectionName: RawKeyPath?) -> String?
|
||||
|
||||
private let isSectioned: Bool
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user