Compare commits

...

60 Commits
5.3.1 ... 6.2.1

Author SHA1 Message Date
John Estropia
0376ac6908 bump 2019-02-28 18:57:28 +09:00
John Estropia
b3421888a6 version bump 2019-02-28 18:55:32 +09:00
John Estropia
7b3f4ae0a4 fix compile error 2019-02-28 17:58:17 +09:00
John Estropia
b4e12cc922 restore NSPersistentStore.affectedStores ARC bug workaround 2019-02-28 17:57:34 +09:00
John Estropia
6c282b18af version bump 2019-02-28 13:14:27 +09:00
John Estropia
ebbde8b7b6 minor fix in demo app 2019-02-28 13:13:01 +09:00
John Estropia
a1407e4121 Revert workaround for iOS 10 NSFetchedResultsController (#100) 2019-02-28 13:07:47 +09:00
John Estropia
99b871b97a add missing documentations for Where.Expression, updated playgrounds 2019-02-20 18:47:29 +09:00
John Estropia
1cd3c4fcf4 fix compile error 2019-02-12 18:18:44 +09:00
John Estropia
e09ac9ee00 add macOS playground 2019-02-12 18:05:06 +09:00
John Estropia
4b0d134acb remove swift 5 annotation 2019-02-12 18:03:59 +09:00
John Estropia
eeec3979ee SwiftPM support 2019-02-12 15:48:50 +09:00
John Estropia
5b365c642d add tests for expressio evaluations 2019-02-08 18:42:19 +09:00
John Estropia
635201868a add comparison operators for Where.Expression 2019-02-08 17:16:56 +09:00
John Estropia
db4426e6b9 Swift 5 support. WIP: Support type-safe predicate expressions 2019-02-01 18:32:22 +09:00
John Estropia
41902fee2e fix compiler errors 2019-01-31 16:50:43 +09:00
John Estropia
9239370793 Added reference comment explaining crashes on A12 devices #291 2019-01-29 14:15:01 +09:00
John Estropia
a4d2f326a5 Improve perfomance by bypassing bridging (similar to https://github.com/JohnEstropia/CoreStore/pull/288) 2019-01-28 20:12:18 +09:00
John Estropia
9f54ec26e2 add Where initializer that can accept another Where clause 2019-01-28 20:10:15 +09:00
John Estropia
9425cb56d7 update documentation for -[CSListMonitor refetch:] to reflect actual behavior 2019-01-28 19:04:46 +09:00
John Estropia
1de56d2776 add missing From.orderBy(_:) overloads 2019-01-25 17:30:11 +09:00
John Estropia
b3261ea930 Update README.md 2019-01-24 16:12:12 +09:00
John Estropia
88dd7aef72 updated README 2019-01-24 15:32:54 +09:00
John Estropia
2863605d84 silence deprecation internal warnings 2019-01-23 12:25:52 +09:00
John Estropia
94d9116299 pod bump 2019-01-23 10:56:10 +09:00
John Estropia
57ddbbd515 make some test cases validate specific error codes from thrown errors 2019-01-23 10:55:58 +09:00
John Estropia
78954b9d78 version bump 2019-01-22 16:41:58 +09:00
John Estropia
4eb06c9858 Merge branch 'throwables' into develop 2019-01-22 16:38:57 +09:00
John Estropia
0d634c1dcc add missing MARKs 2019-01-22 16:38:17 +09:00
John Estropia
84f3740ea1 fix unit test warnings 2019-01-18 17:30:54 +09:00
John Estropia
6dc48b6af7 Add docs for new throwing methods 2019-01-17 18:43:10 +09:00
John Estropia
09ce2816bf Merge branch 'develop' into throwables 2019-01-16 17:03:49 +09:00
John Estropia
62e962eebe Merge pull request #301 from ianbytchek/develop
Resolve source entity and managed object attributes by name
2019-01-16 17:01:48 +09:00
John Estropia
682472c1bd fetches, queries, and deletes are now throwable methods 2019-01-15 20:40:15 +09:00
Ian Bytchek
46ab70b839 Update TravisCI base image to Xcode 10
Replace deprecated build matrix configurations with newer alternatives.
2019-01-13 06:24:04 +00:00
Ian Bytchek
ac8304f977 Resolve source entity and managed object attributes by name
Addresses #300 – see it for details. Also improves the use of whitespace consistency across the `CustomSchemaMappingProvider.swift` and uses method names for `cs_resolve…` over `cs_resolved…` for better alignment with [Swift API Design Guidelines](https://swift.org/documentation/api-design-guidelines).
2019-01-13 05:41:34 +00:00
John Estropia
5777831565 WIP: make fetching methods throwable 2019-01-11 19:52:12 +09:00
John Estropia
42d1f41939 Provide more context when failing to search for mapping models #299 2019-01-11 19:48:35 +09:00
John Estropia
8c30ec3a3d minor fixes on Playgrounds and Demo app 2019-01-09 11:59:06 +09:00
John Estropia
237a1b648e Assert on reserved property names 2019-01-09 11:58:37 +09:00
John Estropia
614f1572c2 print PartialObjects 2018-12-26 22:35:28 +08:00
John Estropia
a48f16aa8c add Jazzy docs 2018-12-19 16:27:05 +09:00
John Estropia
cdbadae002 added comments to playground 2018-12-18 18:44:47 +09:00
John Estropia
4a28a39df6 removed long-standing workaround for NSFetchedResultsController bugs since they seem to be fixed 2018-12-18 18:43:36 +09:00
John Estropia
5febf2542d added playgrounds just to show off 2018-12-14 19:28:55 +09:00
John Estropia
c21ab11a41 format header comment 2018-12-14 18:21:41 +09:00
John Estropia
10cd18dbf0 prototype for CoreStoreObject property observers (a.k.a. KVO) 2018-12-14 18:20:42 +09:00
John Estropia
8409a13289 Merge pull request #288 from ruslanskorb/list-monitor-number-of-objects-performance
[ListMonitor] Fix performance of `numberOfObjects()`.
2018-12-06 18:53:06 +09:00
Ruslan Skorb
a9a73fa5c4 [ListMonitor] [numberOfObjects()] Return count of fetchedObjects.
Casting `fetchedObjects` to `NSArray?` has better performance.
https://github.com/JohnEstropia/CoreStore/pull/288
2018-12-06 10:56:30 +02:00
John Estropia
82cae2e11e Merge pull request #292 from eliseo-juan/patch-1
Fix documentation
2018-12-06 10:54:50 +09:00
John Estropia
42caee2418 Merge pull request #287 from ruslanskorb/list-monitor-subscript-performance
[ListMonitor] Fix performance of `subscript(safeSectionIndex:safeItemIndex:)`.
2018-12-06 10:54:12 +09:00
Eliseo Juan Quintanilla
1dea1d0d06 Fix documentation
Changed attribtue to attribute
2018-12-05 10:09:05 +01:00
John Estropia
d344b9d878 minimum deployment version bumped to iOS 10, macOS 10.12, tvOS 10, watchOS 3. Deprecated iCloud Storage 2018-12-05 17:31:16 +09:00
John Estropia
95c1ce52cc Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2018-12-05 16:17:03 +09:00
John Estropia
cc346816d6 Added new error for cases when addStorageAndWait() is used with .allowSynchronousLightweightMigration but migrations are only allowed asynchronously (related to #277) 2018-12-05 16:15:20 +09:00
John Estropia
f14b561c33 Merge pull request #275 from DmitrijMaz/fix_queueing
Fix queue validation for UnsafeDataTransaction
2018-12-05 11:02:47 +09:00
Ruslan Skorb
6f655951aa [ListMonitor] [numberOfObjects()] Calculate the number of objects in all sections by summing the number of objects stored in NSFetchedResultsSectionInfo.
There is a performance problem in Swift when calling `count` method on an array with a large number of fetched objects. It requires casting the array between Objective-C and Swift, that is pretty slow.
2018-11-24 16:24:14 +02:00
Ruslan Skorb
ff8fbae568 [ListMonitor] [subscript(safeSectionIndex:safeItemIndex:)] Use subscript(indexPath:) after the validation of sectionIndex and itemIndex to get an object.
There is a performance problem in Swift when getting an object from the Objective-C array with a large number of objects using subscript. It requires casting the array between Objective-C and Swift, that is pretty slow.
2018-11-24 16:23:36 +02:00
Dmitry Mazurenko
4d4b02d076 Fix queue validation for UnsafeDataTransaction 2018-10-10 16:48:04 +03:00
John Estropia
06c0981ded debug string for CoreStoreObject 2018-09-24 00:49:53 +09:00
505 changed files with 427260 additions and 2496 deletions

2
.gitignore vendored
View File

@@ -7,3 +7,5 @@ CoreStore.xcworkspace/xcuserdata
.DS_Store
DerivedData
*.orig
build
Playground_macOS.playground/playground.xcworkspace/xcuserdata

15
.jazzy.yaml Normal file
View File

@@ -0,0 +1,15 @@
author: John Estropia
author_url: https://github.com/JohnEstropia
github_url: https://github.com/JohnEstropia/CoreStore
module: CoreStore
readme: README.md
include: Sources/*
output: docs
theme: fullwidth
clean: true
skip_undocumented: true
xcodebuild_arguments:
- -sdk
- iphonesimulator
- -scheme
- CoreStore iOS

View File

@@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode9
osx_image: xcode10
sudo: false
git:
submodules: false
@@ -10,17 +10,17 @@ env:
- LC_CTYPE=en_US.UTF-8
- LANG=en_US.UTF-8
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="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"
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.14 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=12.0,name=iPhone XS" SCHEME="CoreStore iOS" SDK=iphonesimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=11.0.1,name=iPhone 8" SCHEME="CoreStore iOS" SDK=iphonesimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.3.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=4.0,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator5.0 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator5.0 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator5.0 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=12.0,name=Apple TV 4K" SCHEME="CoreStore tvOS" SDK=appletvsimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=11.0,name=Apple TV 4K (at 1080p)" SCHEME="CoreStore tvOS" SDK=appletvsimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator12.0 RUN_TESTS="YES" POD_LINT="NO"
before_install:
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
@@ -39,8 +39,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 "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;
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "iphonesimulator12.0" -destination "OS=11.0.1,name=iPhone 8" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "iphonesimulator12.0" -destination "OS=11.0.1,name=iPhone 8" -configuration Release ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
- if [ $POD_LINT == "YES" ]; then
pod lib lint --quick;
fi

View File

@@ -1,17 +1,18 @@
Pod::Spec.new do |s|
s.name = "CoreStore"
s.version = "5.3.1"
s.version = "6.2.1"
s.swift_version = "4.2"
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"
s.documentation_url = "https://JohnEstropia.github.io/CoreStore"
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" }
s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s }
s.ios.deployment_target = "9.0"
s.osx.deployment_target = "10.11"
s.watchos.deployment_target = "2.0"
s.tvos.deployment_target = "9.0"
s.ios.deployment_target = "10.0"
s.osx.deployment_target = "10.12"
s.watchos.deployment_target = "3.0"
s.tvos.deployment_target = "10.0"
s.source_files = "Sources", "Sources/**/*.{swift,h,m}"
s.public_header_files = "Sources/**/*.h"

View File

@@ -165,10 +165,6 @@
B52557881D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
B52557891D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
B525578A1D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
B52661401CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B52661421CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B52661431CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B52661441CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B529C2041CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
B529C2061CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
B529C2071CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
@@ -297,6 +293,10 @@
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
B546F9761C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
B5474D152227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
B5474D162227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
B5474D172227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
B5474D182227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
B5489F3F1CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
B5489F401CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
B5489F411CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
@@ -477,6 +477,12 @@
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831F4022126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5831F4122126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5831F4222126FED00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5831F432212700400D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B5831F442212700500D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B5831F452212700500D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B58B22F51C93C1BA00521925 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F03A53019C5C6DA005002A5 /* CoreStore.framework */; };
B58D0C631EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
B58D0C641EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
@@ -578,6 +584,8 @@
B5D7A5B81CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
B5D7A5B91CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
B5DAFB482203D9F8003FCCD0 /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
@@ -659,6 +667,10 @@
B5E84F371AFF85470064E85B /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
B5E84F411AFF8CCD0064E85B /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
B5E8A72021C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */; };
B5E8A72121C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */; };
B5E8A72221C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */; };
B5E8A72321C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */; };
B5ECDBDF1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */; };
B5ECDBE11CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */; };
B5ECDBE21CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */; };
@@ -783,6 +795,7 @@
B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverTests.swift; sourceTree = "<group>"; };
B5220E0B1D0D0D19009BC71E /* ImportTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportTests.swift; sourceTree = "<group>"; };
B5220E0F1D0DA6AB009BC71E /* ListObserverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListObserverTests.swift; sourceTree = "<group>"; };
B524E78721CA20AC00BEB794 /* .jazzy.yaml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .jazzy.yaml; sourceTree = SOURCE_ROOT; };
B525576B1CFAF18F00E51965 /* IntoTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntoTests.swift; sourceTree = "<group>"; };
B525576F1D02561A00E51965 /* SelectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectTests.swift; sourceTree = "<group>"; };
B52557731D02791400E51965 /* WhereTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WhereTests.swift; sourceTree = "<group>"; };
@@ -791,7 +804,6 @@
B525577F1D029D2500E51965 /* TweakTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TweakTests.swift; sourceTree = "<group>"; };
B52557831D02A07400E51965 /* SectionByTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionByTests.swift; sourceTree = "<group>"; };
B52557871D02DE8100E51965 /* FetchTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchTests.swift; sourceTree = "<group>"; };
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreFetchRequest+CoreStore.swift"; sourceTree = "<group>"; };
B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSaveResult.swift; sourceTree = "<group>"; };
B52DD1741BE1F8CC00949AFE /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B52DD17D1BE1F8CC00949AFE /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -815,6 +827,7 @@
B546F95C1C9A12B800D5AC55 /* CSSQliteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSQliteStore.swift; sourceTree = "<group>"; };
B546F9681C9AF26D00D5AC55 /* CSInMemoryStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInMemoryStore.swift; sourceTree = "<group>"; };
B546F9721C9C553300D5AC55 /* SetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupResult.swift; sourceTree = "<group>"; };
B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchRequest.swift; sourceTree = "<group>"; };
B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity1.swift; sourceTree = "<group>"; };
B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity2.swift; sourceTree = "<group>"; };
B5489F451CF5F017008B4978 /* TransactionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionTests.swift; sourceTree = "<group>"; };
@@ -855,7 +868,7 @@
B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDynamicSchema.swift; sourceTree = "<group>"; };
B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSXcodeDataModelSchema.swift; sourceTree = "<group>"; };
B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataModelSchema.swift; sourceTree = "<group>"; };
B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = "<group>"; };
B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.swift; sourceTree = "<group>"; };
B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestDataTestCase.swift; sourceTree = "<group>"; };
B57D27C11D0BC20100539C58 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
@@ -872,6 +885,8 @@
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyPath+Querying.swift"; sourceTree = "<group>"; };
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = "<group>"; };
B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = "<group>"; };
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_macOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_iOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionLock.swift; sourceTree = "<group>"; };
B5A9921E1EA898710091A2E3 /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = "<group>"; };
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
@@ -897,6 +912,8 @@
B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacySQLiteStore.swift; sourceTree = "<group>"; };
B5D7A5B51CA3BF8F005C752B /* CSInto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInto.swift; sourceTree = "<group>"; };
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = CoreStore.podspec; sourceTree = SOURCE_ROOT; };
B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Where.Expression.swift; sourceTree = "<group>"; };
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPathGenericBindings.swift; sourceTree = "<group>"; };
B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSCoreStore.swift; sourceTree = "<group>"; };
B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDataStack.swift; sourceTree = "<group>"; };
B5DBE2DA1C9939E100B5CEFA /* CoreStoreTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreStoreTests-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -950,6 +967,7 @@
B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Transaction.swift"; sourceTree = "<group>"; };
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Querying.swift"; sourceTree = "<group>"; };
B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeErasedClauses.swift; sourceTree = "<group>"; };
B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Observing.swift"; sourceTree = "<group>"; };
B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSBaseDataTransaction+Querying.swift"; sourceTree = "<group>"; };
B5ECDBE41CA6BEA300C7F112 /* CSClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSClauseTypes.swift; sourceTree = "<group>"; };
B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSFrom.swift; sourceTree = "<group>"; };
@@ -1040,6 +1058,8 @@
2F03A52619C5C6DA005002A5 = {
isa = PBXGroup;
children = (
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */,
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */,
2F291E3119C6D4D3007AF63F /* Frameworks */,
2F03A53219C5C6DA005002A5 /* Sources */,
2F03A53C19C5C6DA005002A5 /* CoreStoreTests */,
@@ -1082,6 +1102,7 @@
B5BDC91A1C202269008147CD /* Cartfile */,
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */,
B5BDC9271C2024F2008147CD /* .travis.yml */,
B524E78721CA20AC00BEB794 /* .jazzy.yaml */,
B5AD60CD1C90141E00F2B2E8 /* Package.swift */,
);
name = "Supporting Files";
@@ -1324,6 +1345,7 @@
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */,
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */,
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */,
);
name = "KeyPath Utilities";
sourceTree = "<group>";
@@ -1471,6 +1493,7 @@
B5E84F011AFF847B0064E85B /* From.swift */,
B5E84F031AFF847B0064E85B /* Select.swift */,
B5E84F051AFF847B0064E85B /* Where.swift */,
B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */,
B5E84F041AFF847B0064E85B /* OrderBy.swift */,
B5E84F021AFF847B0064E85B /* GroupBy.swift */,
B5E84F001AFF847B0064E85B /* Tweak.swift */,
@@ -1493,6 +1516,7 @@
B56007131B3F6C2800A9A8F9 /* SectionBy.swift */,
B5E84F1A1AFF84860064E85B /* DataStack+Observing.swift */,
B5E84F1B1AFF84860064E85B /* CoreStore+Observing.swift */,
B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */,
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */,
B5E84F1C1AFF84860064E85B /* ObjectMonitor.swift */,
B5E84F1F1AFF84860064E85B /* ObjectObserver.swift */,
@@ -1520,8 +1544,8 @@
children = (
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */,
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */,
B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */,
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
B51260921E9B28F100402229 /* EntityIdentifier.swift */,
@@ -1886,6 +1910,7 @@
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */,
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
@@ -1925,11 +1950,11 @@
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B5DAFB482203D9F8003FCCD0 /* Where.Expression.swift in Sources */,
B5FE4DA21C8481E100FA6A91 /* StorageInterface.swift in Sources */,
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */,
B52661401CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B53FBA181CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
B5519A591CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
@@ -2008,6 +2033,8 @@
B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72021C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B5474D152227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
@@ -2117,9 +2144,11 @@
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
B5831F4022126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */,
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */,
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
B5831F432212700400D8604C /* Where.Expression.swift in Sources */,
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
@@ -2127,7 +2156,6 @@
82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */,
B53FBA1A1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
82BA18CA1C4BBD5900A0916E /* MigrationResult.swift in Sources */,
B52661421CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B5519A5A1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
B5ECDBE11CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
82BA18C11C4BBD5300A0916E /* CoreStore+Observing.swift in Sources */,
@@ -2204,6 +2232,8 @@
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72121C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B5474D162227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CAF1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
@@ -2313,9 +2343,11 @@
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
B5831F4222126FED00D8604C /* KeyPathGenericBindings.swift in Sources */,
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */,
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5831F452212700500D8604C /* Where.Expression.swift in Sources */,
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B5ECDBE31CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
B5ECDC031CA80CBA00C7F112 /* CSWhere.swift in Sources */,
@@ -2324,7 +2356,6 @@
B52DD1C71BE1F94600949AFE /* NSManagedObjectContext+Querying.swift in Sources */,
B52DD1C81BE1F94600949AFE /* NSManagedObjectContext+Setup.swift in Sources */,
B52DD1C31BE1F94600949AFE /* NotificationObserver.swift in Sources */,
B52661441CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B52DD1A81BE1F93200949AFE /* DataStack+Querying.swift in Sources */,
B5220E221D130818009BC71E /* CSSectionBy.swift in Sources */,
B52DD1BC1BE1F94000949AFE /* MigrationResult.swift in Sources */,
@@ -2400,6 +2431,8 @@
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72321C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B5474D182227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CB11FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
@@ -2509,14 +2542,15 @@
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
B56321981BD65216006C9394 /* Where.swift in Sources */,
B5831F4122126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */,
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */,
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
B5831F442212700500D8604C /* Where.Expression.swift in Sources */,
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */,
B52661431CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B53FBA1B1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5519A5B1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
B5ECDBE21CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
@@ -2596,6 +2630,8 @@
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72221C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B5474D172227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CB01FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
@@ -2685,8 +2721,8 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = Sources/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MACOSX_DEPLOYMENT_TARGET = 10.11;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "-D DEBUG";
@@ -2697,10 +2733,10 @@
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 9.0;
TVOS_DEPLOYMENT_TARGET = 10.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
WATCHOS_DEPLOYMENT_TARGET = 2.0;
WATCHOS_DEPLOYMENT_TARGET = 3.0;
};
name = Debug;
};
@@ -2749,8 +2785,8 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = Sources/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MACOSX_DEPLOYMENT_TARGET = 10.11;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore;
PRODUCT_NAME = CoreStore;
@@ -2759,11 +2795,11 @@
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 9.0;
TVOS_DEPLOYMENT_TARGET = 10.0;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
WATCHOS_DEPLOYMENT_TARGET = 2.0;
WATCHOS_DEPLOYMENT_TARGET = 3.0;
};
name = Release;
};
@@ -2777,13 +2813,11 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -2797,13 +2831,11 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -2824,7 +2856,6 @@
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -2840,7 +2871,6 @@
SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -2861,7 +2891,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
@@ -2883,7 +2912,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
@@ -2902,7 +2930,6 @@
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
@@ -2921,7 +2948,6 @@
SDKROOT = appletvos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
@@ -2942,12 +2968,10 @@
GCC_NO_COMMON_BLOCKS = YES;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -2968,12 +2992,10 @@
GCC_NO_COMMON_BLOCKS = YES;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -2994,7 +3016,6 @@
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -3015,7 +3036,6 @@
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -3037,7 +3057,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
};
name = Debug;
@@ -3061,7 +3080,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
};
name = Release;

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

View File

@@ -410,7 +410,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -460,7 +460,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
@@ -474,7 +474,6 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -488,7 +487,6 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -20,7 +20,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {
application.statusBarStyle = .lightContent
return true
}
}

View File

@@ -1,14 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" 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="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"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<customFonts key="customFonts">
@@ -78,14 +75,14 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8b8-lM-Krq">
<rect key="frame" x="15" y="13" width="28.5" height="19"/>
<rect key="frame" x="16" y="13" width="28.5" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="16"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hR1-Zb-BOk">
<rect key="frame" x="308" y="13" width="52" height="19"/>
<rect key="frame" x="307" y="13" width="52" height="19"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="16"/>
<color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -136,7 +133,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OQf-Bd-Zze">
<rect key="frame" x="295" y="8" width="72" height="27.5"/>
<rect key="frame" x="288" y="11" width="72" height="22"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
<inset key="contentEdgeInsets" minX="7" minY="0.0" maxX="7" maxY="0.0"/>
<state key="normal" title="mutate!"/>
@@ -145,7 +142,7 @@
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VZk-6K-4ut">
<rect key="frame" x="15" y="8" width="270" height="27.5"/>
<rect key="frame" x="22" y="11" width="256" height="22"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Thin" family="Helvetica Neue" pointSize="17"/>
<color key="textColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -275,18 +272,18 @@
<rect key="frame" x="0.0" y="35" width="375" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="AXm-KE-45G" id="9te-Wx-hkf">
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="49.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Accounts" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Q3n-Df-v1t">
<rect key="frame" x="15" y="6" width="82" height="24"/>
<rect key="frame" x="16" y="6" width="82" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Setting up multiple persistent store configurations" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Hbn-cf-Y7m">
<rect key="frame" x="15" y="30" width="263.5" height="13.5"/>
<rect key="frame" x="16" y="30" width="263.5" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -302,18 +299,18 @@
<rect key="frame" x="0.0" y="85" width="375" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fsb-zw-8Ii" id="Upm-AO-Fw3">
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="49.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Colors" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="vpt-cT-gMo">
<rect key="frame" x="15" y="6" width="56" height="24"/>
<rect key="frame" x="16" y="6" width="56" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Observing list changes and single object changes" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ou9-TZ-8bf">
<rect key="frame" x="15" y="30" width="260.5" height="13.5"/>
<rect key="frame" x="16" y="30" width="260.5" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -329,18 +326,18 @@
<rect key="frame" x="0.0" y="135" width="375" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ekW-PJ-mbo" id="CYq-mg-PVS">
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="49.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Placemarks" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="UbU-Kd-yrY">
<rect key="frame" x="15" y="6" width="100.5" height="24"/>
<rect key="frame" x="16" y="6" width="100.5" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Making changes with transactions" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="uP1-Jc-o9v">
<rect key="frame" x="15" y="30" width="179" height="13.5"/>
<rect key="frame" x="16" y="30" width="179" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -356,18 +353,18 @@
<rect key="frame" x="0.0" y="185" width="375" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="ph1-8z-C1m" id="nNz-rd-ksg">
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="49.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Time Zones" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="C8Y-0y-lEG">
<rect key="frame" x="15" y="6" width="101.5" height="24"/>
<rect key="frame" x="16" y="6" width="101.5" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Fetching objects and raw values" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="jZw-qE-0ws">
<rect key="frame" x="15" y="30" width="168.5" height="13.5"/>
<rect key="frame" x="16" y="30" width="168.5" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -383,18 +380,18 @@
<rect key="frame" x="0.0" y="235" width="375" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wyK-rk-3tI" id="fLd-KK-QcW">
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="49.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Logger" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZfY-Aq-Ykq">
<rect key="frame" x="15" y="6" width="61" height="24"/>
<rect key="frame" x="16" y="6" width="61" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Implementing a custom logger" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QzD-9b-k1j">
<rect key="frame" x="15" y="30" width="159" height="13.5"/>
<rect key="frame" x="16" y="30" width="159" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -410,18 +407,18 @@
<rect key="frame" x="0.0" y="285" width="375" height="50"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="xTM-Cf-0if" id="DfO-BW-krd">
<rect key="frame" x="0.0" y="0.0" width="342" height="49.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="49.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Evolution" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hSG-mG-YBw">
<rect key="frame" x="15" y="6" width="78.5" height="24"/>
<rect key="frame" x="16" y="6" width="78.5" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Migrating and de-migrating stores" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="X9P-TQ-LYh">
<rect key="frame" x="15" y="30" width="179.5" height="13.5"/>
<rect key="frame" x="16" y="30" width="179.5" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -460,7 +457,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
<rect key="frame" x="16" y="89.5" width="343" height="50"/>
<rect key="frame" x="16" y="69.5" width="343" height="70"/>
<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"/>
@@ -512,7 +509,7 @@
</connections>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p4O-tf-dgt">
<rect key="frame" x="16" y="69" width="343" height="20.5"/>
<rect key="frame" x="16" y="49" 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"/>
@@ -623,7 +620,7 @@
<tabBarItem key="tabBarItem" title="Demo" image="second" id="3iQ-I2-4LW"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="00L-5k-Eno">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<color key="tintColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="barTintColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -653,18 +650,18 @@
<rect key="frame" x="0.0" y="22" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="G3X-70-BCD" id="aT8-nz-i5l">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uQX-PI-UWF">
<rect key="frame" x="8" y="8" width="27" height="27"/>
<rect key="frame" x="16" y="11" width="22" height="22"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" secondItem="uQX-PI-UWF" secondAttribute="height" multiplier="1:1" id="9qA-iN-Neb"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HJC-5w-lIN">
<rect key="frame" x="45" y="8" width="34.5" height="27"/>
<rect key="frame" x="48" y="11" width="34.5" height="22"/>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="14"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -713,18 +710,18 @@
<rect key="frame" x="0.0" y="22" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="zSO-3e-OVq" id="cHA-by-n4b">
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5uq-Yi-XwH">
<rect key="frame" x="8" y="8" width="27" height="27"/>
<rect key="frame" x="16" y="11" width="22" height="22"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" secondItem="5uq-Yi-XwH" secondAttribute="height" multiplier="1:1" id="oOe-HC-VyN"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Zyu-PC-WmO">
<rect key="frame" x="45" y="8" width="34.5" height="27"/>
<rect key="frame" x="48" y="11" width="34.5" height="22"/>
<fontDescription key="fontDescription" name="HelveticaNeue" family="Helvetica Neue" pointSize="14"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@@ -767,7 +764,7 @@
<extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="6XA-6M-yvZ">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<color key="tintColor" red="0.68773996829986572" green="0.71417498588562012" blue="0.73246318101882935" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="barTintColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -794,11 +791,11 @@
<viewControllerLayoutGuide type="bottom" id="RZg-hi-T8O"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="k4s-iL-Krh">
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<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"/>
<mapView verifyAmbiguity="ignoreSizes" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="V2U-0R-Ts0">
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<connections>
<outlet property="delegate" destination="jPl-fH-NlD" id="Sjn-YC-haS"/>
</connections>
@@ -888,7 +885,7 @@
<extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="wJo-mp-1pS">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<color key="tintColor" red="0.68773996829986572" green="0.71417498588562012" blue="0.73246318101882935" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="barTintColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -1008,14 +1005,14 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="name" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="RgX-yK-1L2">
<rect key="frame" x="15" y="11" width="48.5" height="24"/>
<rect key="frame" x="16" y="11" width="48.5" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="offset" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="QZ4-A2-x4h">
<rect key="frame" x="15" y="35" width="31" height="13.5"/>
<rect key="frame" x="16" y="35" width="31" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@@ -1054,14 +1051,14 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="name" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Syt-QJ-KXg">
<rect key="frame" x="15" y="11" width="48.5" height="24"/>
<rect key="frame" x="16" y="11" width="48.5" height="24"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="20"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="offset" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="yHS-dP-IKS">
<rect key="frame" x="15" y="35" width="31" height="13.5"/>
<rect key="frame" x="16" y="35" width="31" height="13.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.13079629838466644" green="0.184075728058815" blue="0.24594299495220184" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>

View File

@@ -25,7 +25,7 @@ private struct Static {
_ = try? dataStack.perform(
synchronous: { (transaction) in
transaction.deleteAll(From<TimeZone>())
try transaction.deleteAll(From<TimeZone>())
for name in NSTimeZone.knownTimeZoneNames {
@@ -164,17 +164,17 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
title: "All Time Zones",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.orderBy(.ascending(\.name))
)!
)
}
),
(
title: "Time Zones in Asia",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
@@ -182,14 +182,14 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
"Asia"
)
.orderBy(.ascending(\.secondsFromGMT))
)!
)
}
),
(
title: "Time Zones in America and Europe",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@ OR %K BEGINSWITH[c] %@",
@@ -199,14 +199,14 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
"Europe"
)
.orderBy(.ascending(\.secondsFromGMT))
)!
)
}
),
(
title: "All Time Zones Except America",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
@@ -214,18 +214,18 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
"America"
)
.orderBy(.ascending(\.secondsFromGMT))
)!
)
}
),
(
title: "Time Zones with Summer Time",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(\.hasDaylightSavingTime == true)
.orderBy(.ascending(\.name))
)!
)
}
)
]
@@ -235,28 +235,28 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
title: "Number of Time Zones",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
return try! Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(NSNumber.self, .count(\.name))
)! as Any
)!
}
),
(
title: "Abbreviation For Tokyo's Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
return try! Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(String.self, .attribute(\.abbreviation))
.where(format: "%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
)! as Any
)!
}
),
(
title: "All Abbreviations",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
@@ -264,14 +264,14 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
.attribute(\.abbreviation)
)
.orderBy(.ascending(\.name))
)!
)
}
),
(
title: "Number of Countries per Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
@@ -283,14 +283,14 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
.ascending(\.secondsFromGMT),
.ascending(\.name)
)
)!
)
}
),
(
title: "Number of Countries with Summer Time",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
@@ -302,7 +302,7 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
.descending(\.hasDaylightSavingTime),
.ascending(\.name)
)
)!
)
}
)
]

View File

@@ -1,5 +1,15 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
@@ -32,6 +42,36 @@
"filename" : "Icon-60@3x-1.png",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
@@ -44,6 +84,21 @@
"filename" : "Icon-76@2x.png",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
},
{
"idiom" : "car",
"size" : "60x60",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "car",

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>5.1.0</string>
<string>6.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -122,6 +122,11 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
target: self,
action: #selector(self.addBarButtonItemTouched(_:))
),
UIBarButtonItem(
barButtonSystemItem: .refresh,
target: self,
action: #selector(self.shuffleBarButtonItemTouched(_:))
),
filterBarButton
]
self.filterBarButton = filterBarButton
@@ -155,7 +160,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ColorsDemo.palettes.numberOfObjectsInSection(section)
return ColorsDemo.palettes.numberOfObjects(in: section)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -203,7 +208,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ColorsDemo.palettes.sectionInfoAtIndex(section).name
return ColorsDemo.palettes.sectionInfo(at: section).name
}
@@ -283,7 +288,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
transaction.deleteAll(From<Palette>())
try transaction.deleteAll(From<Palette>())
},
completion: { _ in }
)
@@ -305,9 +310,29 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
completion: { _ in }
)
}
@IBAction private dynamic func shuffleBarButtonItemTouched(_ sender: AnyObject?) {
self.setTable(enabled: false)
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
for palette in try transaction.fetchAll(From<Palette>()) {
palette.hue .= Palette.randomHue()
palette.colorName .= nil
}
},
completion: { _ in
self.setTable(enabled: true)
}
)
}
private func setTable(enabled: Bool) {
tableView.isUserInteractionEnabled = enabled
UIView.animate(
withDuration: 0.2,
delay: 0,
@@ -317,7 +342,6 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
if let tableView = self.tableView {
tableView.alpha = enabled ? 1.0 : 0.5
tableView.isUserInteractionEnabled = enabled
}
},
completion: nil

View File

@@ -50,7 +50,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
required init?(coder aDecoder: NSCoder) {
if let palette = ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue))) {
if let palette = try! ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue))) {
self.monitor = ColorsDemo.stack.monitorObject(palette)
}
@@ -64,7 +64,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
}
)
let palette = ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue)))!
let palette = try! ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue)))!
self.monitor = ColorsDemo.stack.monitorObject(palette)
}

View File

@@ -25,6 +25,11 @@ final class Palette: CoreStoreObject {
isTransient: true,
customGetter: Palette.getColorName
)
static func randomHue() -> Int {
return Int(arc4random_uniform(360))
}
private static func getColorName(_ partialObject: PartialObject<Palette>) -> String? {
@@ -71,7 +76,7 @@ extension Palette {
func setInitialValues(in transaction: BaseDataTransaction) {
self.hue .= Int(arc4random_uniform(360))
self.hue .= Palette.randomHue()
self.saturation .= Float(1.0)
self.brightness .= Float(arc4random_uniform(70) + 30) / 100.0
}

View File

@@ -16,11 +16,6 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
// MARK: NSObject
deinit {
CoreStore.logger = DefaultLogger()
}
let dataStack = DataStack()
// MARK: UIViewController
@@ -30,13 +25,14 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
super.viewDidLoad()
try! self.dataStack.addStorageAndWait(SQLiteStore(fileName: "emptyStore.sqlite"))
CoreStore.logger = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
CoreStore.logger = self
let alert = UIAlertController(
title: "Logger Demo",
message: "This demo shows how to plug-in any logging framework to CoreStore.\n\nThe view controller implements CoreStoreLogger and appends all logs to the text view.",
@@ -46,6 +42,13 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
self.present(alert, animated: true, completion: nil)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
CoreStore.logger = DefaultLogger()
}
// MARK: CoreStoreLogger
@@ -113,7 +116,7 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
case 2?:
DispatchQueue.global(qos: .background).async {
_ = self.dataStack.fetchOne(From<Place>())
_ = try! self.dataStack.fetchOne(From<Place>())
}
default:

View File

@@ -79,7 +79,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
func listMonitorDidChange(_ monitor: ListMonitor<NSManagedObject>) {
if self.lastSelectedIndexPath == nil,
let numberOfObjectsInSection = self.listMonitor?.numberOfObjectsInSection(0),
let numberOfObjectsInSection = self.listMonitor?.numberOfObjects(in: 0),
numberOfObjectsInSection > 0 {
self.tableView?.reloadData()
@@ -100,7 +100,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listMonitor?.numberOfObjectsInSection(0) ?? 0
return self.listMonitor?.numberOfObjects(in: 0) ?? 0
}
@objc dynamic func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -286,7 +286,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
self.set(dataStack: dataStack, model: model, scrollToSelection: true)
let count = dataStack.queryValue(
let count = try! dataStack.queryValue(
From<NSManagedObject>(model.entityType)
.select(Int.self, .count(#keyPath(OrganismV1.dna))))!
if count > 0 {
@@ -378,7 +378,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
if self.lastSelectedIndexPath == nil {
if listMonitor.numberOfObjectsInSection(0) > 0 {
if listMonitor.numberOfObjects(in: 0) > 0 {
self.setSelectedIndexPath(IndexPath(row: 0, section: 0), scrollToSelection: true)
}

View File

@@ -36,7 +36,7 @@ private struct Static {
_ = try? dataStack.perform(
synchronous: { (transaction) in
transaction.deleteAll(From<UserAccount>())
try transaction.deleteAll(From<UserAccount>())
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
account1.accountType = "Facebook"
@@ -74,7 +74,7 @@ private struct Static {
_ = try? dataStack.perform(
synchronous: { (transaction) in
transaction.deleteAll(From<UserAccount>())
try transaction.deleteAll(From<UserAccount>())
let account1 = transaction.create(Into<MaleAccount>(maleConfiguration))
account1.accountType = "Twitter"
@@ -99,8 +99,8 @@ private struct Static {
class StackSetupDemoViewController: UITableViewController {
let accounts = [
Static.facebookStack.fetchAll(From(UserAccount.self)) ?? [],
Static.twitterStack.fetchAll(From(UserAccount.self)) ?? []
try! Static.facebookStack.fetchAll(From<UserAccount>()),
try! Static.twitterStack.fetchAll(From<UserAccount>())
]

View File

@@ -26,7 +26,7 @@ private struct Static {
)
)
var place = CoreStore.fetchOne(From<Place>())
var place = try! CoreStore.fetchOne(From<Place>())
if place == nil {
_ = try? CoreStore.perform(
@@ -36,7 +36,7 @@ private struct Static {
place.setInitialValues()
}
)
place = CoreStore.fetchOne(From<Place>())
place = try! CoreStore.fetchOne(From<Place>())
}
return CoreStore.monitorObject(place!)

View File

@@ -36,8 +36,7 @@ class BaseTestCase: XCTestCase {
// MARK: Internal
@nonobjc
@discardableResult
func prepareStack<T>(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> T) -> T {
func prepareStack(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) throws -> Void) {
let stack = DataStack(
xcodeModelName: "Model",
@@ -57,16 +56,16 @@ class BaseTestCase: XCTestCase {
)
)
}
try closure(stack)
}
catch let error as NSError {
XCTFail(error.coreStoreDumpString)
}
return closure(stack)
}
@nonobjc
func expectLogger<T>(_ expectations: [TestLogger.Expectation], closure: () -> T) -> T {
func expectLogger<T>(_ expectations: [TestLogger.Expectation], closure: () throws -> T) rethrows -> T {
CoreStore.logger = TestLogger(self.prepareLoggerExpectations(expectations))
defer {
@@ -74,7 +73,7 @@ class BaseTestCase: XCTestCase {
self.checkExpectationsImmediately()
CoreStore.logger = TestLogger([:])
}
return closure()
return try closure()
}
@nonobjc
@@ -82,6 +81,33 @@ class BaseTestCase: XCTestCase {
CoreStore.logger = TestLogger(expectations)
}
@nonobjc
func expectError<T>(code: CoreStoreErrorCode, closure: () throws -> T) {
CoreStore.logger = TestLogger(self.prepareLoggerExpectations([.logError]))
defer {
self.checkExpectationsImmediately()
CoreStore.logger = TestLogger([:])
}
do {
_ = try closure()
}
catch let error as CoreStoreError {
if error.errorCode == code.rawValue {
return
}
XCTFail("Expected error code \(code) different from actual error: \((error as NSError).coreStoreDumpString)")
}
catch {
XCTFail("Error not wrapped as \(cs_typeName(CoreStoreError.self)): \((error as NSError).coreStoreDumpString)")
}
}
@nonobjc
func prepareLoggerExpectations(_ expectations: [TestLogger.Expectation]) -> [TestLogger.Expectation: XCTestExpectation] {

View File

@@ -30,9 +30,10 @@ import CoreStore
#if os(macOS)
typealias Color = NSColor
#else
typealias Color = UIColor
#endif
class Animal: CoreStoreObject {
@@ -70,8 +71,13 @@ class Person: CoreStoreObject {
customGetter: Person.getDisplayName(_:),
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
)
let spouse = Relationship.ToOne<Person>("spouse")
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
private let _spouse = Relationship.ToOne<Person>("_spouseInverse", inverse: { $0.spouse })
private static func setTitle(_ partialObject: PartialObject<Person>, _ newValue: String) {
@@ -126,7 +132,7 @@ class DynamicModelTests: BaseTestDataTestCase {
versionLock: [
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
"Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b]
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
]
)
)
@@ -134,7 +140,7 @@ class DynamicModelTests: BaseTestDataTestCase {
let k1 = String(keyPath: \Animal.species)
XCTAssertEqual(k1, "species")
let k2 = String(keyPath: \Dog.species)
XCTAssertEqual(k2, "species")
@@ -143,6 +149,9 @@ class DynamicModelTests: BaseTestDataTestCase {
let updateDone = self.expectation(description: "update-done")
let fetchDone = self.expectation(description: "fetch-done")
let willSetPriorObserverDone = self.expectation(description: "willSet-observe-prior-done")
let willSetNotPriorObserverDone = self.expectation(description: "willSet-observe-notPrior-done")
let didSetObserverDone = self.expectation(description: "didSet-observe-done")
stack.perform(
asynchronous: { (transaction) in
@@ -160,9 +169,42 @@ class DynamicModelTests: BaseTestDataTestCase {
XCTAssertEqual(dog.species.value, "Swift")
XCTAssertEqual(dog.nickname.value, nil)
XCTAssertEqual(dog.age.value, 1)
let didSetObserver = dog.species.observe(options: [.new, .old]) { (object, change) in
XCTAssertEqual(object, dog)
XCTAssertEqual(change.kind, .setting)
XCTAssertEqual(change.newValue, "Dog")
XCTAssertEqual(change.oldValue, "Swift")
XCTAssertFalse(change.isPrior)
XCTAssertEqual(object.species.value, "Dog")
didSetObserverDone.fulfill()
}
let willSetObserver = dog.species.observe(options: [.new, .old, .prior]) { (object, change) in
XCTAssertEqual(object, dog)
XCTAssertEqual(change.kind, .setting)
XCTAssertEqual(change.oldValue, "Swift")
if change.isPrior {
XCTAssertNil(change.newValue)
XCTAssertEqual(object.species.value, "Swift")
willSetPriorObserverDone.fulfill()
}
else {
XCTAssertEqual(change.newValue, "Dog")
XCTAssertEqual(object.species.value, "Dog")
willSetNotPriorObserverDone.fulfill()
}
}
dog.species .= "Dog"
XCTAssertEqual(dog.species.value, "Dog")
didSetObserver.invalidate()
willSetObserver.invalidate()
dog.nickname .= "Spot"
XCTAssertEqual(dog.nickname.value, "Spot")
@@ -212,51 +254,54 @@ class DynamicModelTests: BaseTestDataTestCase {
let p1 = Where<Animal>({ $0.species == "Sparrow" })
XCTAssertEqual(p1.predicate, NSPredicate(format: "%K == %@", "species", "Sparrow"))
let bird = transaction.fetchOne(From<Animal>(), p1)
let bird = try transaction.fetchOne(From<Animal>(), p1)
XCTAssertNotNil(bird)
XCTAssertEqual(bird!.species.value, "Sparrow")
let p2 = Where<Dog>({ $0.nickname == "Spot" })
XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot"))
let dog = transaction.fetchOne(From<Dog>().where(\.nickname == "Spot"))
let dog = try transaction.fetchOne(From<Dog>().where(\.nickname == "Spot"))
XCTAssertNotNil(dog)
XCTAssertEqual(dog!.nickname.value, "Spot")
XCTAssertEqual(dog!.species.value, "Dog")
let person = transaction.fetchOne(From<Person>())
let person = try transaction.fetchOne(From<Person>())
XCTAssertNotNil(person)
XCTAssertEqual(person!.pets.value.first, dog)
let p3 = Where<Dog>({ $0.age == 10 })
XCTAssertEqual(p3.predicate, NSPredicate(format: "%K == %d", "age", 10))
let totalAge = try transaction.queryValue(From<Dog>().select(Int.self, .sum(\Dog.age)))
XCTAssertEqual(totalAge, 1)
_ = transaction.fetchAll(
_ = try transaction.fetchAll(
From<Dog>()
.where(\Animal.species == "Dog" && \.age == 10)
.where(\Animal.species == "Dog" && \Dog.age == 10)
)
_ = transaction.fetchAll(
_ = try transaction.fetchAll(
From<Dog>()
.where(\.age == 10 && \Animal.species == "Dog")
.where(\Dog.age == 10 && \Animal.species == "Dog")
.orderBy(.ascending({ $0.species }))
)
_ = transaction.fetchAll(
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.age > 10 && $0.age <= 15 })
)
_ = transaction.fetchAll(
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.species == "Dog" && $0.age == 10 })
)
_ = transaction.fetchAll(
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.age == 10 && $0.species == "Dog" })
)
_ = transaction.fetchAll(
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.age > 10 && $0.age <= 15 })
)
_ = transaction.fetchAll(
_ = try transaction.fetchAll(
From<Dog>(),
(\Dog.age > 10 && \Dog.age <= 15)
)

File diff suppressed because it is too large Load Diff

View File

@@ -74,33 +74,31 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>()
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
try from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
}
do {
let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
}
@@ -115,102 +113,98 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>()
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>()
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
}
@@ -225,99 +219,96 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>()
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(Set(affectedConfigurations), ["PF_DEFAULT_CONFIGURATION_NAME", "Config1"] as Set)
}
do {
let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>()
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
}
@@ -332,96 +323,94 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>()
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>()
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"])
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
from.applyToFetchRequest(request, context: dataStack.mainContext)
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertFalse(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertTrue(storesFound)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"])
}
}

View File

@@ -68,8 +68,8 @@ final class GroupByTests: BaseTestCase {
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
let request = CoreStoreFetchRequest()
_ = From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
try From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
groupBy.applyToFetchRequest(request)
XCTAssertNotNil(request.propertiesToGroupBy)

View File

@@ -95,7 +95,7 @@ class ImportTests: BaseTestDataTestCase {
]
)
XCTAssertNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
}
)
}
@@ -103,7 +103,7 @@ class ImportTests: BaseTestDataTestCase {
XCTFail()
}
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
}
}
@@ -137,9 +137,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestInsertError {
errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
let object = transaction.fetchOne(From<TestEntity1>())
let object = try transaction.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertNil(object?.testEntityID)
XCTAssertNil(object?.testBoolean)
@@ -182,7 +182,7 @@ class ImportTests: BaseTestDataTestCase {
]
)
XCTAssertNotNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertNil(object?.testEntityID)
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertEqual(object?.testNumber, NSNumber(value: 1))
@@ -202,7 +202,7 @@ class ImportTests: BaseTestDataTestCase {
#keyPath(TestEntity1.testDate): self.dateFormatter.date(from: "2000-01-02T00:00:00Z")!
]
)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertNil(object?.testEntityID)
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 2))
@@ -254,7 +254,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray
)
XCTAssertEqual(objects.count, 1)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
let object = objects[0]
let dictionary = sourceArray[1]
@@ -316,9 +316,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestInsertError {
errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
let object = transaction.fetchOne(From<TestEntity1>())
let object = try transaction.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertNil(object?.testEntityID)
XCTAssertNil(object?.testBoolean)
@@ -372,7 +372,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray
)
XCTAssertEqual(objects.count, sourceArray.count)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 2)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 2)
for i in 0 ..< sourceArray.count {
@@ -424,7 +424,7 @@ class ImportTests: BaseTestDataTestCase {
]
)
XCTAssertNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
}
do {
@@ -442,20 +442,19 @@ class ImportTests: BaseTestDataTestCase {
]
)
XCTAssertNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects)
XCTAssertEqual(existingObjects?.count, 1)
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertEqual(existingObjects.count, 1)
let existingObject = existingObjects?[0]
XCTAssertEqual(existingObject?.testEntityID, NSNumber(value: 105))
XCTAssertEqual(existingObject?.testBoolean, NSNumber(value: true))
XCTAssertEqual(existingObject?.testNumber, NSNumber(value: 5))
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5"))
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5")
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
let existingObject = existingObjects[0]
XCTAssertEqual(existingObject.testEntityID, NSNumber(value: 105))
XCTAssertEqual(existingObject.testBoolean, NSNumber(value: true))
XCTAssertEqual(existingObject.testNumber, NSNumber(value: 5))
XCTAssertEqual(existingObject.testDecimal, NSDecimalNumber(string: "5"))
XCTAssertEqual(existingObject.testString, "nil:TestEntity1:5")
XCTAssertEqual(existingObject.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(existingObject.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
}
}
)
@@ -504,7 +503,7 @@ class ImportTests: BaseTestDataTestCase {
)
XCTAssertEqual(objects.count, 1)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let object = objects[0]
let dictionary = sourceArray[1]
@@ -618,9 +617,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestInsertError {
errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let object = transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertNil(object?.testBoolean)
@@ -657,21 +656,19 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestUpdateError {
errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects)
XCTAssertEqual(existingObjects?.count, 1)
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertEqual(existingObjects.count, 1)
let existingObject = existingObjects?[0]
XCTAssertNotNil(existingObject)
XCTAssertEqual(existingObject?.testEntityID, NSNumber(value: 105))
XCTAssertEqual(existingObject?.testBoolean, NSNumber(value: true))
XCTAssertEqual(existingObject?.testNumber, NSNumber(value: 5))
XCTAssertEqual(existingObject?.testDecimal, NSDecimalNumber(string: "5"))
XCTAssertEqual(existingObject?.testString, "nil:TestEntity1:5")
XCTAssertEqual(existingObject?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(existingObject?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
let existingObject = existingObjects[0]
XCTAssertEqual(existingObject.testEntityID, NSNumber(value: 105))
XCTAssertEqual(existingObject.testBoolean, NSNumber(value: true))
XCTAssertEqual(existingObject.testNumber, NSNumber(value: 5))
XCTAssertEqual(existingObject.testDecimal, NSDecimalNumber(string: "5"))
XCTAssertEqual(existingObject.testString, "nil:TestEntity1:5")
XCTAssertEqual(existingObject.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(existingObject.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
}
self.checkExpectationsImmediately()
}
@@ -710,7 +707,7 @@ class ImportTests: BaseTestDataTestCase {
]
)
XCTAssertNotNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -735,7 +732,7 @@ class ImportTests: BaseTestDataTestCase {
]
)
XCTAssertNotNil(object)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
@@ -745,11 +742,10 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(object?.testData, ("nil:TestEntity1:7" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-07T00:00:00Z")!)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
XCTAssertNotNil(existingObjects)
XCTAssertEqual(existingObjects?.count, 1)
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
XCTAssertEqual(existingObjects.count, 1)
let existingObject = existingObjects?[0]
let existingObject = existingObjects[0]
XCTAssertEqual(existingObject, object)
}
}
@@ -799,7 +795,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray
)
XCTAssertEqual(objects.count, 1)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
let object = objects[0]
let dictionary = sourceArray[1]
@@ -864,10 +860,10 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestIDError {
errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
}
transaction.unsafeContext().reset()
self.checkExpectationsImmediately()
@@ -910,7 +906,7 @@ class ImportTests: BaseTestDataTestCase {
errorExpectation.fulfill()
let object = transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
XCTAssertNil(object?.testBoolean)
@@ -951,9 +947,9 @@ class ImportTests: BaseTestDataTestCase {
catch _ as TestUpdateError {
errorExpectation.fulfill()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 5)
let object = transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
let object = try transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 105))
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
@@ -963,11 +959,10 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(object?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects)
XCTAssertEqual(existingObjects?.count, 1)
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertEqual(existingObjects.count, 1)
let existingObject = existingObjects?[0]
let existingObject = existingObjects[0]
XCTAssertEqual(existingObject, object)
}
transaction.context.reset()
@@ -1018,7 +1013,7 @@ class ImportTests: BaseTestDataTestCase {
sourceArray: sourceArray
)
XCTAssertEqual(objects.count, sourceArray.count)
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 6)
for i in 0 ..< sourceArray.count {
let object = objects[i]
@@ -1032,11 +1027,10 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
}
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertNotNil(existingObjects)
XCTAssertEqual(existingObjects?.count, 1)
let existingObjects = try transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
XCTAssertEqual(existingObjects.count, 1)
let existingObject = existingObjects?[0]
let existingObject = existingObjects[0]
XCTAssertEqual(existingObject, objects[0])
}
)

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>5.3.1</string>
<string>6.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -76,7 +76,7 @@ class ListObserverTests: BaseTestDataTestCase {
XCTAssertEqual(
((note.userInfo as NSDictionary?) ?? [:]),
[
"sectionInfo": monitor.sectionInfoAtIndex(0),
"sectionInfo": monitor.sectionInfo(at: 0),
"sectionIndex": 0
] as NSDictionary
)
@@ -178,9 +178,9 @@ class ListObserverTests: BaseTestDataTestCase {
XCTAssertTrue(monitor.hasSections())
XCTAssertEqual(monitor.numberOfSections(), 2)
XCTAssertTrue(monitor.hasObjects())
XCTAssertTrue(monitor.hasObjectsInSection(0))
XCTAssertEqual(monitor.numberOfObjectsInSection(0), 2)
XCTAssertEqual(monitor.numberOfObjectsInSection(1), 3)
XCTAssertTrue(monitor.hasObjects(in: 0))
XCTAssertEqual(monitor.numberOfObjects(in: 0), 2)
XCTAssertEqual(monitor.numberOfObjects(in: 1), 3)
var events = 0
@@ -268,7 +268,7 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
if let object = transaction.fetchOne(
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
@@ -282,7 +282,7 @@ class ListObserverTests: BaseTestDataTestCase {
XCTFail()
}
if let object = transaction.fetchOne(
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
@@ -394,7 +394,7 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
if let object = transaction.fetchOne(
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
@@ -526,7 +526,7 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
let count = transaction.deleteAll(
let count = try transaction.deleteAll(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
)

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11759" systemVersion="16C67" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="17G2307" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="TestEntity1AAA" representedClassName="CoreStoreTests.TestEntity1" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
@@ -9,6 +9,8 @@
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="testToManyUnordered" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToOne" inverseEntity="TestEntity1AAA" syncable="YES"/>
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToManyUnordered" inverseEntity="TestEntity1AAA" syncable="YES"/>
</entity>
<entity name="TestEntity2" representedClassName="CoreStoreTests.TestEntity2" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
@@ -19,6 +21,8 @@
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="testToManyOrdered" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TestEntity2" inverseName="testToOne" inverseEntity="TestEntity2" syncable="YES"/>
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity2" inverseName="testToManyOrdered" inverseEntity="TestEntity2" syncable="YES"/>
</entity>
<configuration name="Config1">
<memberEntity name="TestEntity1AAA"/>
@@ -27,7 +31,7 @@
<memberEntity name="TestEntity2"/>
</configuration>
<elements>
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="165"/>
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="165"/>
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="195"/>
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="195"/>
</elements>
</model>

View File

@@ -41,7 +41,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne(
guard let object = try stack.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
@@ -138,7 +138,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne(
guard let object = try stack.fetchOne(
From<TestEntity1>(),
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {

View File

@@ -179,7 +179,7 @@ final class OrderByTests: XCTestCase {
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
orderBy.applyToFetchRequest(request)
XCTAssertNotNil(request.sortDescriptors)
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)

View File

@@ -47,7 +47,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Bool>(#keyPath(TestEntity1.testBoolean)),
queryClauses
@@ -57,7 +57,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int8>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -67,7 +67,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int16>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -77,7 +77,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int32>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -87,7 +87,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int64>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -97,7 +97,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -107,7 +107,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Double>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -117,7 +117,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Float>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -127,7 +127,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSNumber>(#keyPath(TestEntity1.testNumber)),
queryClauses
@@ -137,7 +137,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDecimalNumber>(#keyPath(TestEntity1.testDecimal)),
queryClauses
@@ -147,7 +147,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, String>(#keyPath(TestEntity1.testString)),
queryClauses
@@ -157,7 +157,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSString>(#keyPath(TestEntity1.testString)),
queryClauses
@@ -167,7 +167,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Data>(#keyPath(TestEntity1.testData)),
queryClauses
@@ -177,7 +177,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSData>(#keyPath(TestEntity1.testData)),
queryClauses
@@ -187,7 +187,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Date>(#keyPath(TestEntity1.testDate)),
queryClauses
@@ -197,7 +197,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDate>(#keyPath(TestEntity1.testDate)),
queryClauses
@@ -207,7 +207,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSManagedObjectID>(#keyPath(TestEntity1.testDate)),
queryClauses
@@ -232,7 +232,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Bool>(.average(#keyPath(TestEntity1.testBoolean))),
queryClauses
@@ -242,7 +242,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int8>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -252,7 +252,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int16>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -262,7 +262,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int32>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -272,7 +272,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int64>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -282,7 +282,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -292,7 +292,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Double>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -302,7 +302,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Float>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -312,7 +312,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSNumber>(.average(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -322,7 +322,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDecimalNumber>(.average(#keyPath(TestEntity1.testDecimal))),
queryClauses
@@ -332,7 +332,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, String>(.average(#keyPath(TestEntity1.testString))),
queryClauses
@@ -341,7 +341,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSString>(.average(#keyPath(TestEntity1.testString))),
queryClauses
@@ -350,7 +350,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Data>(.average(#keyPath(TestEntity1.testData))),
queryClauses
@@ -359,7 +359,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSData>(.average(#keyPath(TestEntity1.testData))),
queryClauses
@@ -368,7 +368,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Date>(.average(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -377,7 +377,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDate>(.average(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -386,7 +386,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSManagedObjectID>(#keyPath(TestEntity1.testEntityID)),
queryClauses
@@ -410,7 +410,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Bool>(.count(#keyPath(TestEntity1.testBoolean))),
queryClauses
@@ -420,7 +420,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int8>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -430,7 +430,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int16>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -440,7 +440,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int32>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -450,7 +450,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int64>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -460,7 +460,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -470,7 +470,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Double>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -480,7 +480,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Float>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -490,7 +490,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSNumber>(.count(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -500,7 +500,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDecimalNumber>(.count(#keyPath(TestEntity1.testDecimal))),
queryClauses
@@ -509,7 +509,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, String>(.count(#keyPath(TestEntity1.testString))),
queryClauses
@@ -518,7 +518,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSString>(.count(#keyPath(TestEntity1.testString))),
queryClauses
@@ -527,7 +527,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Data>(.count(#keyPath(TestEntity1.testData))),
queryClauses
@@ -536,7 +536,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSData>(.count(#keyPath(TestEntity1.testData))),
queryClauses
@@ -545,7 +545,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Date>(.count(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -554,7 +554,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDate>(.count(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -563,7 +563,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSManagedObjectID>(.count(#keyPath(TestEntity1.testEntityID))),
queryClauses
@@ -587,7 +587,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Bool>(.maximum(#keyPath(TestEntity1.testBoolean))),
queryClauses
@@ -597,7 +597,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int8>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -607,7 +607,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int16>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -617,7 +617,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int32>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -627,7 +627,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int64>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -637,7 +637,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -647,7 +647,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Double>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -657,7 +657,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Float>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -667,7 +667,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSNumber>(.maximum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -677,7 +677,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDecimalNumber>(.maximum(#keyPath(TestEntity1.testDecimal))),
queryClauses
@@ -687,7 +687,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, String>(.maximum(#keyPath(TestEntity1.testString))),
queryClauses
@@ -697,7 +697,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSString>(.maximum(#keyPath(TestEntity1.testString))),
queryClauses
@@ -707,7 +707,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Data>(.maximum(#keyPath(TestEntity1.testData))),
queryClauses
@@ -717,7 +717,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSData>(.maximum(#keyPath(TestEntity1.testData))),
queryClauses
@@ -727,7 +727,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Date>(.maximum(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -737,7 +737,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDate>(.maximum(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -747,7 +747,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSManagedObjectID>(.maximum(#keyPath(TestEntity1.testEntityID))),
queryClauses
@@ -771,7 +771,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Bool>(.minimum(#keyPath(TestEntity1.testBoolean))),
queryClauses
@@ -781,7 +781,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int8>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -791,7 +791,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int16>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -801,7 +801,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int32>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -811,7 +811,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int64>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -821,7 +821,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -831,7 +831,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Double>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -841,7 +841,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Float>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -851,7 +851,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSNumber>(.minimum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -861,7 +861,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDecimalNumber>(.minimum(#keyPath(TestEntity1.testDecimal))),
queryClauses
@@ -871,7 +871,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, String>(.minimum(#keyPath(TestEntity1.testString))),
queryClauses
@@ -881,7 +881,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSString>(.minimum(#keyPath(TestEntity1.testString))),
queryClauses
@@ -891,7 +891,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Data>(.minimum(#keyPath(TestEntity1.testData))),
queryClauses
@@ -901,7 +901,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSData>(.minimum(#keyPath(TestEntity1.testData))),
queryClauses
@@ -911,7 +911,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Date>(.minimum(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -921,7 +921,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDate>(.minimum(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -931,7 +931,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSManagedObjectID>(.minimum(#keyPath(TestEntity1.testEntityID))),
queryClauses
@@ -955,7 +955,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Bool>(.sum(#keyPath(TestEntity1.testBoolean))),
queryClauses
@@ -965,7 +965,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int8>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -975,7 +975,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int16>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -985,7 +985,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int32>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -995,7 +995,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int64>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -1005,7 +1005,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -1015,7 +1015,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Double>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -1025,7 +1025,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Float>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -1035,7 +1035,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSNumber>(.sum(#keyPath(TestEntity1.testNumber))),
queryClauses
@@ -1045,7 +1045,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDecimalNumber>(.sum(#keyPath(TestEntity1.testDecimal))),
queryClauses
@@ -1055,7 +1055,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, String>(.sum(#keyPath(TestEntity1.testString))),
queryClauses
@@ -1064,7 +1064,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSString>(.sum(#keyPath(TestEntity1.testString))),
queryClauses
@@ -1073,7 +1073,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Data>(.sum(#keyPath(TestEntity1.testData))),
queryClauses
@@ -1082,7 +1082,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSData>(.sum(#keyPath(TestEntity1.testData))),
queryClauses
@@ -1091,7 +1091,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Date>(.sum(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -1100,7 +1100,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDate>(.sum(#keyPath(TestEntity1.testDate))),
queryClauses
@@ -1109,7 +1109,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSManagedObjectID>(.sum(#keyPath(TestEntity1.testEntityID))),
queryClauses
@@ -1133,7 +1133,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Bool>(.objectID()),
queryClauses
@@ -1142,7 +1142,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int8>(.objectID()),
queryClauses
@@ -1151,7 +1151,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int16>(.objectID()),
queryClauses
@@ -1160,7 +1160,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int32>(.objectID()),
queryClauses
@@ -1169,7 +1169,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int64>(.objectID()),
queryClauses
@@ -1178,7 +1178,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Int>(.objectID()),
queryClauses
@@ -1187,7 +1187,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Double>(.objectID()),
queryClauses
@@ -1196,7 +1196,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Float>(.objectID()),
queryClauses
@@ -1205,7 +1205,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSNumber>(.objectID()),
queryClauses
@@ -1214,7 +1214,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDecimalNumber>(.objectID()),
queryClauses
@@ -1223,7 +1223,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, String>(.objectID()),
queryClauses
@@ -1232,7 +1232,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSString>(.objectID()),
queryClauses
@@ -1241,7 +1241,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Data>(.objectID()),
queryClauses
@@ -1250,7 +1250,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSData>(.objectID()),
queryClauses
@@ -1259,7 +1259,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, Date>(.objectID()),
queryClauses
@@ -1268,7 +1268,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSDate>(.objectID()),
queryClauses
@@ -1277,7 +1277,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let value = stack.queryValue(
let value = try stack.queryValue(
from,
Select<TestEntity1, NSManagedObjectID>(.objectID()),
queryClauses
@@ -1302,7 +1302,7 @@ class QueryTests: BaseTestDataTestCase {
]
do {
let values = stack.queryAttributes(
let values = try stack.queryAttributes(
from,
Select<TestEntity1, NSDictionary>(
#keyPath(TestEntity1.testBoolean),
@@ -1353,7 +1353,7 @@ class QueryTests: BaseTestDataTestCase {
let queryClauses: [QueryClause] = []
do {
let values = stack.queryAttributes(
let values = try stack.queryAttributes(
from,
Select<TestEntity1, NSDictionary>(
.sum(#keyPath(TestEntity1.testBoolean)),
@@ -1380,7 +1380,7 @@ class QueryTests: BaseTestDataTestCase {
}
do {
let values = stack.queryAttributes(
let values = try stack.queryAttributes(
from,
Select(
.sum(#keyPath(TestEntity1.testBoolean), as: "testSum"),

View File

@@ -330,7 +330,14 @@ class SetupTests: BaseTestDataTestCase {
xcodeModelName: "Model",
bundle: Bundle(for: type(of: self))
)
try! stack.addStorageAndWait(sqliteStore)
try! stack.addStorageAndWait(
SQLiteStore.legacy(
fileName: sqliteStore.fileURL.lastPathComponent,
configuration: sqliteStore.configuration,
migrationMappingProviders: sqliteStore.migrationMappingProviders,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
self.prepareTestDataForStack(stack)
}
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))

View File

@@ -107,8 +107,8 @@ final class StorageInterfaceTests: XCTestCase {
@objc
dynamic func test_ThatFileURLSQLiteStores_ConfigureCorrectly() {
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
.appendingPathComponent(NSUUID().uuidString, isDirectory: false)!
let fileURL = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString, isDirectory: false)
.appendingPathExtension("db")
let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2",

View File

@@ -36,4 +36,6 @@ class TestEntity1: NSManagedObject {
@NSManaged var testDecimal: NSDecimalNumber?
@NSManaged var testData: Data?
@NSManaged var testNil: String?
@NSManaged var testToOne: TestEntity1?
@NSManaged var testToManyUnordered: NSSet?
}

View File

@@ -36,4 +36,6 @@ class TestEntity2: NSManagedObject {
@NSManaged var testDecimal: NSDecimalNumber?
@NSManaged var testData: Data?
@NSManaged var testNil: String?
@NSManaged var testToOne: TestEntity2?
@NSManaged var testToManyOrdered: NSOrderedSet?
}

View File

@@ -69,9 +69,9 @@ final class TransactionTests: BaseTestCase {
self.checkExpectationsImmediately()
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
@@ -84,14 +84,14 @@ final class TransactionTests: BaseTestCase {
do {
let updateExpectation = self.expectation(description: "update")
let hasChanges: Bool = try! stack.perform(
let hasChanges: Bool = try stack.perform(
synchronous: { (transaction) in
defer {
updateExpectation.fulfill()
}
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
// TODO: convert fetch methods to throwing methods
XCTFail()
try transaction.cancel()
@@ -107,9 +107,9 @@ final class TransactionTests: BaseTestCase {
self.checkExpectationsImmediately()
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
@@ -128,7 +128,7 @@ final class TransactionTests: BaseTestCase {
deleteExpectation.fulfill()
}
let object = transaction.fetchOne(From<TestEntity1>())
let object = try transaction.fetchOne(From<TestEntity1>())
transaction.delete(object)
return transaction.hasChanges
}
@@ -141,9 +141,9 @@ final class TransactionTests: BaseTestCase {
}
self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNil(object)
}
}
@@ -184,10 +184,10 @@ final class TransactionTests: BaseTestCase {
}
self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1"))
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
@@ -206,7 +206,7 @@ final class TransactionTests: BaseTestCase {
updateExpectation.fulfill()
}
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
XCTFail()
try transaction.cancel()
@@ -226,10 +226,10 @@ final class TransactionTests: BaseTestCase {
}
self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1"))
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
@@ -248,7 +248,7 @@ final class TransactionTests: BaseTestCase {
deleteExpectation.fulfill()
}
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
transaction.delete(object)
return transaction.hasChanges
@@ -262,8 +262,8 @@ final class TransactionTests: BaseTestCase {
}
self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
}
}
}
@@ -294,17 +294,17 @@ final class TransactionTests: BaseTestCase {
)
self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNil(object)
}
let testDate = Date()
do {
let createExpectation = self.expectation(description: "create")
let dataPrepared: Void? = try? stack.perform(
synchronous: { (transaction) in
try stack.perform(
synchronous: { (transaction) -> Void in
let object = transaction.create(Into<TestEntity1>())
object.testEntityID = NSNumber(value: 1)
@@ -313,10 +313,7 @@ final class TransactionTests: BaseTestCase {
object.testDate = testDate
}
)
if dataPrepared != nil {
createExpectation.fulfill()
}
createExpectation.fulfill()
self.checkExpectationsImmediately()
}
do {
@@ -329,7 +326,7 @@ final class TransactionTests: BaseTestCase {
updateDiscardExpectation.fulfill()
}
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
try transaction.cancel()
@@ -343,9 +340,9 @@ final class TransactionTests: BaseTestCase {
)
self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
@@ -362,7 +359,7 @@ final class TransactionTests: BaseTestCase {
deleteDiscardExpectation.fulfill()
}
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
try transaction.cancel()
@@ -374,9 +371,9 @@ final class TransactionTests: BaseTestCase {
)
self.checkExpectationsImmediately()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
@@ -520,19 +517,26 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
createExpectation.fulfill()
do {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
createExpectation.fulfill()
}
catch {
XCTFail()
}
},
failure: { _ in
@@ -546,7 +550,7 @@ final class TransactionTests: BaseTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
try transaction.cancel()
@@ -560,16 +564,23 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
XCTAssertEqual(object?.testNumber, 200)
XCTAssertEqual(object?.testDate, Date.distantFuture)
updateExpectation.fulfill()
do {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
XCTAssertEqual(object?.testNumber, 200)
XCTAssertEqual(object?.testDate, Date.distantFuture)
updateExpectation.fulfill()
}
catch {
XCTFail()
}
},
failure: { _ in
@@ -583,7 +594,7 @@ final class TransactionTests: BaseTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
let object = transaction.fetchOne(From<TestEntity1>())
let object = try transaction.fetchOne(From<TestEntity1>())
transaction.delete(object)
return transaction.hasChanges
@@ -591,12 +602,19 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
let object = stack.fetchOne(From<TestEntity1>())
XCTAssertNil(object)
deleteExpectation.fulfill()
do {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNil(object)
deleteExpectation.fulfill()
}
catch {
XCTFail()
}
},
failure: { _ in
@@ -631,17 +649,24 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
createExpectation.fulfill()
do {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
createExpectation.fulfill()
}
catch {
XCTFail()
}
},
failure: { _ in
@@ -655,7 +680,7 @@ final class TransactionTests: BaseTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
XCTFail()
try transaction.cancel()
@@ -669,17 +694,24 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
XCTAssertEqual(object?.testNumber, 200)
XCTAssertEqual(object?.testDate, Date.distantFuture)
updateExpectation.fulfill()
do {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
XCTAssertEqual(object?.testNumber, 200)
XCTAssertEqual(object?.testDate, Date.distantFuture)
updateExpectation.fulfill()
}
catch {
XCTFail()
}
},
failure: { _ in
@@ -693,7 +725,7 @@ final class TransactionTests: BaseTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
transaction.delete(object)
return transaction.hasChanges
@@ -701,11 +733,21 @@ final class TransactionTests: BaseTestCase {
success: { (hasChanges) in
XCTAssertTrue(hasChanges)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
deleteExpectation.fulfill()
do {
let configCount = try stack.fetchCount(From<TestEntity1>("Config1"))
XCTAssertEqual(configCount, 0)
let defaultCount = try stack.fetchCount(From<TestEntity1>(nil))
XCTAssertEqual(defaultCount, 0)
deleteExpectation.fulfill()
}
catch {
XCTFail()
}
},
failure: { _ in
@@ -754,8 +796,8 @@ final class TransactionTests: BaseTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(transaction.fetchOne(From<TestEntity1>()))
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>()))
let object = transaction.create(Into<TestEntity1>())
object.testEntityID = NSNumber(value: 1)
@@ -782,7 +824,7 @@ final class TransactionTests: BaseTestCase {
stack.perform(
asynchronous: { (transaction) -> Void in
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
return
@@ -811,9 +853,9 @@ final class TransactionTests: BaseTestCase {
stack.perform(
asynchronous: { (transaction) -> Void in
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
try transaction.cancel()
@@ -835,15 +877,22 @@ final class TransactionTests: BaseTestCase {
failure: { (error) in
XCTAssertEqual(error, CoreStoreError.userCancelled)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
deleteDiscardExpectation.fulfill()
do {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
XCTAssertEqual(object?.testNumber, 100)
XCTAssertEqual(object?.testDate, testDate)
deleteDiscardExpectation.fulfill()
}
catch {
XCTFail()
}
}
)
}
@@ -878,9 +927,9 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.fetchSource()?.unsafeContext(), stack.mainContext)
XCTAssertEqual(object?.querySource()?.unsafeContext(), stack.mainContext)
@@ -897,7 +946,7 @@ final class TransactionTests: BaseTestCase {
}
do {
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
return
@@ -911,9 +960,9 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
let object = stack.fetchOne(From<TestEntity1>())
let object = try stack.fetchOne(From<TestEntity1>())
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
@@ -927,7 +976,7 @@ final class TransactionTests: BaseTestCase {
}
do {
let object = transaction.fetchOne(From<TestEntity1>())
let object = try transaction.fetchOne(From<TestEntity1>())
transaction.delete(object)
do {
@@ -935,8 +984,8 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(stack.fetchOne(From<TestEntity1>()))
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(try stack.fetchOne(From<TestEntity1>()))
}
catch {
@@ -967,10 +1016,10 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1"))
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1")
@@ -984,7 +1033,7 @@ final class TransactionTests: BaseTestCase {
}
do {
guard let object = transaction.fetchOne(From<TestEntity1>("Config1")) else {
guard let object = try transaction.fetchOne(From<TestEntity1>("Config1")) else {
XCTFail()
return
@@ -998,10 +1047,10 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 1)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
let object = stack.fetchOne(From<TestEntity1>("Config1"))
let object = try stack.fetchOne(From<TestEntity1>("Config1"))
XCTAssertNotNil(object)
XCTAssertEqual(object?.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object?.testString, "string1_edit")
@@ -1015,7 +1064,7 @@ final class TransactionTests: BaseTestCase {
}
do {
let object = transaction.fetchOne(From<TestEntity1>("Config1"))
let object = try transaction.fetchOne(From<TestEntity1>("Config1"))
transaction.delete(object)
do {
@@ -1023,8 +1072,8 @@ final class TransactionTests: BaseTestCase {
XCTAssertTrue(transaction.hasChanges)
try transaction.commitAndWait()
XCTAssertEqual(stack.fetchCount(From<TestEntity1>("Config1")), 0)
XCTAssertEqual(stack.fetchCount(From<TestEntity1>(nil)), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>("Config1")), 0)
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>(nil)), 0)
}
catch {
@@ -1050,11 +1099,11 @@ final class TransactionTests: BaseTestCase {
transaction.rollback()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(transaction.fetchOne(From<TestEntity1>()))
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(try transaction.fetchOne(From<TestEntity1>()))
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(stack.fetchOne(From<TestEntity1>()))
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 0)
XCTAssertNil(try stack.fetchOne(From<TestEntity1>()))
}
let testDate = Date()
@@ -1079,7 +1128,7 @@ final class TransactionTests: BaseTestCase {
do {
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
return
@@ -1090,8 +1139,8 @@ final class TransactionTests: BaseTestCase {
transaction.rollback()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
if let object = transaction.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
if let object = try transaction.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1")
@@ -1103,8 +1152,8 @@ final class TransactionTests: BaseTestCase {
XCTFail()
}
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
if let object = stack.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
if let object = try stack.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1")
@@ -1119,7 +1168,7 @@ final class TransactionTests: BaseTestCase {
do {
guard let object = transaction.fetchOne(From<TestEntity1>()) else {
guard let object = try transaction.fetchOne(From<TestEntity1>()) else {
XCTFail()
return
@@ -1128,8 +1177,8 @@ final class TransactionTests: BaseTestCase {
transaction.rollback()
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 1)
if let object = transaction.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(try transaction.fetchCount(From<TestEntity1>()), 1)
if let object = try transaction.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1")
@@ -1141,8 +1190,8 @@ final class TransactionTests: BaseTestCase {
XCTFail()
}
XCTAssertEqual(stack.fetchCount(From<TestEntity1>()), 1)
if let object = stack.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(try stack.fetchCount(From<TestEntity1>()), 1)
if let object = try stack.fetchOne(From<TestEntity1>()) {
XCTAssertEqual(object.testEntityID, NSNumber(value: 1))
XCTAssertEqual(object.testString, "string1")

View File

@@ -43,7 +43,7 @@ final class TweakTests: XCTestCase {
$0.fetchLimit = 200
$0.predicate = predicate
}
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
tweak.applyToFetchRequest(request)
XCTAssertEqual(request.fetchOffset, 100)
XCTAssertEqual(request.fetchLimit, 200)

View File

@@ -56,6 +56,275 @@ final class WhereTests: XCTestCase {
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
XCTAssertEqual(String(keyPath: \TestEntity1.testEntityID), "testEntityID")
XCTAssertEqual(String(keyPath: \Animal.color), "color")
}
@objc
dynamic func test_ThatExpressions_HaveCorrectKeyPaths() {
do {
do {
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testEntityID),
(\TestEntity1.testToOne ~ \.testEntityID).description,
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
)
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered).description,
String(keyPath: \TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered)
)
XCTAssertEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).description,
String(keyPath: \TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered)
)
}
do {
XCTAssertEqual(
"master.pets",
(\Animal.master ~ \.pets).description,
String(keyPath: \Animal.master ~ \.pets)
)
XCTAssertEqual(
"master.pets.species",
(\Animal.master ~ \.pets ~ \.species).description,
String(keyPath: \Animal.master ~ \.pets ~ \.species)
)
XCTAssertEqual(
"master.pets.master",
(\Animal.master ~ \.pets ~ \.master).description,
String(keyPath: \Animal.master ~ \.pets ~ \.master)
)
}
}
do {
do {
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testToManyUnordered) + ".@count",
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).count())
)
XCTAssertEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered) + ".@count",
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count())
)
}
do {
XCTAssertEqual(
"master.pets.@count",
(\Animal.master ~ \.pets).count().description,
String(keyPath: (\Animal.master ~ \.pets).count())
)
}
}
do {
do {
XCTAssertEqual(
"ANY " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).any())
)
XCTAssertEqual(
"ANY " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any())
)
}
do {
XCTAssertEqual(
"ANY master.pets",
(\Animal.master ~ \.pets).any().description,
String(keyPath: (\Animal.master ~ \.pets).any())
)
XCTAssertEqual(
"ANY master.pets.species",
(\Animal.master ~ \.pets ~ \.species).any().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).any())
)
}
}
do {
do {
XCTAssertEqual(
"ALL " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).all())
)
XCTAssertEqual(
"ALL " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all())
)
}
do {
XCTAssertEqual(
"ALL master.pets",
(\Animal.master ~ \.pets).all().description,
String(keyPath: (\Animal.master ~ \.pets).all())
)
XCTAssertEqual(
"ALL master.pets.species",
(\Animal.master ~ \.pets ~ \.species).all().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).all())
)
}
}
do {
do {
XCTAssertEqual(
"NONE " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).none())
)
XCTAssertEqual(
"NONE " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none())
)
}
do {
XCTAssertEqual(
"NONE master.pets",
(\Animal.master ~ \.pets).none().description,
String(keyPath: (\Animal.master ~ \.pets).none())
)
XCTAssertEqual(
"NONE master.pets.species",
(\Animal.master ~ \.pets ~ \.species).none().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).none())
)
}
}
}
@objc
dynamic func test_ThatWhereClauses_CanBeCreatedFromExpressionsCorrectly() {
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testString) == dummy
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.name) == dummy
let predicate = NSPredicate(format: "master.name == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToOne ~ \.testString) == dummy
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToOne.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.spouse ~ \.name) == dummy
let predicate = NSPredicate(format: "master.spouse.name == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let count = 3
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered).count() == count
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToManyUnordered)).@count == %d", count)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets).count() == count
let predicate = NSPredicate(format: "master.pets.@count == %d", count)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).any() == dummy
let predicate = NSPredicate(format: "ANY \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).any() == dummy
let predicate = NSPredicate(format: "ANY master.pets.species == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).all() == dummy
let predicate = NSPredicate(format: "ALL \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).all() == dummy
let predicate = NSPredicate(format: "ALL master.pets.species == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).none() == dummy
let predicate = NSPredicate(format: "NONE \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).none() == dummy
let predicate = NSPredicate(format: "NONE master.pets.species == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
}
@objc
@@ -314,7 +583,7 @@ final class WhereTests: XCTestCase {
dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() {
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
whereClause.applyToFetchRequest(request)
XCTAssertNotNil(request.predicate)
XCTAssertEqual(request.predicate, whereClause.predicate)

View File

@@ -1,3 +1,4 @@
// swift-tools-version:4.2
//
// Package.swift
// CoreStore
@@ -25,21 +26,18 @@
import PackageDescription
let targets: [Target]
#if os(iOS)
targets = [Target(name: "CoreStore iOS")]
#elseif os(macOS)
targets = [Target(name: "CoreStore OSX")]
#elseif os(watchOS)
targets = [Target(name: "CoreStore watchOS")]
#elseif os(tvOS)
targets = [Target(name: "CoreStore tvOS")]
#else
targets = []
#endif
let package = Package(
name: "CoreStore",
targets: targets,
exclude: ["Carthage", "CoreStoreDemo", "Sources/libA/images"]
products: [
.library(name: "CoreStore", type: .static, targets: ["CoreStore"])
],
dependencies: [],
targets: [
.target(
name: "CoreStore",
dependencies: [],
path: "Sources",
exclude: ["CoreStoreBridge.h", "CoreStoreBridge.m"]
)
]
)

View File

@@ -0,0 +1,79 @@
import UIKit
import CoreStore
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
/// Model Declaration =====
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "Swift")
let master = Relationship.ToOne<Person>("master")
let color = Transformable.Optional<UIColor>("color", initial: .orange)
}
class Person: CoreStoreObject {
let name = Value.Optional<String>("name")
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
}
/// =======================
/// Stack setup ===========
let dataStack = DataStack(
CoreStoreSchema(
modelVersion: "V1",
entities: [
Entity<Animal>("Animal"),
Entity<Person>("Person")
]
)
)
dataStack.addStorage(
SQLiteStore(fileName: "data.sqlite"),
completion: { result in
switch result {
case .failure(let error):
print(error)
case .success:
/// Transactions ==========
dataStack.perform(
asynchronous: { transaction in
let animal = transaction.create(Into<Animal>())
animal.species .= "Sparrow"
animal.color .= .yellow
let person = transaction.create(Into<Person>())
person.name .= "John"
person.pets.value.insert(animal)
},
completion: { result in
switch result {
case .failure(let error):
print(error)
case .success:
/// Accessing Objects =====
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
print(bird.species.value)
print(bird.color.value as Any)
print(bird)
let owner = bird.master.value!
print(owner.name.value as Any)
print(owner.pets.count)
print(owner)
/// =======================
}
}
)
/// =======================
}
}
)

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' executeOnSourceChanges='false'>
<timeline fileName='timeline.xctimeline'/>
</playground>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
</Workspace>

View File

@@ -0,0 +1,77 @@
import AppKit
import CoreStore
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
/// Model Declaration =====
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "Swift")
let master = Relationship.ToOne<Person>("master")
let color = Transformable.Optional<NSColor>("color", initial: .orange)
}
class Person: CoreStoreObject {
let name = Value.Optional<String>("name")
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
}
/// =======================
/// Stack setup ===========
let dataStack = DataStack(
CoreStoreSchema(
modelVersion: "V1",
entities: [
Entity<Animal>("Animal"),
Entity<Person>("Person")
]
)
)
dataStack.addStorage(
SQLiteStore(fileName: "data.sqlite"),
completion: { result in
switch result {
case .failure(let error):
print(error)
case .success:
/// Transactions ==========
dataStack.perform(
asynchronous: { transaction in
let animal = transaction.create(Into<Animal>())
animal.species .= "Sparrow"
animal.color .= .yellow
let person = transaction.create(Into<Person>())
person.name .= "John"
person.pets.value.insert(animal)
},
completion: { result in
switch result {
case .failure(let error):
print(error)
case .success:
/// Accessing Objects =====
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
print(bird.species.value)
print(bird.color.value as Any)
print(bird)
let owner = bird.master.value!
print(owner.name.value as Any)
print(owner.pets.count)
print(owner)
/// =======================
}
}
)
/// =======================
}
}
)

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
<timeline fileName='timeline.xctimeline'/>
</playground>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

115
README.md
View File

@@ -6,22 +6,23 @@ Unleashing the real power of Core Data with the elegance and safety of Swift
<br />
<br />
<a href="https://travis-ci.org/JohnEstropia/CoreStore"><img alt="Build Status" src="https://img.shields.io/travis/JohnEstropia/CoreStore/master.svg?style=flat" /></a>
<a href="https://github.com/JohnEstropia/CoreStore/commits"><img alt="Last Commit" src="https://img.shields.io/github/last-commit/johnestropia/corestore.svg?style=flat" /></a>
<a href="http://cocoadocs.org/docsets/CoreStore"><img alt="Platform" src="https://img.shields.io/cocoapods/p/CoreStore.svg?style=flat" /></a>
<a href="https://raw.githubusercontent.com/JohnEstropia/CoreStore/master/LICENSE"><img alt="License" src="https://img.shields.io/cocoapods/l/CoreStore.svg?style=flat" /></a>
<br /><br />Dependency managers<br />
<a href="https://cocoapods.org/pods/CoreStore"><img alt="Cocoapods compatible" src="https://img.shields.io/cocoapods/v/CoreStore.svg?style=flat&label=Cocoapods" /></a>
<a href="https://github.com/Carthage/Carthage"><img alt="Carthage compatible" src="https://img.shields.io/badge/Carthage-compatible-16a085.svg?style=flat" /></a>
<a href="https://swiftpkgs.ng.bluemix.net/package/JohnEstropia/CoreStore"><img alt="Swift Package Manager compatible" src="https://img.shields.io/badge/Swift_Package_Manager-compatible-orange.svg?style=flat" /></a>
<a href="https://swift.org/source-compatibility/#current-list-of-projects"><img alt="Swift Package Manager compatible" src="https://img.shields.io/badge/Swift_Package_Manager-compatible-orange.svg?style=flat" /></a>
<br /><br />Contact<br />
<a href="http://swift-corestore-slack.herokuapp.com/"><img alt="Join us on Slack!" src="http://swift-corestore-slack.herokuapp.com/badge.svg" /></a>
<a href="https://twitter.com/JohnEstropia"><img alt="Reach me on Twitter!" src="https://img.shields.io/badge/twitter-%40JohnEstropia-3498db.svg" /></a>
<br />
</p>
* **Swift 4.2:** iOS 9+ / macOS 10.10+ / watchOS 2.0+ / tvOS 9.0+
* **Swift 4.2:** iOS 10+ / macOS 10.12+ / watchOS 3.0+ / tvOS 10.0+
* Other Swift versions: [Swift 3.2(version 4.2.3)](https://github.com/JohnEstropia/CoreStore/tree/4.2.3)
Upgrading from CoreStore 4.2 (Swift 3.2) to 5.x (Swift 4.x)? Check out the [new features](#features) and make sure to read the [Change logs](https://github.com/JohnEstropia/CoreStore/releases).
Upgrading from CoreStore 5.x (min iOS 9) to 6.x (min iOS 10)? Check out the [new features](#features) and make sure to read the [Change logs](https://github.com/JohnEstropia/CoreStore/releases).
CoreStore is now part of the [Swift Source Compatibility projects](https://swift.org/source-compatibility/#current-list-of-projects).
@@ -64,7 +65,7 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
- [Starting migrations](#starting-migrations)
- [Progressive migrations](#progressive-migrations)
- [Forecasting migrations](#forecasting-migrations)
- [Custom migratoins](#custom-migrations)
- [Custom migrations](#custom-migrations)
- [Saving and processing transactions](#saving-and-processing-transactions)
- [Transaction types](#transaction-types)
- [Asynchronous transactions](#asynchronous-transactions)
@@ -86,6 +87,7 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
- [`GroupBy` clause](#groupby-clause)
- [Logging and error reporting](#logging-and-error-reporting)
- [Observing changes and notifications](#observing-changes-and-notifications)
- [Observe a single property](#observe-a-single-property)
- [Observe a single object](#observe-a-single-object)
- [Observe a list of objects](#observe-a-list-of-objects)
- [Objective-C support](#objective-c-support)
@@ -139,12 +141,12 @@ CoreStore.perform(
Fetching objects (simple):
```swift
let people = CoreStore.fetchAll(From<MyPersonEntity>())
let people = try CoreStore.fetchAll(From<MyPersonEntity>())
```
Fetching objects (complex):
```swift
let people = CoreStore.fetchAll(
let people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30),
.orderBy(.ascending(\.name), .descending(.\age)),
@@ -154,7 +156,7 @@ let people = CoreStore.fetchAll(
Querying values:
```swift
let maxAge = CoreStore.queryValue(
let maxAge = try CoreStore.queryValue(
From<MyPersonEntity>()
.select(Int.self, .maximum(\.age))
)
@@ -851,7 +853,7 @@ To update an existing object, fetch the object's instance from the transaction:
```swift
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let person = transaction.fetchOne(
let person = try transaction.fetchOne(
From<MyPersonEntity>()
.where(\.name == "Jane Smith")
)
@@ -913,8 +915,8 @@ let jane: MyPersonEntity = // ...
CoreStore.perform(
asynchronous: { (transaction) -> Void in
transaction.delete(john, jane)
// transaction.delete([john, jane]) is also allowed
try transaction.delete(john, jane)
// try transaction.delete([john, jane]) is also allowed
},
completion: { _ in }
)
@@ -923,7 +925,7 @@ If you do not have references yet to the objects to be deleted, transactions hav
```swift
CoreStore.perform(
asynchronous: { (transaction) -> Void in
transaction.deleteAll(
try transaction.deleteAll(
From<MyPersonEntity>()
.where(\.age > 30)
)
@@ -971,7 +973,7 @@ var peopleIDs: [NSManagedObjectID] = // ...
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let jane = transaction.fetchOne(
let jane = try transaction.fetchOne(
From<MyPersonEntity>()
.where(\.name == "Jane Smith")
)
@@ -1184,17 +1186,17 @@ Before we dive in, be aware that CoreStore distinguishes between *fetching* and
#### `From` clause
The search conditions for fetches and queries are specified using *clauses*. All fetches and queries require a `From` clause that indicates the target entity type:
```swift
let people = CoreStore.fetchAll(From<MyPersonEntity>())
let people = try CoreStore.fetchAll(From<MyPersonEntity>())
```
`people` in the example above will be of type `[MyPersonEntity]`. The `From<MyPersonEntity>()` clause indicates a fetch to all persistent stores that `MyPersonEntity` belong to.
If the entity exists in multiple configurations and you need to only search from a particular configuration, indicate in the `From` clause the configuration name for the destination persistent store:
```swift
let people = CoreStore.fetchAll(From<MyPersonEntity>("Config1")) // ignore objects in persistent stores other than the "Config1" configuration
let people = try CoreStore.fetchAll(From<MyPersonEntity>("Config1")) // ignore objects in persistent stores other than the "Config1" configuration
```
or if the persistent store is the auto-generated "Default" configuration, specify `nil`:
```swift
let person = CoreStore.fetchAll(From<MyPersonEntity>(nil))
let person = try CoreStore.fetchAll(From<MyPersonEntity>(nil))
```
Now we know how to use a `From` clause, let's move on to fetching and querying.
@@ -1214,11 +1216,11 @@ Each method's purpose is straightforward, but we need to understand how to set t
The `Where` clause is CoreStore's `NSPredicate` wrapper. It specifies the search filter to use when fetching (or querying). It implements all initializers that `NSPredicate` does (except for `-predicateWithBlock:`, which Core Data does not support):
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
Where<MyPersonEntity>("%K > %d", "age", 30) // string format initializer
)
people = CoreStore.fetchAll(
people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
Where<MyPersonEntity>(true) // boolean initializer
)
@@ -1233,14 +1235,14 @@ var people = CoreStore.fetchAll(
```
Starting CoreStore 5.0, `Where` clauses became more type-safe and are now generic types. To avoid verbose repetition of the generic object type, fetch methods now support **Fetch Chain builders**. We can also use Swift's Smart KeyPaths as the `Where` clause expression:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30) // Type-safe!
)
```
`Where` clauses also implement the `&&`, `||`, and `!` logic operators, so you can provide logical conditions without writing too much `AND`, `OR`, and `NOT` strings:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30 && \.gender == "M")
)
@@ -1251,7 +1253,7 @@ If you do not provide a `Where` clause, all objects that belong to the specified
The `OrderBy` clause is CoreStore's `NSSortDescriptor` wrapper. Use it to specify attribute keys in which to sort the fetch (or query) results with.
```swift
var mostValuablePeople = CoreStore.fetchAll(
var mostValuablePeople = try CoreStore.fetchAll(
From<MyPersonEntity>(),
OrderBy<MyPersonEntity>(.descending("rating"), .ascending("surname"))
)
@@ -1259,7 +1261,7 @@ var mostValuablePeople = CoreStore.fetchAll(
As seen above, `OrderBy` accepts a list of `SortKey` enumeration values, which can be either `.ascending` or `.descending`.
As with `Where` clauses, CoreStore 5.0 turned `OrderBy` clauses into generic types. To avoid verbose repetition of the generic object type, fetch methods now support **Fetch Chain builders**. We can also use Swift's Smart KeyPaths as the `OrderBy` clause expression:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.orderBy(.descending(\.rating), .ascending(\.surname)) // Type-safe!
)
@@ -1271,7 +1273,7 @@ var orderBy = OrderBy<MyPersonEntity>(.descending(\.rating))
if sortFromYoungest {
orderBy += OrderBy(.ascending(\.age))
}
var mostValuablePeople = CoreStore.fetchAll(
var mostValuablePeople = try CoreStore.fetchAll(
From<MyPersonEntity>(),
orderBy
)
@@ -1281,7 +1283,7 @@ var mostValuablePeople = CoreStore.fetchAll(
The `Tweak` clause lets you, uh, *tweak* the fetch (or query). `Tweak` exposes the `NSFetchRequest` in a closure where you can make changes to its properties:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
Where<MyPersonEntity>("age > %d", 30),
OrderBy<MyPersonEntity>(.ascending("surname")),
@@ -1294,7 +1296,7 @@ var people = CoreStore.fetchAll(
```
`Tweak` also supports **Fetch Chain builders**:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
.where(\.age > 30)
.orderBy(.ascending(\.surname))
@@ -1325,7 +1327,7 @@ Setting up the `From`, `Where`, `OrderBy`, and `Tweak` clauses is similar to how
The `Select<T>` clause specifies the target attribute/aggregate key, as well as the expected return type:
```swift
let johnsAge = CoreStore.queryValue(
let johnsAge = try CoreStore.queryValue(
From<MyPersonEntity>(),
Select<Int>("age"),
Where("name == %@", "John Smith")
@@ -1335,14 +1337,14 @@ The example above queries the "age" property for the first object that matches t
For `queryAttributes(...)`, only `NSDictionary` is valid for `Select`, thus you are allowed to omit the generic type:
```swift
let allAges = CoreStore.queryAttributes(
let allAges = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("age")
)
```
Starting CoreStore 5.0, query methods now support **Query Chain builders**. We can also use Swift's Smart KeyPaths to use in the expressions:
```swift
let johnsAge = CoreStore.queryValue(
let johnsAge = try CoreStore.queryValue(
From<MyPersonEntity>()
.select(\.age) // binds the result to Int
.where(\.name == "John Smith")
@@ -1357,7 +1359,7 @@ If you only need a value for a particular attribute, you can just specify the ke
- `.sum(...)`
```swift
let oldestAge = CoreStore.queryValue(
let oldestAge = try CoreStore.queryValue(
From<MyPersonEntity>(),
Select<Int>(.maximum("age"))
)
@@ -1365,7 +1367,7 @@ let oldestAge = CoreStore.queryValue(
For `queryAttributes(...)` which returns an array of dictionaries, you can specify multiple attributes/aggregates to `Select`:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("name", "age")
)
@@ -1385,7 +1387,7 @@ let personJSON = CoreStore.queryAttributes(
```
You can also include an aggregate as well:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("name", .count("friends"))
)
@@ -1405,7 +1407,7 @@ which returns:
```
The `"count(friends)"` key name was automatically used by CoreStore, but you can specify your own key alias if you need:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("name", .count("friends", as: "friendsCount"))
)
@@ -1428,7 +1430,7 @@ which now returns:
The `GroupBy` clause lets you group results by a specified attribute/aggregate. This is useful only for `queryAttributes(...)` since `queryValue(...)` just returns the first value.
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("age", .count("age", as: "count")),
GroupBy("age")
@@ -1436,7 +1438,7 @@ let personJSON = CoreStore.queryAttributes(
```
Starting CoreStore 5.0, `GroupBy` clauses are now also generic types and now support **Query Chain builders**. We can also use Swift's Smart KeyPaths to use in the expressions:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>()
.select(.attribute(\.age), .count(\.age, as: "count"))
.groupBy(\.age)
@@ -1491,16 +1493,35 @@ A couple of examples, `ListMonitor`:
These are all implemented with `CustomDebugStringConvertible.debugDescription`, so they work with lldb's `po` command as well.
## Observing changes and notifications
> (unavailable on macOS versions below 10.12)
CoreStore provides type-safe wrappers for observing managed objects:
- `ObjectMonitor`: use to monitor changes to a single `NSManagedObject` or `CoreStoreObject` instance (instead of Key-Value Observing)
- `ListMonitor`: use to monitor changes to a list of `NSManagedObject` or `CoreStoreObject` instances (instead of `NSFetchedResultsController`)
### Observe a single property
To get notifications for single property changes in an object, there are two methods depending on the object's base class.
- For `NSManagedObject` subclasses: Use the standard KVO method:
```swift
let observer = person.observe(\.age, options: [.new]) { (person, change)
print("Happy \(change.newValue)th birthday!")
}
```
- For `CoreStoreObject` subclasses: Call the `observe(...)` method directly on the property. You'll notice that the API itself is a bit similar to the KVO method:
```swift
let observer = person.age.observe(options: [.new]) { (person, change)
print("Happy \(change.newValue)th birthday!")
}
```
For both methods, you will need to keep a reference to the returned `observer` for the duration of the observation.
### Observe a single object
To observe an object, implement the `ObjectObserver` protocol and specify the `EntityType`:
To observe an object itself as a whole, implement the `ObjectObserver` protocol and specify the `EntityType`:
```swift
class MyViewController: UIViewController, ObjectObserver {
func objectMonitor(monitor: ObjectMonitor<MyPersonEntity>, willUpdateObject object: MyPersonEntity) {
@@ -1796,7 +1817,7 @@ let keyPath: String = Dog.keyPath { $0.nickname }
```
as well as `Where` and `OrderBy` clauses
```swift
let puppies = CoreStore.fetchAll(
let puppies = try CoreStore.fetchAll(
From<Dog>()
.where(\.age < 1)
.orderBy(.ascending(\.age))
@@ -1841,8 +1862,8 @@ Once the version lock is set, any changes in the properties or to the model will
# Installation
- Requires:
- iOS 8 SDK and above
- Swift 4 (Xcode 9+)
- iOS 10 SDK and above
- Swift 4.2 (Xcode 10+)
- Dependencies:
- *None*
- Other notes:
@@ -1851,7 +1872,7 @@ Once the version lock is set, any changes in the properties or to the model will
### Install with CocoaPods
In your `Podfile`, add
```
pod 'CoreStore', '~> 5.0'
pod 'CoreStore', '~> 6.1'
```
and run
```
@@ -1862,7 +1883,7 @@ This installs CoreStore as a framework. Declare `import CoreStore` in your swift
### Install with Carthage
In your `Cartfile`, add
```
github "JohnEstropia/CoreStore" >= 5.0.0
github "JohnEstropia/CoreStore" >= 6.2.1
```
and run
```
@@ -1870,18 +1891,20 @@ carthage update
```
This installs CoreStore as a framework. Declare `import CoreStore` in your swift file to use the library.
#### Install with Swift Package Manager:
```swift
dependencies: [
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "6.2.1"))
]
```
Declare `import CoreStore` in your swift file to use the library.
### Install as Git Submodule
```
git submodule add https://github.com/JohnEstropia/CoreStore.git <destination directory>
```
Drag and drop **CoreStore.xcodeproj** to your project.
#### To install as a framework:
Drag and drop **CoreStore.xcodeproj** to your project.
#### To include directly in your app module:
Add all *.swift* files to your project.
### Objective-C support

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - BaseDataTransaction
public extension BaseDataTransaction {
extension BaseDataTransaction {
/**
Creates an `ImportableObject` by importing from the specified import source.
@@ -151,7 +151,7 @@ public extension BaseDataTransaction {
return nil
}
if let object = self.fetchOne(From(entityType), Where<D>(uniqueIDKeyPath, isEqualTo: uniqueIDValue)) {
if let object = try self.fetchOne(From(entityType), Where<D>(uniqueIDKeyPath, isEqualTo: uniqueIDValue)) {
guard entityType.shouldUpdate(from: source, in: self) else {
@@ -215,7 +215,8 @@ public extension BaseDataTransaction {
importSourceByID = try autoreleasepool { try preProcess(importSourceByID) }
var existingObjectsByID = Dictionary<D.UniqueIDType, D>()
self.fetchAll(From(entityType), Where<D>(entityType.uniqueIDKeyPath, isMemberOf: sortedIDs))?
try self
.fetchAll(From(entityType), Where<D>(entityType.uniqueIDKeyPath, isMemberOf: sortedIDs))
.forEach { existingObjectsByID[$0.uniqueIDValue] = $0 }
var processedObjectIDs = Set<D.UniqueIDType>()

View File

@@ -39,13 +39,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- returns: the number of `DynamicObject`s deleted
*/
@discardableResult
public func deleteAll<D>(_ from: From<D>, _ deleteClauses: DeleteClause...) -> Int? {
public func deleteAll<D>(_ from: From<D>, _ deleteClauses: DeleteClause...) throws -> Int {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to delete from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.deleteAll(from, deleteClauses)
return try self.context.deleteAll(from, deleteClauses)
}
/**
@@ -56,13 +56,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- returns: the number of `DynamicObject`s deleted
*/
@discardableResult
public func deleteAll<D>(_ from: From<D>, _ deleteClauses: [DeleteClause]) -> Int? {
public func deleteAll<D>(_ from: From<D>, _ deleteClauses: [DeleteClause]) throws -> Int {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to delete from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.deleteAll(from, deleteClauses)
return try self.context.deleteAll(from, deleteClauses)
}
/**
@@ -74,14 +74,14 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- returns: the number of `DynamicObject`s deleted
*/
@discardableResult
public func deleteAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
public func deleteAll<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> Int {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to delete from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.deleteAll(clauseChain.from, clauseChain.fetchClauses)
return try self.context.deleteAll(clauseChain.from, clauseChain.fetchClauses)
}
@@ -136,15 +136,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> D? {
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> D? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchOne(from, fetchClauses)
return try self.context.fetchOne(from, fetchClauses)
}
/**
@@ -152,15 +153,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> D? {
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> D? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchOne(from, fetchClauses)
return try self.context.fetchOne(from, fetchClauses)
}
/**
@@ -173,15 +175,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) -> B.ObjectType? {
public func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> B.ObjectType? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchOne(clauseChain)
return try self.context.fetchOne(clauseChain)
}
/**
@@ -189,15 +192,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [D]? {
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [D] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchAll(from, fetchClauses)
return try self.context.fetchAll(from, fetchClauses)
}
/**
@@ -205,15 +209,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [D]? {
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [D] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchAll(from, fetchClauses)
return try self.context.fetchAll(from, fetchClauses)
}
/**
@@ -226,15 +231,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]? {
public func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [B.ObjectType] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchAll(clauseChain)
return try self.context.fetchAll(clauseChain)
}
/**
@@ -242,15 +248,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> Int? {
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> Int {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchCount(from, fetchClauses)
return try self.context.fetchCount(from, fetchClauses)
}
/**
@@ -258,15 +265,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> Int? {
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> Int {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchCount(from, fetchClauses)
return try self.context.fetchCount(from, fetchClauses)
}
/**
@@ -279,15 +287,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the number `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
public func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> Int {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchCount(clauseChain)
return try self.context.fetchCount(clauseChain)
}
/**
@@ -295,15 +304,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> NSManagedObjectID? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchObjectID(from, fetchClauses)
return try self.context.fetchObjectID(from, fetchClauses)
}
/**
@@ -311,15 +321,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> NSManagedObjectID? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchObjectID(from, fetchClauses)
return try self.context.fetchObjectID(from, fetchClauses)
}
/**
@@ -332,15 +343,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) -> NSManagedObjectID? {
public func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> NSManagedObjectID? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchObjectID(clauseChain)
return try self.context.fetchObjectID(clauseChain)
}
/**
@@ -348,15 +360,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [NSManagedObjectID] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchObjectIDs(from, fetchClauses)
return try self.context.fetchObjectIDs(from, fetchClauses)
}
/**
@@ -364,15 +377,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [NSManagedObjectID] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchObjectIDs(from, fetchClauses)
return try self.context.fetchObjectIDs(from, fetchClauses)
}
/**
@@ -385,15 +399,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) -> [NSManagedObjectID]? {
public func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [NSManagedObjectID] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.fetchObjectIDs(clauseChain)
return try self.context.fetchObjectIDs(clauseChain)
}
@@ -407,15 +422,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- returns: the result of the the query, or `nil` if no match was found. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) -> U? {
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) throws -> U? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.queryValue(from, selectClause, queryClauses)
return try self.context.queryValue(from, selectClause, queryClauses)
}
/**
@@ -426,15 +442,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- returns: the result of the the query, or `nil` if no match was found. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) -> U? {
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) throws -> U? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.queryValue(from, selectClause, queryClauses)
return try self.context.queryValue(from, selectClause, queryClauses)
}
/**
@@ -449,15 +466,16 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `QueryChainableBuilderType` indicating the property/aggregate to fetch and the series of queries for the request.
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
- returns: the result of the the query as specified by the `QueryChainableBuilderType`, or `nil` if no match was found.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) -> B.ResultType? where B.ResultType: QueryableAttributeType {
public func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) throws -> B.ResultType? where B.ResultType: QueryableAttributeType {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
return try self.context.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
/**
@@ -469,14 +487,15 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- 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.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) throws -> [[String: Any]] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.queryAttributes(from, selectClause, queryClauses)
return try self.context.queryAttributes(from, selectClause, queryClauses)
}
/**
@@ -488,14 +507,15 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- 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.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) throws -> [[String: Any]] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.queryAttributes(from, selectClause, queryClauses)
return try self.context.queryAttributes(from, selectClause, queryClauses)
}
/**
@@ -520,14 +540,15 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
```
- parameter clauseChain: a `QueryChainableBuilderType` indicating the properties to fetch and the series of queries for the request.
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) -> [[String: Any]]? where B.ResultType == NSDictionary {
public func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) throws -> [[String: Any]] where B.ResultType == NSDictionary {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.context.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
return try self.context.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
@@ -544,7 +565,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
// MARK: Obsoleted
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
@available(swift, obsoleted: 3.1, renamed: "unsafeContext()")
public func internalContext() -> NSManagedObjectContext {
fatalError()

View File

@@ -223,7 +223,7 @@ public /*abstract*/ class BaseDataTransaction {
public func insertedObjects<D: DynamicObject>(_ entity: D.Type) -> Set<D> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access inserted objects from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -241,7 +241,7 @@ public /*abstract*/ class BaseDataTransaction {
public func insertedObjectIDs() -> Set<NSManagedObjectID> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access inserted object IDs from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -260,7 +260,7 @@ public /*abstract*/ class BaseDataTransaction {
public func insertedObjectIDs<D: DynamicObject>(_ entity: D.Type) -> Set<NSManagedObjectID> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access inserted object IDs from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -279,7 +279,7 @@ public /*abstract*/ class BaseDataTransaction {
public func updatedObjects<D: DynamicObject>(_ entity: D.Type) -> Set<D> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access updated objects from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -297,7 +297,7 @@ public /*abstract*/ class BaseDataTransaction {
public func updatedObjectIDs() -> Set<NSManagedObjectID> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access updated object IDs from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -316,7 +316,7 @@ public /*abstract*/ class BaseDataTransaction {
public func updatedObjectIDs<D: DynamicObject>(_ entity: D.Type) -> Set<NSManagedObjectID> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access updated object IDs from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -335,7 +335,7 @@ public /*abstract*/ class BaseDataTransaction {
public func deletedObjects<D: DynamicObject>(_ entity: D.Type) -> Set<D> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access deleted objects from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -354,7 +354,7 @@ public /*abstract*/ class BaseDataTransaction {
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access deleted object IDs from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
@@ -373,7 +373,7 @@ public /*abstract*/ class BaseDataTransaction {
public func deletedObjectIDs<D: DynamicObject>(_ entity: D.Type) -> Set<NSManagedObjectID> {
CoreStore.assert(
self.transactionQueue.cs_isCurrentExecutionContext(),
self.isRunningInAllowedQueue(),
"Attempted to access deleted object IDs from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSBaseDataTransaction
public extension CSBaseDataTransaction {
extension CSBaseDataTransaction {
/**
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
@@ -93,7 +93,8 @@ public extension CSBaseDataTransaction {
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.swiftTransaction.context.fetchOne(from, fetchClauses)
return (try? self.swiftTransaction.context.fetchOne(from, fetchClauses))?
.flatMap({ $0 })
}
/**
@@ -110,7 +111,8 @@ public extension CSBaseDataTransaction {
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.swiftTransaction.context.fetchAll(from, fetchClauses)
return (try? self.swiftTransaction.context.fetchAll(from, fetchClauses))
.flatMap({ $0 })
}
/**
@@ -127,9 +129,8 @@ public extension CSBaseDataTransaction {
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.swiftTransaction.context
.fetchCount(from, fetchClauses)
.flatMap { NSNumber(value: $0) }
return (try? self.swiftTransaction.context.fetchCount(from, fetchClauses))
.flatMap({ NSNumber(value: $0) })
}
/**
@@ -146,7 +147,8 @@ public extension CSBaseDataTransaction {
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.swiftTransaction.context.fetchObjectID(from, fetchClauses)
return (try? self.swiftTransaction.context.fetchObjectID(from, fetchClauses))
.flatMap({ $0 })
}
/**
@@ -166,7 +168,8 @@ public extension CSBaseDataTransaction {
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.swiftTransaction.context.queryValue(from, selectClause, queryClauses)
return (try? self.swiftTransaction.context.queryValue(from, selectClause, queryClauses))
.flatMap({ $0 })
}
/**
@@ -186,6 +189,7 @@ public extension CSBaseDataTransaction {
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.swiftTransaction.context.queryAttributes(from, selectClause, queryClauses)
return (try? self.swiftTransaction.context.queryAttributes(from, selectClause, queryClauses))
.flatMap({ $0 })
}
}

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Asynchronously adds a `CSInMemoryStore` to the `defaultStack`. Migrations are also initiated by default.

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - CSCoreStore
@available(macOS 10.12, *)
public extension CSCoreStore {
extension CSCoreStore {
/**
Using the `defaultStack`, creates an `CSObjectMonitor` for the specified `NSManagedObject`. Multiple `CSObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Using the `defaultStack`, fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Returns the `defaultStack`'s model version. The version string is the same as the name of the version-specific .xcdatamodeld file.

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Using the `defaultStack`, begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSDataStack
public extension CSDataStack {
extension CSDataStack {
/**
Asynchronously adds a `CSInMemoryStore` to the stack. Migrations are also initiated by default.

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - CSDataStack
@available(macOS 10.12, *)
public extension CSDataStack {
extension CSDataStack {
/**
Creates a `CSObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
@@ -68,7 +68,7 @@ public extension CSDataStack {
sectionBy: nil,
applyFetchClauses: { (fetchRequest) in
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
}
).bridgeToObjectiveC
}
@@ -97,7 +97,7 @@ public extension CSDataStack {
sectionBy: nil,
applyFetchClauses: { (fetchRequest) in
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
},
createAsynchronously: {
@@ -131,7 +131,7 @@ public extension CSDataStack {
sectionBy: sectionBy.bridgeToSwift,
applyFetchClauses: { (fetchRequest) in
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
}
).bridgeToObjectiveC
}
@@ -160,7 +160,7 @@ public extension CSDataStack {
sectionBy: sectionBy.bridgeToSwift,
applyFetchClauses: { (fetchRequest) in
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
},
createAsynchronously: {

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSDataStack
public extension CSDataStack {
extension CSDataStack {
/**
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
@@ -93,7 +93,8 @@ public extension CSDataStack {
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.bridgeToSwift.mainContext.fetchOne(from, fetchClauses)
return (try? self.bridgeToSwift.mainContext.fetchOne(from, fetchClauses))?
.flatMap({ $0 })
}
/**
@@ -110,7 +111,8 @@ public extension CSDataStack {
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.bridgeToSwift.mainContext.fetchAll(from, fetchClauses)
return (try? self.bridgeToSwift.mainContext.fetchAll(from, fetchClauses))
.flatMap({ $0 })
}
/**
@@ -127,9 +129,8 @@ public extension CSDataStack {
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.bridgeToSwift.mainContext
.fetchCount(from, fetchClauses)
.flatMap { NSNumber(value: $0) }
return (try? self.bridgeToSwift.mainContext.fetchCount(from, fetchClauses))
.flatMap({ NSNumber(value: $0) })
}
/**
@@ -146,7 +147,8 @@ public extension CSDataStack {
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.bridgeToSwift.mainContext.fetchObjectID(from, fetchClauses)
return (try? self.bridgeToSwift.mainContext.fetchObjectID(from, fetchClauses))?
.flatMap({ $0 })
}
/**
@@ -163,7 +165,8 @@ public extension CSDataStack {
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.bridgeToSwift.mainContext.fetchObjectIDs(from, fetchClauses)
return (try? self.bridgeToSwift.mainContext.fetchObjectIDs(from, fetchClauses))
.flatMap({ $0 })
}
/**
@@ -183,7 +186,8 @@ public extension CSDataStack {
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.bridgeToSwift.mainContext.queryValue(from, selectClause, queryClauses)
return (try? self.bridgeToSwift.mainContext.queryValue(from, selectClause, queryClauses))
.flatMap({ $0 })
}
/**
@@ -203,6 +207,7 @@ public extension CSDataStack {
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.bridgeToSwift.mainContext.queryAttributes(from, selectClause, queryClauses)
return (try? self.bridgeToSwift.mainContext.queryAttributes(from, selectClause, queryClauses))
.flatMap({ $0 })
}
}

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CSDataStack
public extension CSDataStack {
extension CSDataStack {
/**
Begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.

View File

@@ -50,7 +50,7 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`.
- parameter xcodeModelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
- parameter bundle: an optional bundle to load .xcdatamodeld 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

View File

@@ -217,6 +217,17 @@ extension CoreStoreError: CoreStoreSwiftType, _ObjectiveCBridgeableError {
return
}
self = .progressiveMigrationRequired(localStoreURL: localStoreURL)
case .asynchronousMigrationRequired:
guard
let localStoreURL = info["localStoreURL"] as? URL,
case let nsError as NSError = info["NSError"]
else {
self = .unknown
return
}
self = .asynchronousMigrationRequired(localStoreURL: localStoreURL, NSError: nsError)
case .internalError:
guard case let nsError as NSError = info["NSError"] else {
@@ -236,6 +247,14 @@ extension CoreStoreError: CoreStoreSwiftType, _ObjectiveCBridgeableError {
case .userCancelled:
self = .userCancelled
case .persistentStoreNotFound:
guard let entity = info["entity"] as? DynamicObject.Type else {
self = .unknown
return
}
self = .persistentStoreNotFound(entity: entity)
}
}
}
@@ -243,7 +262,7 @@ extension CoreStoreError: CoreStoreSwiftType, _ObjectiveCBridgeableError {
// MARK: Internal
internal extension Error {
extension Error {
internal var bridgeToSwift: CoreStoreError {

View File

@@ -132,7 +132,7 @@ public final class CSListMonitor: NSObject {
@objc
public func hasObjectsInSection(_ section: Int) -> Bool {
return self.bridgeToSwift.hasObjectsInSection(section)
return self.bridgeToSwift.hasObjects(in: section)
}
/**
@@ -155,7 +155,7 @@ public final class CSListMonitor: NSObject {
@objc
public func objectsInSection(_ section: Int) -> [NSManagedObject] {
return self.bridgeToSwift.objectsInSection(section)
return self.bridgeToSwift.objects(in: section)
}
/**
@@ -167,7 +167,7 @@ public final class CSListMonitor: NSObject {
@objc
public func objectsInSafeSection(safeSectionIndex section: Int) -> [NSManagedObject]? {
return self.bridgeToSwift.objectsInSection(safeSectionIndex: section)
return self.bridgeToSwift.objects(safelyIn: section)
}
/**
@@ -201,7 +201,7 @@ public final class CSListMonitor: NSObject {
@objc
public func numberOfObjectsInSection(_ section: Int) -> Int {
return self.bridgeToSwift.numberOfObjectsInSection(section)
return self.bridgeToSwift.numberOfObjects(in: section)
}
/**
@@ -214,7 +214,7 @@ public final class CSListMonitor: NSObject {
public func numberOfObjectsInSafeSection(safeSectionIndex section: Int) -> NSNumber? {
return self.bridgeToSwift
.numberOfObjectsInSection(safeSectionIndex: section)
.numberOfObjects(safelyIn: section)
.flatMap { NSNumber(value: $0) }
}
@@ -227,7 +227,7 @@ public final class CSListMonitor: NSObject {
@objc
public func sectionInfoAtIndex(_ section: Int) -> NSFetchedResultsSectionInfo {
return self.bridgeToSwift.sectionInfoAtIndex(section)
return self.bridgeToSwift.sectionInfo(at: section)
}
/**
@@ -239,7 +239,7 @@ public final class CSListMonitor: NSObject {
@objc
public func sectionInfoAtSafeSectionIndex(safeSectionIndex section: Int) -> NSFetchedResultsSectionInfo? {
return self.bridgeToSwift.sectionInfoAtIndex(safeSectionIndex: section)
return self.bridgeToSwift.sectionInfo(safelyAt: section)
}
/**
@@ -263,7 +263,7 @@ public final class CSListMonitor: NSObject {
@objc
public func targetSectionForSectionIndexTitle(title: String, index: Int) -> Int {
return self.bridgeToSwift.targetSectionForSectionIndex(title: title, index: index)
return self.bridgeToSwift.targetSection(forSectionIndexTitle: title, at: index)
}
/**
@@ -287,7 +287,7 @@ public final class CSListMonitor: NSObject {
public func indexOf(_ object: NSManagedObject) -> NSNumber? {
return self.bridgeToSwift
.indexOf(object)
.index(of: object)
.flatMap { NSNumber(value: $0) }
}
@@ -300,7 +300,7 @@ public final class CSListMonitor: NSObject {
@objc
public func indexPathOf(_ object: NSManagedObject) -> IndexPath? {
return self.bridgeToSwift.indexPathOf(object)
return self.bridgeToSwift.indexPath(of: object)
}
@@ -495,14 +495,15 @@ public final class CSListMonitor: NSObject {
`refetch(...)` broadcasts `listMonitorWillRefetch(...)` to its observers immediately, and then `listMonitorDidRefetch(...)` after the new fetch request completes.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses. Note that only specified clauses will be changed; unspecified clauses will use previous values.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
- Important: Starting CoreStore 4.0, all `CSFetchClause`s required by the `CSListMonitor` should be provided in the arguments list of `refetch(...)`.
*/
@objc
public func refetch(_ fetchClauses: [CSFetchClause]) {
self.bridgeToSwift.refetch { (fetchRequest) in
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
}
}

View File

@@ -195,14 +195,14 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
// MARK: Obsoleted
@available(*, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileURL:configuration:localStorageOptions:]) initializer instead.")
@available(swift, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileURL:configuration:localStorageOptions:]) initializer instead.")
@objc
public convenience init(fileURL: URL, configuration: ModelConfiguration, mappingModelBundles: [Bundle]?, localStorageOptions: Int) {
fatalError()
}
@available(*, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileName:configuration:localStorageOptions:]) initializer instead.")
@available(swift, 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) {

View File

@@ -137,6 +137,10 @@ extension CoreStoreError: CustomDebugStringConvertible, CoreStoreDebugStringConv
case .progressiveMigrationRequired(let localStoreURL):
firstLine = ".progressiveMigrationRequired"
info.append(("localStoreURL", localStoreURL))
case .asynchronousMigrationRequired(let localStoreURL):
firstLine = ".asynchronousMigrationRequired"
info.append(("localStoreURL", localStoreURL))
case .internalError(let NSError):
firstLine = ".internalError"
@@ -148,6 +152,10 @@ extension CoreStoreError: CustomDebugStringConvertible, CoreStoreDebugStringConv
case .userCancelled:
firstLine = ".userCancelled"
case .persistentStoreNotFound(let entity):
firstLine = ".persistentStoreNotFound"
info.append(("entity", entity))
}
return createFormattedString(
@@ -158,6 +166,30 @@ extension CoreStoreError: CustomDebugStringConvertible, CoreStoreDebugStringConv
}
// MARK: - CoreStoreObject
extension CoreStoreObject: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return formattedDebugDescription(self)
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
return createFormattedString(
"(", ")",
("rawObject", self.rawObject as Any)
)
}
}
// MARK: - CoreStoreSchema
extension CoreStoreSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
@@ -292,37 +324,6 @@ extension GroupBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertible
}
#if os(iOS) || os(macOS)
// MARK: - ICloudStore
extension ICloudStore: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return formattedDebugDescription(self)
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
return createFormattedString(
"(", ")",
("configuration", self.configuration as Any),
("storeOptions", self.storeOptions as Any),
("cacheFileURL", self.cacheFileURL),
("cloudStorageOptions", self.cloudStorageOptions)
)
}
}
#endif
// MARK: - InMemoryStore
extension InMemoryStore: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
@@ -658,6 +659,30 @@ extension OrderBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertible
}
// MARK: - PartialObject
extension PartialObject: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return formattedDebugDescription(self)
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
return createFormattedString(
"(", ")",
("rawObject", self.rawObject as Any)
)
}
}
// MARK: - SaveResult
@available(*, deprecated, message: "Use the new DataStack.perform(asynchronous:...) and DataStack.perform(synchronous:...) family of APIs")
@@ -1086,7 +1111,7 @@ private func createFormattedString(_ firstLine: String, _ lastLine: String, _ in
return string
}
fileprivate extension String {
extension String {
fileprivate static func indention(_ level: Int = 1) -> String {
@@ -1207,6 +1232,8 @@ extension NSAttributeType: CoreStoreDebugStringConvertible {
case .objectIDAttributeType: return ".objectIDAttributeType"
case .UUIDAttributeType: return ".UUIDAttributeType"
case .URIAttributeType: return ".URIAttributeType"
@unknown default:
fatalError()
}
}
}
@@ -1229,6 +1256,8 @@ extension NSDeleteRule: CoreStoreDebugStringConvertible {
case .nullifyDeleteRule: return ".nullifyDeleteRule"
case .cascadeDeleteRule: return ".cascadeDeleteRule"
case .denyDeleteRule: return ".denyDeleteRule"
@unknown default:
fatalError()
}
}
}
@@ -1257,7 +1286,10 @@ extension NSEntityDescription: CoreStoreDebugStringConvertible {
info.append(("compoundIndexes", self.compoundIndexes))
}
info.append(("uniquenessConstraints", self.uniquenessConstraints))
if #available(macOS 10.11, *) {
info.append(("uniquenessConstraints", self.uniquenessConstraints))
}
return createFormattedString(
"(", ")",
info

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
The `CoreStoreLogger` instance to be used. The default logger is an instance of a `DefaultLogger`.
@@ -66,8 +66,8 @@ public extension CoreStore {
internal static func assert( _ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
self.logger.assert(
condition,
message: message,
condition(),
message: message(),
fileName: fileName,
lineNumber: lineNumber,
functionName: functionName

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Asynchronously adds a `StorageInterface` to the `defaultStack`. Migrations are also initiated by default.

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - CoreStore
@available(macOS 10.12, *)
public extension CoreStore {
extension CoreStore {
/**
Using the `defaultStack`, creates an `ObjectMonitor` for the specified `DynamicObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `DynamicObject`.
@@ -113,7 +113,7 @@ public extension CoreStore {
```
CoreStore.monitorList(
{ (monitor) in
createAsynchronously: { (monitor) in
self.monitor = monitor
},
From<MyPersonEntity>()
@@ -123,7 +123,6 @@ public extension CoreStore {
```
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
*/
public static func monitorList<B: FetchChainableBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {
@@ -212,7 +211,7 @@ public extension CoreStore {
Asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType` built from a chain of clauses.
```
CoreStore.monitorSectionedList(
{ (monitor) in
createAsynchronously: { (monitor) in
self.monitor = monitor
},
From<MyPersonEntity>()
@@ -221,8 +220,8 @@ public extension CoreStore {
.orderBy(.ascending(\.age))
)
```
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter clauseChain: a `SectionMonitorBuilderType` built from a chain of clauses
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType`
*/
public static func monitorSectionedList<B: SectionMonitorBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Using the `defaultStack`, fetches the `DynamicObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.
@@ -80,11 +80,12 @@ public extension CoreStore {
- 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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> D? {
public static func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> D? {
return self.defaultStack.fetchOne(from, fetchClauses)
return try self.defaultStack.fetchOne(from, fetchClauses)
}
/**
@@ -92,11 +93,12 @@ public extension CoreStore {
- 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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> D? {
public static func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> D? {
return self.defaultStack.fetchOne(from, fetchClauses)
return try self.defaultStack.fetchOne(from, fetchClauses)
}
/**
@@ -109,11 +111,12 @@ public extension CoreStore {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) -> B.ObjectType? {
public static func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> B.ObjectType? {
return self.defaultStack.fetchOne(clauseChain)
return try self.defaultStack.fetchOne(clauseChain)
}
/**
@@ -121,11 +124,12 @@ public extension CoreStore {
- 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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [D]? {
public static func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [D] {
return self.defaultStack.fetchAll(from, fetchClauses)
return try self.defaultStack.fetchAll(from, fetchClauses)
}
/**
@@ -133,11 +137,12 @@ public extension CoreStore {
- 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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [D]? {
public static func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [D] {
return self.defaultStack.fetchAll(from, fetchClauses)
return try self.defaultStack.fetchAll(from, fetchClauses)
}
/**
@@ -150,11 +155,12 @@ public extension CoreStore {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]? {
public static func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [B.ObjectType] {
return self.defaultStack.fetchAll(clauseChain)
return try self.defaultStack.fetchAll(clauseChain)
}
/**
@@ -162,11 +168,12 @@ public extension CoreStore {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> Int? {
public static func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> Int {
return self.defaultStack.fetchCount(from, fetchClauses)
return try self.defaultStack.fetchCount(from, fetchClauses)
}
/**
@@ -174,11 +181,12 @@ public extension CoreStore {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> Int? {
public static func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> Int {
return self.defaultStack.fetchCount(from, fetchClauses)
return try self.defaultStack.fetchCount(from, fetchClauses)
}
/**
@@ -191,11 +199,12 @@ public extension CoreStore {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the number `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
public static func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> Int {
return self.defaultStack.fetchCount(clauseChain)
return try self.defaultStack.fetchCount(clauseChain)
}
/**
@@ -203,11 +212,12 @@ public extension CoreStore {
- 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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
public static func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> NSManagedObjectID? {
return self.defaultStack.fetchObjectID(from, fetchClauses)
return try self.defaultStack.fetchObjectID(from, fetchClauses)
}
/**
@@ -215,11 +225,12 @@ public extension CoreStore {
- 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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
public static func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> NSManagedObjectID? {
return self.defaultStack.fetchObjectID(from, fetchClauses)
return try self.defaultStack.fetchObjectID(from, fetchClauses)
}
/**
@@ -232,11 +243,12 @@ public extension CoreStore {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) -> NSManagedObjectID? {
public static func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> NSManagedObjectID? {
return self.defaultStack.fetchObjectID(clauseChain)
return try self.defaultStack.fetchObjectID(clauseChain)
}
/**
@@ -244,11 +256,12 @@ public extension CoreStore {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
public static func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [NSManagedObjectID] {
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
return try self.defaultStack.fetchObjectIDs(from, fetchClauses)
}
/**
@@ -256,11 +269,12 @@ public extension CoreStore {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
public static func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [NSManagedObjectID] {
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
return try self.defaultStack.fetchObjectIDs(from, fetchClauses)
}
/**
@@ -273,11 +287,12 @@ public extension CoreStore {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) -> [NSManagedObjectID]? {
public static func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [NSManagedObjectID] {
return self.defaultStack.fetchObjectIDs(clauseChain)
return try self.defaultStack.fetchObjectIDs(clauseChain)
}
/**
@@ -288,11 +303,12 @@ public extension CoreStore {
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- returns: the result of the the query, or `nil` if no match was found. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) -> U? {
public static func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) throws -> U? {
return self.defaultStack.queryValue(from, selectClause, queryClauses)
return try self.defaultStack.queryValue(from, selectClause, queryClauses)
}
/**
@@ -303,11 +319,12 @@ public extension CoreStore {
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- returns: the result of the the query, or `nil` if no match was found. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) -> U? {
public static func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) throws -> U? {
return self.defaultStack.queryValue(from, selectClause, queryClauses)
return try self.defaultStack.queryValue(from, selectClause, queryClauses)
}
/**
@@ -322,26 +339,12 @@ public extension CoreStore {
)
```
- parameter clauseChain: a `QueryChainableBuilderType` indicating the property/aggregate to fetch and the series of queries for the request.
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
- returns: the result of the the query as specified by the `QueryChainableBuilderType`, or `nil` if no match was found.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) -> B.ResultType? where B.ResultType: QueryableAttributeType {
public static func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) throws -> B.ResultType? where B.ResultType: QueryableAttributeType {
return self.defaultStack.queryValue(clauseChain)
}
/**
Using the `defaultStack`, queries a dictionary of attribtue values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- 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<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
return try self.defaultStack.queryValue(clauseChain)
}
/**
@@ -353,10 +356,27 @@ public extension CoreStore {
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- 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.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
public static func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) throws -> [[String: Any]] {
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
return try self.defaultStack.queryAttributes(from, selectClause, queryClauses)
}
/**
Using the `defaultStack`, queries a dictionary of attribute values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- 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.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) throws -> [[String: Any]] {
return try self.defaultStack.queryAttributes(from, selectClause, queryClauses)
}
/**
@@ -381,9 +401,10 @@ public extension CoreStore {
```
- parameter clauseChain: a `QueryChainableBuilderType` indicating the properties to fetch and the series of queries for the request.
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public static func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) -> [[String: Any]]? where B.ResultType == NSDictionary {
public static func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) throws -> [[String: Any]] where B.ResultType == NSDictionary {
return self.defaultStack.queryAttributes(clauseChain)
return try self.defaultStack.queryAttributes(clauseChain)
}
}

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Returns the `defaultStack`'s model version. The version string is the same as the name of a version-specific .xcdatamodeld file or `CoreStoreSchema`.
@@ -152,7 +152,7 @@ public extension CoreStore {
// MARK: Obsolete
@available(*, obsoleted: 3.1, renamed: "entityDescription(for:)")
@available(swift, obsoleted: 3.1, renamed: "entityDescription(for:)")
public static func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
return self.entityDescription(for: type)

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.

View File

@@ -564,16 +564,4 @@ CORESTORE_EXTERN
CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RETURNS_RETAINED;
#pragma mark CoreStoreFetchRequest
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
NS_SWIFT_NAME(CoreStoreFetchRequest)
@interface _CSFetchRequest: NSFetchRequest
@property (nullable, nonatomic, copy, readonly) NSArray<NSPersistentStore *> *safeAffectedStores;
@end
#endif /* CoreStoreBridge_h */

View File

@@ -218,40 +218,3 @@ CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RE
return [[CSWhere alloc] initWithPredicate:predicate];
}
#pragma mark CoreStoreFetchRequest
@interface _CSFetchRequest ()
@property (nullable, nonatomic, copy) NSArray<NSPersistentStore *> *safeAffectedStores;
@property (nullable, nonatomic, assign) CFArrayRef releaseArray;
@end
@implementation _CSFetchRequest
// MARK: NSFetchRequest
- (void)setAffectedStores:(NSArray<NSPersistentStore *> *_Nullable)affectedStores {
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0
|| [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){ 11, 0, 0 }]) {
self.safeAffectedStores = affectedStores;
[super setAffectedStores:affectedStores];
return;
}
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
if (self.releaseArray != NULL) {
CFRelease(self.releaseArray);
self.releaseArray = NULL;
}
self.safeAffectedStores = affectedStores;
[super setAffectedStores:affectedStores];
self.releaseArray = CFBridgingRetain([super affectedStores]);
}
@end

View File

@@ -53,6 +53,11 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
Progressive migrations are disabled for a store, but an `NSMappingModel` could not be found for a specific source and destination model versions.
*/
case progressiveMigrationRequired(localStoreURL: URL)
/**
The `LocalStorage` was configured with `.allowSynchronousLightweightMigration`, but the model can only be migrated asynchronously.
*/
case asynchronousMigrationRequired(localStoreURL: URL, NSError: NSError)
/**
An internal SDK call failed with the specified `NSError`.
@@ -68,6 +73,11 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
The transaction was cancelled by the user.
*/
case userCancelled
/**
Attempted to perform a fetch but could not find any related persistent store.
*/
case persistentStoreNotFound(entity: DynamicObject.Type)
// MARK: CustomNSError
@@ -92,6 +102,9 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
case .progressiveMigrationRequired:
return CoreStoreErrorCode.progressiveMigrationRequired.rawValue
case .asynchronousMigrationRequired:
return CoreStoreErrorCode.asynchronousMigrationRequired.rawValue
case .internalError:
return CoreStoreErrorCode.internalError.rawValue
@@ -101,6 +114,9 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
case .userCancelled:
return CoreStoreErrorCode.userCancelled.rawValue
case .persistentStoreNotFound:
return CoreStoreErrorCode.persistentStoreNotFound.rawValue
}
}
@@ -127,6 +143,12 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
return [
"localStoreURL": localStoreURL
]
case .asynchronousMigrationRequired(let localStoreURL, let nsError):
return [
"localStoreURL": localStoreURL,
"NSError": nsError
]
case .internalError(let nsError):
return [
@@ -140,6 +162,11 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
case .userCancelled:
return [:]
case .persistentStoreNotFound(let entity):
return [
"entity": entity
]
}
}
@@ -161,6 +188,10 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
case (.progressiveMigrationRequired(let url1), .progressiveMigrationRequired(let url2)):
return url1 == url2
case (.asynchronousMigrationRequired(let url1, let NSError1), .asynchronousMigrationRequired(let url2, let NSError2)):
return url1 == url2
&& NSError1.isEqual(NSError2)
case (.internalError(let NSError1), .internalError(let NSError2)):
return NSError1.isEqual(NSError2)
@@ -177,6 +208,9 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
case (.userCancelled, .userCancelled):
return true
case (.persistentStoreNotFound(let entity1), .persistentStoreNotFound(let entity2)):
return entity1 == entity2
default:
return false
@@ -205,12 +239,19 @@ public enum CoreStoreError: Error, CustomNSError, Hashable {
case .progressiveMigrationRequired(let localStoreURL):
hasher.combine(localStoreURL)
case .asynchronousMigrationRequired(let localStoreURL, let nsError):
hasher.combine(localStoreURL)
hasher.combine(nsError)
case .internalError(let nsError):
hasher.combine(nsError)
case .userError(let error):
hasher.combine(error as NSError)
case .persistentStoreNotFound(let entity):
hasher.combine(ObjectIdentifier(entity))
case .userCancelled:
break
}
@@ -261,6 +302,11 @@ public enum CoreStoreErrorCode: Int {
Progressive migrations are disabled for a store, but an `NSMappingModel` could not be found for a specific source and destination model versions.
*/
case progressiveMigrationRequired
/**
The `LocalStorage` was configured with `.allowSynchronousLightweightMigration`, but the model can only be migrated asynchronously.
*/
case asynchronousMigrationRequired
/**
An internal SDK call failed with the specified "NSError" userInfo key.
@@ -276,12 +322,17 @@ public enum CoreStoreErrorCode: Int {
The transaction was cancelled by the user.
*/
case userCancelled
/**
Attempted to perform a fetch but could not find any related persistent store.
*/
case persistentStoreNotFound
}
// MARK: - NSError
internal extension NSError {
extension NSError {
// MARK: Internal

View File

@@ -1,41 +0,0 @@
//
// CoreStoreFetchRequest+CoreStore.swift
// CoreStore
//
// Copyright © 2018 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreData
// MARK: - CoreStoreFetchRequest
internal extension CoreStoreFetchRequest {
// MARK: Internal
@nonobjc @inline(__always)
internal func dynamicCast<U>() -> NSFetchRequest<U> {
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
}
}

View File

@@ -0,0 +1,91 @@
//
// CoreStoreFetchRequest.swift
// CoreStore
//
// Copyright © 2019 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreData
import ObjectiveC
// MARK: - CoreStoreFetchRequest
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
internal final class CoreStoreFetchRequest<T: NSFetchRequestResult>: NSFetchRequest<NSFetchRequestResult> {
@nonobjc
internal func safeAffectedStores() -> [NSPersistentStore]? {
return self.copiedAffectedStores as! [NSPersistentStore]?
}
@nonobjc @inline(__always)
internal func staticCast() -> NSFetchRequest<T> {
return unsafeBitCast(self, to: NSFetchRequest<T>.self)
}
@nonobjc @inline(__always)
internal func dynamicCast<U>() -> NSFetchRequest<U> {
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
}
// MARK: NSFetchRequest
@objc dynamic
override var affectedStores: [NSPersistentStore]? {
get {
return super.affectedStores
}
set {
if #available(iOS 11.0, macOS 10.13, watchOS 4.0, tvOS 11.0, *) {
self.copiedAffectedStores = (newValue as NSArray?)?.copy() as! NSArray?
super.affectedStores = newValue
return
}
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
if let releaseArray = self.releaseArray {
releaseArray.release()
self.releaseArray = nil
}
self.copiedAffectedStores = (newValue as NSArray?)?.copy() as! NSArray?
super.affectedStores = newValue
self.releaseArray = (super.affectedStores as NSArray?).map(Unmanaged<NSArray>.passRetained(_:))
}
}
// MARK: Private
private var copiedAffectedStores: NSArray?
private var releaseArray: Unmanaged<NSArray>?
}

View File

@@ -33,10 +33,13 @@ import CoreData
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController<NSManagedObject> {
// MARK: Internal
@nonobjc
internal let typedFetchRequest: CoreStoreFetchRequest<NSManagedObject>
@nonobjc
internal convenience init<D>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
internal convenience init<D>(dataStack: DataStack, fetchRequest: CoreStoreFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
self.init(
context: dataStack.mainContext,
fetchRequest: fetchRequest,
@@ -47,22 +50,23 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
}
@nonobjc
internal init<D>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
internal init<D>(context: NSManagedObjectContext, fetchRequest: CoreStoreFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
_ = from.applyToFetchRequest(
_ = try? from.applyToFetchRequest(
fetchRequest,
context: context,
applyAffectedStores: false
)
applyFetchClauses(fetchRequest)
self.typedFetchRequest = fetchRequest
self.reapplyAffectedStores = { fetchRequest, context in
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
try from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
}
super.init(
fetchRequest: fetchRequest,
fetchRequest: fetchRequest.staticCast(),
managedObjectContext: context,
sectionNameKeyPath: sectionBy?.sectionKeyPath,
cacheName: nil
@@ -71,14 +75,8 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
@nonobjc
internal func performFetchFromSpecifiedStores() throws {
if !self.reapplyAffectedStores(self.fetchRequest, self.managedObjectContext) {
CoreStore.log(
.warning,
message: "Attempted to perform a fetch on an \(cs_typeName(self)) but could not find any persistent store for the entity \(cs_typeName(self.fetchRequest.entityName))"
)
}
try self.reapplyAffectedStores(self.typedFetchRequest, self.managedObjectContext)
try self.performFetch()
}
@@ -97,5 +95,5 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
// MARK: Private
@nonobjc
private let reapplyAffectedStores: (_ fetchRequest: NSFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) -> Bool
private let reapplyAffectedStores: (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) throws -> Void
}

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStoreObject
public extension CoreStoreObject {
extension CoreStoreObject {
/**
Exposes a `FetchableSource` that can fetch sibling objects of this `CoreStoreObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated.

View File

@@ -0,0 +1,591 @@
//
// CoreStoreObject+Observing.swift
// CoreStore
//
// Copyright © 2018 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreData
// MARK: CoreStoreObjectKeyValueObservation
/**
Observation token for `CoreStoreObject` properties. Make sure to retain this instance to keep observing notifications.
`invalidate()` will be called automatically when an `CoreStoreObjectKeyValueObservation` is deinited.
*/
public protocol CoreStoreObjectKeyValueObservation: class {
/**
`invalidate()` will be called automatically when an `CoreStoreObjectKeyValueObservation` is deinited.
*/
func invalidate()
}
// MARK: - ValueContainer.Required
extension ValueContainer.Required {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectValueDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - ValueContainer.Optional
extension ValueContainer.Optional {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectValueDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - TransformableContainer.Required
extension TransformableContainer.Required {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectTransformableDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - TransformableContainer.Optional
extension TransformableContainer.Optional {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectTransformableDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - RelationshipContainer.ToOne
extension RelationshipContainer.ToOne {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectObjectDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectObjectDiff<D>(
kind: kind,
newNativeValue: newValue as! CoreStoreManagedObject?,
oldNativeValue: oldValue as! CoreStoreManagedObject?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
// MARK: - RelationshipContainer.ToManyUnordered
extension RelationshipContainer.ToManyUnordered {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectUnorderedDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectUnorderedDiff<D>(
kind: kind,
newNativeValue: newValue as! NSOrderedSet?,
oldNativeValue: oldValue as! NSOrderedSet?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
// MARK: - RelationshipContainer.ToManyOrdered
extension RelationshipContainer.ToManyOrdered {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectOrderedDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, indexes, isPrior) in
let notification = CoreStoreObjectOrderedDiff<D>(
kind: kind,
newNativeValue: newValue as! NSArray?,
oldNativeValue: oldValue as! NSArray?,
indexes: indexes ?? IndexSet(),
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
// MARK: - CoreStoreObjectValueDiff
/**
The object containing the changeset for an observed `ValueContainer.Required` and `ValueContainer.Optional` property.
*/
public final class CoreStoreObjectValueDiff<V: ImportableAttributeType> {
/**
Indicates the kind of change. See the comments for `NSObject.observeValue(forKeyPath:of:change:context:)` for more information.
*/
public let kind: NSKeyValueChange
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. `newValue` will be `nil` if `isPrior` is `true`.
*/
public private(set) lazy var newValue: V? = self.newNativeValue.flatMap(V.cs_fromQueryableNativeType)
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`.
*/
public private(set) lazy var oldValue: V? = self.oldNativeValue.flatMap(V.cs_fromQueryableNativeType)
/**
'isPrior' will be `true` if this change observation is being sent before the change happens, due to `.prior` being passed to `observe()`
*/
public let isPrior: Bool
// MARK: FilePrivate
fileprivate init(kind: NSKeyValueChange, newNativeValue: V.QueryableNativeType?, oldNativeValue: V.QueryableNativeType?, isPrior: Bool) {
self.kind = kind
self.newNativeValue = newNativeValue
self.oldNativeValue = oldNativeValue
self.isPrior = isPrior
}
// MARK: Private
private let newNativeValue: V.QueryableNativeType?
private let oldNativeValue: V.QueryableNativeType?
}
// MARK: - CoreStoreObjectValueDiff
/**
The object containing the changeset for an observed `TransformableContainer.Required` or `TransformableContainer.Optional` property.
*/
public final class CoreStoreObjectTransformableDiff<V: NSCoding & NSCopying> {
/**
Indicates the kind of change. See the comments for `NSObject.observeValue(forKeyPath:of:change:context:)` for more information.
*/
public let kind: NSKeyValueChange
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public let newValue: V?
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public let oldValue: V?
/**
'isPrior' will be `true` if this change observation is being sent before the change happens, due to `.prior` being passed to `observe()`
*/
public let isPrior: Bool
// MARK: FilePrivate
fileprivate init(kind: NSKeyValueChange, newValue: V?, oldValue: V?, isPrior: Bool) {
self.kind = kind
self.newValue = newValue
self.oldValue = oldValue
self.isPrior = isPrior
}
}
// MARK: - CoreStoreObjectObjectDiff
/**
The object containing the changeset for an observed `RelationshipContainer.ToOne` property.
*/
public final class CoreStoreObjectObjectDiff<D: CoreStoreObject> {
/**
Indicates the kind of change. See the comments for `NSObject.observeValue(forKeyPath:of:change:context:)` for more information.
*/
public let kind: NSKeyValueChange
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public private(set) lazy var newValue: D? = self.newNativeValue.flatMap(D.cs_fromRaw(object:))
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public private(set) lazy var oldValue: D? = self.oldNativeValue.flatMap(D.cs_fromRaw(object:))
/**
'isPrior' will be `true` if this change observation is being sent before the change happens, due to `.prior` being passed to `observe()`
*/
public let isPrior: Bool
// MARK: FilePrivate
fileprivate init(kind: NSKeyValueChange, newNativeValue: CoreStoreManagedObject?, oldNativeValue: CoreStoreManagedObject?, isPrior: Bool) {
self.kind = kind
self.newNativeValue = newNativeValue
self.oldNativeValue = oldNativeValue
self.isPrior = isPrior
}
// MARK: Private
private let newNativeValue: CoreStoreManagedObject?
private let oldNativeValue: CoreStoreManagedObject?
}
// MARK: - CoreStoreObjectUnorderedDiff
/**
The object containing the changeset for an observed `RelationshipContainer.ToManyUnordered` property.
*/
public final class CoreStoreObjectUnorderedDiff<D: CoreStoreObject> {
/**
Indicates the kind of change. See the comments for `NSObject.observeValue(forKeyPath:of:change:context:)` for more information.
*/
public let kind: NSKeyValueChange
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public private(set) lazy var newValue: Set<D> = Set(self.newNativeValue.map({ D.cs_fromRaw(object: $0 as! NSManagedObject) }))
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public private(set) lazy var oldValue: Set<D> = Set(self.oldNativeValue.map({ D.cs_fromRaw(object: $0 as! NSManagedObject) }))
/**
'isPrior' will be `true` if this change observation is being sent before the change happens, due to `.prior` being passed to `observe()`
*/
public let isPrior: Bool
// MARK: FilePrivate
fileprivate init(kind: NSKeyValueChange, newNativeValue: NSOrderedSet?, oldNativeValue: NSOrderedSet?, isPrior: Bool) {
self.kind = kind
self.newNativeValue = newNativeValue ?? []
self.oldNativeValue = oldNativeValue ?? []
self.isPrior = isPrior
}
// MARK: Private
private let newNativeValue: NSOrderedSet
private let oldNativeValue: NSOrderedSet
}
// MARK: - CoreStoreObjectOrderedDiff
/**
The object containing the changeset for an observed `RelationshipContainer.Ordered` property.
*/
public final class CoreStoreObjectOrderedDiff<D: CoreStoreObject> {
/**
Indicates the kind of change. See the comments for `NSObject.observeValue(forKeyPath:of:change:context:)` for more information.
*/
public let kind: NSKeyValueChange
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public private(set) lazy var newValue: [D] = self.newNativeValue.map({ D.cs_fromRaw(object: $0 as! NSManagedObject) })
/**
`newValue` and `oldValue` will only be non-nil if `.new`/`.old` is passed to `observe()`. In general, get the most up to date value by accessing it directly on the observed object instead.
*/
public private(set) lazy var oldValue: [D] = self.oldNativeValue.map({ D.cs_fromRaw(object: $0 as! NSManagedObject) })
/**
`indexes` will be `nil` unless the observed KeyPath refers to an ordered to-many property
*/
public let indexes: IndexSet
/**
'isPrior' will be `true` if this change observation is being sent before the change happens, due to `.prior` being passed to `observe()`
*/
public let isPrior: Bool
// MARK: FilePrivate
fileprivate init(kind: NSKeyValueChange, newNativeValue: NSArray?, oldNativeValue: NSArray?, indexes: IndexSet, isPrior: Bool) {
self.kind = kind
self.newNativeValue = newNativeValue ?? []
self.oldNativeValue = oldNativeValue ?? []
self.indexes = indexes
self.isPrior = isPrior
}
// MARK: Private
private let newNativeValue: NSArray
private let oldNativeValue: NSArray
}
// MARK: - AttributeProtocol
extension AttributeProtocol {
// MARK: FilePrivate
fileprivate func observe<O: CoreStoreObject, V: ImportableAttributeType>(with options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectValueDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectValueDiff<V>(
kind: kind,
newNativeValue: newValue as! V.QueryableNativeType?,
oldNativeValue: oldValue as! V.QueryableNativeType?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
fileprivate func observe<O: CoreStoreObject, V: NSCoding & NSCopying>(with options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectTransformableDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectTransformableDiff<V>(
kind: kind,
newValue: newValue as! V?,
oldValue: oldValue as! V?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
// MARK: - _CoreStoreObjectKeyValueObservation
// Mirrored implementation from https://github.com/apple/swift/blob/6e7051eb1e38e743a514555d09256d12d3fec750/stdlib/public/Darwin/Foundation/NSObject.swift#L141
fileprivate final class _CoreStoreObjectKeyValueObservation: NSObject, CoreStoreObjectKeyValueObservation {
// MARK: FilePrivate
@nonobjc
fileprivate init(object: CoreStoreManagedObject, keyPath: KeyPathString, callback: @escaping (_ object: CoreStoreManagedObject, _ kind: NSKeyValueChange, _ newValue: Any?, _ oldValue: Any?, _ indexes: IndexSet?, _ isPrior: Bool) -> Void) {
let _ = _CoreStoreObjectKeyValueObservation.swizzler
self.keyPath = keyPath
self.object = object
self.callback = callback
}
@nonobjc
fileprivate func start(_ options: NSKeyValueObservingOptions) {
self.object?.addObserver(self, forKeyPath: self.keyPath, options: options, context: nil)
}
deinit {
self.object?.removeObserver(self, forKeyPath: self.keyPath, context: nil)
}
// MARK: DynamicObjectKeyValueObservation
@nonobjc
public func invalidate() {
self.object?.removeObserver(self, forKeyPath: self.keyPath, context: nil)
self.object = nil
}
// MARK: Private
// workaround for <rdar://problem/31640524> Erroneous (?) error when using bridging in the Foundation overlay
@nonobjc
static var swizzler: Any? = cs_lazy {
let bridgeClass: AnyClass = _CoreStoreObjectKeyValueObservation.self
let rootObserveImpl = class_getInstanceMethod(
bridgeClass,
#selector(_CoreStoreObjectKeyValueObservation.observeValue(forKeyPath:of:change:context:))
)!
let swapObserveImpl = class_getInstanceMethod(
bridgeClass,
#selector(_CoreStoreObjectKeyValueObservation._cs_swizzle_me_observeValue(forKeyPath:of:change:context:))
)!
method_exchangeImplementations(rootObserveImpl, swapObserveImpl)
return nil
}
@nonobjc
private weak var object: CoreStoreManagedObject?
@nonobjc
private let callback: (_ object: CoreStoreManagedObject, _ kind: NSKeyValueChange, _ newValue: Any?, _ oldValue: Any?, _ indexes: IndexSet?, _ isPrior: Bool) -> Void
@nonobjc
private let keyPath: KeyPathString
@objc
private dynamic func _cs_swizzle_me_observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSString: Any]?, context: UnsafeMutableRawPointer?) {
guard
let object = object as? CoreStoreManagedObject,
object == self.object,
let change = change
else {
return
}
let rawKind: UInt = change[NSKeyValueChangeKey.kindKey.rawValue as NSString] as! UInt
self.callback(
object,
NSKeyValueChange(rawValue: rawKind)!,
change[NSKeyValueChangeKey.newKey.rawValue as NSString],
change[NSKeyValueChangeKey.oldKey.rawValue as NSString],
change[NSKeyValueChangeKey.indexesKey.rawValue as NSString] as! IndexSet?,
change[NSKeyValueChangeKey.notificationIsPriorKey.rawValue as NSString] as! Bool? ?? false
)
}
}

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - ValueContainer.Required
public extension ValueContainer.Required {
extension ValueContainer.Required {
/**
Creates a `Where` clause by comparing if a property is equal to a value
@@ -112,7 +112,7 @@ public extension ValueContainer.Required {
// MARK: - ValueContainer.Optional
public extension ValueContainer.Optional {
extension ValueContainer.Optional {
/**
Creates a `Where` clause by comparing if a property is equal to a value
@@ -223,7 +223,7 @@ public extension ValueContainer.Optional {
// MARK: - RelationshipContainer.ToOne
public extension RelationshipContainer.ToOne {
extension RelationshipContainer.ToOne {
/**
Creates a `Where` clause by comparing if a property is equal to a value

View File

@@ -140,7 +140,7 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
// MARK: - DynamicObject where Self: CoreStoreObject
public extension DynamicObject where Self: CoreStoreObject {
extension DynamicObject where Self: CoreStoreObject {
/**
Returns the `PartialObject` instance for the object, which acts as a fast, type-safe KVC interface for `CoreStoreObject`.

View File

@@ -288,6 +288,10 @@ public final class CoreStoreSchema: DynamicSchema {
switch child.value {
case let attribute as AttributeProtocol:
CoreStore.assert(
!NSManagedObject.instancesRespond(to: Selector(attribute.keyPath)),
"Attribute Property name \"\(String(reflecting: entity.type)).\(attribute.keyPath)\" is not allowed because it collides with \"\(String(reflecting: NSManagedObject.self)).\(attribute.keyPath)\""
)
let description = NSAttributeDescription()
description.name = attribute.keyPath
description.attributeType = Swift.type(of: attribute).attributeType
@@ -302,6 +306,10 @@ public final class CoreStoreSchema: DynamicSchema {
customGetterSetterByKeyPaths[attribute.keyPath] = (attribute.getter, attribute.setter)
case let relationship as RelationshipProtocol:
CoreStore.assert(
!NSManagedObject.instancesRespond(to: Selector(relationship.keyPath)),
"Relationship Property name \"\(String(reflecting: entity.type)).\(relationship.keyPath)\" is not allowed because it collides with \"\(String(reflecting: NSManagedObject.self)).\(relationship.keyPath)\""
)
let description = NSRelationshipDescription()
description.name = relationship.keyPath
description.minCount = relationship.minCount
@@ -442,15 +450,18 @@ public final class CoreStoreSchema: DynamicSchema {
)
}
for (entity, entityDescription) in entityDescriptionsByEntity {
let uniqueConstraints = entity.uniqueConstraints.filter({ !$0.isEmpty })
if !uniqueConstraints.isEmpty {
if #available(macOS 10.11, *) {
CoreStore.assert(
entityDescription.superentity == nil,
"Uniqueness constraints must be defined at the highest level possible."
)
entityDescription.uniquenessConstraints = entity.uniqueConstraints.map { $0.map { $0 as NSString } }
let uniqueConstraints = entity.uniqueConstraints.filter({ !$0.isEmpty })
if !uniqueConstraints.isEmpty {
CoreStore.assert(
entityDescription.superentity == nil,
"Uniqueness constraints must be defined at the highest level possible."
)
entityDescription.uniquenessConstraints = entity.uniqueConstraints.map { $0.map { $0 as NSString } }
}
}
guard !entity.indexes.isEmpty else {
@@ -517,7 +528,14 @@ public final class CoreStoreSchema: DynamicSchema {
return CoreStoreManagedObject.self
}
let managedObjectClass: AnyClass = className.withCString {
// Xcode 10.1+ users: You may find this comment due to a crash while debugging on an iPhone XR device (or any A12 device).
// This is a known issue that should not occur in archived builds, as the AppStore strips away arm64e build architectures from the binary. So while it crashes on DEBUG, it shouldn't be an issue for live users.
// In the meantime, please submit a bug report to Apple and refer to similar discussions here:
// - https://github.com/realm/realm-cocoa/issues/6013
// - https://github.com/wordpress-mobile/WordPress-iOS/pull/10400
// - https://github.com/JohnEstropia/CoreStore/issues/291
// If you wish to debug with A12 devices, please use Xcode 10.0 for now.
return objc_allocateClassPair(superClass, $0, 0)!
}
defer {

View File

@@ -121,24 +121,24 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
// MARK: Equatable
public static func == (lhs: CustomMapping, rhs: CustomMapping) -> Bool {
public static func ==(lhs: CustomMapping, rhs: CustomMapping) -> Bool {
switch (lhs, rhs) {
case (.deleteEntity(let sourceEntity1), .deleteEntity(let sourceEntity2)):
return sourceEntity1 == sourceEntity2
case (.insertEntity(let destinationEntity1), .insertEntity(let destinationEntity2)):
return destinationEntity1 == destinationEntity2
case (.copyEntity(let sourceEntity1, let destinationEntity1), .copyEntity(let sourceEntity2, let destinationEntity2)):
return sourceEntity1 == sourceEntity2
&& destinationEntity1 == destinationEntity2
case (.transformEntity(let sourceEntity1, let destinationEntity1, _), .transformEntity(let sourceEntity2, let destinationEntity2, _)):
return sourceEntity1 == sourceEntity2
&& destinationEntity1 == destinationEntity2
default:
return false
}
@@ -146,24 +146,24 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
// MARK: Hashable
public func hash(into hasher: inout Hasher) {
switch self {
case .deleteEntity(let sourceEntity):
hasher.combine(0)
hasher.combine(sourceEntity)
case .insertEntity(let destinationEntity):
hasher.combine(1)
hasher.combine(destinationEntity)
case .copyEntity(let sourceEntity, let destinationEntity):
hasher.combine(2)
hasher.combine(sourceEntity)
hasher.combine(destinationEntity)
case .transformEntity(let sourceEntity, let destinationEntity, _):
hasher.combine(3)
hasher.combine(sourceEntity)
@@ -177,12 +177,12 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
fileprivate var entityMappingSourceEntity: EntityName? {
switch self {
case .deleteEntity(let sourceEntity),
.copyEntity(let sourceEntity, _),
.transformEntity(let sourceEntity, _, _):
return sourceEntity
case .insertEntity:
return nil
}
@@ -191,12 +191,12 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
fileprivate var entityMappingDestinationEntity: EntityName? {
switch self {
case .insertEntity(let destinationEntity),
.copyEntity(_, let destinationEntity),
.transformEntity(_, let destinationEntity, _):
return destinationEntity
case .deleteEntity:
return nil
}
@@ -324,7 +324,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
// MARK: Equatable
public static func == (lhs: CustomSchemaMappingProvider, rhs: CustomSchemaMappingProvider) -> Bool {
public static func ==(lhs: CustomSchemaMappingProvider, rhs: CustomSchemaMappingProvider) -> Bool {
return lhs.sourceVersion == rhs.sourceVersion
&& lhs.destinationVersion == rhs.destinationVersion
@@ -333,9 +333,9 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
// MARK: Hashable
public func hash(into hasher: inout Hasher) {
hasher.combine(self.sourceVersion)
hasher.combine(self.destinationVersion)
hasher.combine(ObjectIdentifier(cs_dynamicType(of: self)))
@@ -422,8 +422,8 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
entityMapping.sourceExpression = expression(forSource: sourceEntity)
entityMapping.attributeMappings = autoreleasepool { () -> [NSPropertyMapping] in
let sourceAttributes = sourceEntity.cs_resolvedAttributeRenamingIdentities()
let destinationAttributes = destinationEntity.cs_resolvedAttributeRenamingIdentities()
let sourceAttributes = sourceEntity.cs_resolveAttributeNames()
let destinationAttributes = destinationEntity.cs_resolveAttributeRenamingIdentities()
var attributeMappings: [NSPropertyMapping] = []
for (renamingIdentifier, destination) in destinationAttributes {
@@ -439,15 +439,15 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
}
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
let sourceRelationships = sourceEntity.cs_resolvedRelationshipRenamingIdentities()
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
let sourceRelationships = sourceEntity.cs_resolveRelationshipNames()
let destinationRelationships = destinationEntity.cs_resolveRelationshipRenamingIdentities()
var relationshipMappings: [NSPropertyMapping] = []
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), \"destinationInstancesForSourceRelationshipNamed:sourceInstances:\", \"\(sourceRelationshipName)\", FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceRelationshipName)\"))")
@@ -476,12 +476,12 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
]
autoreleasepool {
let sourceAttributes = sourceEntity.cs_resolvedAttributeRenamingIdentities()
let destinationAttributes = destinationEntity.cs_resolvedAttributeRenamingIdentities()
let sourceAttributes = sourceEntity.cs_resolveAttributeNames()
let destinationAttributes = destinationEntity.cs_resolveAttributeRenamingIdentities()
let transformedRenamingIdentifiers = Set(destinationAttributes.keys)
.intersection(sourceAttributes.keys)
var sourceAttributesByDestinationKey: [KeyPathString: NSAttributeDescription] = [:]
for renamingIdentifier in transformedRenamingIdentifiers {
@@ -493,19 +493,19 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
}
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
let sourceRelationships = sourceEntity.cs_resolvedRelationshipRenamingIdentities()
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
let sourceRelationships = sourceEntity.cs_resolveRelationshipNames()
let destinationRelationships = destinationEntity.cs_resolveRelationshipRenamingIdentities()
let transformedRenamingIdentifiers = Set(destinationRelationships.keys)
.intersection(sourceRelationships.keys)
var relationshipMappings: [NSPropertyMapping] = []
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 = destinationRelationshipName
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"destinationInstancesForSourceRelationshipNamed:sourceInstances:\", \"\(sourceRelationshipName)\", FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceRelationshipName)\"))")
@@ -593,9 +593,9 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
var allMappedSourceKeys: [KeyPathString: KeyPathString] = [:]
var allMappedDestinationKeys: [KeyPathString: KeyPathString] = [:]
let sourceRenamingIdentifiers = sourceModel.cs_resolvedRenamingIdentities()
let sourceRenamingIdentifiers = sourceModel.cs_resolveNames()
let sourceEntityNames = sourceModel.entitiesByName
let destinationRenamingIdentifiers = destinationModel.cs_resolvedRenamingIdentities()
let destinationRenamingIdentifiers = destinationModel.cs_resolveRenamingIdentities()
let destinationEntityNames = destinationModel.entitiesByName
let removedRenamingIdentifiers = Set(sourceRenamingIdentifiers.keys)
@@ -610,7 +610,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
for mapping in self.entityMappings {
switch mapping {
case .deleteEntity(let sourceEntity):
CoreStore.assert(
sourceEntityNames[sourceEntity] != nil,
@@ -622,7 +622,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
)
deleteMappings.insert(mapping)
allMappedSourceKeys[sourceEntity] = ""
case .insertEntity(let destinationEntity):
CoreStore.assert(
destinationEntityNames[destinationEntity] != nil,
@@ -634,7 +634,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
)
insertMappings.insert(mapping)
allMappedDestinationKeys[destinationEntity] = ""
case .transformEntity(let sourceEntity, let destinationEntity, _):
CoreStore.assert(
sourceEntityNames[sourceEntity] != nil,
@@ -655,7 +655,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
transformMappings.insert(mapping)
allMappedSourceKeys[sourceEntity] = destinationEntity
allMappedDestinationKeys[destinationEntity] = sourceEntity
case .copyEntity(let sourceEntity, let destinationEntity):
CoreStore.assert(
sourceEntityNames[sourceEntity] != nil,
@@ -689,7 +689,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
let sourceEntityName = sourceEntity.name!
let destinationEntityName = destinationEntity.name!
switch (allMappedSourceKeys[sourceEntityName], allMappedDestinationKeys[destinationEntityName]) {
case (nil, nil):
if sourceEntity.versionHash == destinationEntity.versionHash {
@@ -699,8 +699,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
destinationEntity: destinationEntityName
)
)
}
else {
} else {
transformMappings.insert(
.transformEntity(
@@ -712,15 +711,15 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
}
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
}
@@ -730,11 +729,11 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
let sourceEntity = sourceRenamingIdentifiers[renamingIdentifier]!.entity
let sourceEntityName = sourceEntity.name!
switch allMappedSourceKeys[sourceEntityName] {
case nil:
deleteMappings.insert(.deleteEntity(sourceEntity: sourceEntityName))
allMappedSourceKeys[sourceEntityName] = ""
default:
continue
}
@@ -744,11 +743,11 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
let destinationEntityName = destinationEntity.name!
switch allMappedDestinationKeys[destinationEntityName] {
case nil:
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
allMappedDestinationKeys[destinationEntityName] = ""
default:
continue
}

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - DataStack
public extension DataStack {
extension DataStack {
/**
Asynchronously adds a `StorageInterface` to the stack. Migrations are also initiated by default.
@@ -748,12 +748,20 @@ public extension DataStack {
// Lightweight migration failed somehow. Proceed using InferedMappingModel below
}
}
let fileManager = FileManager.default
let systemTemporaryDirectoryURL: URL
if #available(macOS 10.12, *) {
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
systemTemporaryDirectoryURL = fileManager.temporaryDirectory
}
else {
systemTemporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory())
}
let temporaryDirectoryURL = systemTemporaryDirectoryURL
.appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack")
.appendingPathComponent(ProcessInfo().globallyUniqueString)
let fileManager = FileManager.default
try! fileManager.createDirectory(
at: temporaryDirectoryURL,
withIntermediateDirectories: true,
@@ -838,7 +846,7 @@ public extension DataStack {
// MARK: - FilePrivate
fileprivate extension Array where Element == SchemaMappingProvider {
extension Array where Element == SchemaMappingProvider {
func findMapping(sourceSchema: DynamicSchema, destinationSchema: DynamicSchema, storage: LocalStorage) throws -> (mappingModel: NSMappingModel, migrationType: MigrationType) {

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - DataStack
@available(macOS 10.12, *)
public extension DataStack {
extension DataStack {
/**
Creates an `ObjectMonitor` for the specified `DynamicObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `DynamicObject`.
@@ -152,7 +152,7 @@ public extension DataStack {
```
dataStack.monitorList(
{ (monitor) in
createAsynchronously: { (monitor) in
self.monitor = monitor
},
From<MyPersonEntity>()
@@ -162,7 +162,6 @@ public extension DataStack {
```
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
*/
public func monitorList<B: FetchChainableBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {
@@ -288,7 +287,7 @@ public extension DataStack {
Asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType` built from a chain of clauses.
```
dataStack.monitorSectionedList(
{ (monitor) in
createAsynchronously: { (monitor) in
self.monitor = monitor
},
From<MyPersonEntity>()
@@ -297,8 +296,8 @@ public extension DataStack {
.orderBy(.ascending(\.age))
)
```
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter clauseChain: a `SectionMonitorBuilderType` built from a chain of clauses
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType`
*/
public func monitorSectionedList<B: SectionMonitorBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {

View File

@@ -82,15 +82,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> D? {
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> D? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchOne(from, fetchClauses)
return try self.mainContext.fetchOne(from, fetchClauses)
}
/**
@@ -98,15 +99,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> D? {
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> D? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchOne(from, fetchClauses)
return try self.mainContext.fetchOne(from, fetchClauses)
}
/**
@@ -119,15 +121,16 @@ extension DataStack: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) -> B.ObjectType? {
public func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> B.ObjectType? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchOne(clauseChain)
return try self.mainContext.fetchOne(clauseChain)
}
/**
@@ -135,15 +138,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [D]? {
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [D] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchAll(from, fetchClauses)
return try self.mainContext.fetchAll(from, fetchClauses)
}
/**
@@ -151,15 +155,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [D]? {
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [D] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchAll(from, fetchClauses)
return try self.mainContext.fetchAll(from, fetchClauses)
}
/**
@@ -172,15 +177,16 @@ extension DataStack: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]? {
public func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [B.ObjectType] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchAll(clauseChain)
return try self.mainContext.fetchAll(clauseChain)
}
/**
@@ -188,15 +194,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> Int? {
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> Int {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchCount(from, fetchClauses)
return try self.mainContext.fetchCount(from, fetchClauses)
}
/**
@@ -204,15 +211,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> Int? {
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> Int {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchCount(from, fetchClauses)
return try self.mainContext.fetchCount(from, fetchClauses)
}
/**
@@ -225,15 +233,16 @@ extension DataStack: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the number `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
public func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> Int {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchCount(clauseChain)
return try self.mainContext.fetchCount(clauseChain)
}
/**
@@ -241,15 +250,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> NSManagedObjectID? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchObjectID(from, fetchClauses)
return try self.mainContext.fetchObjectID(from, fetchClauses)
}
/**
@@ -257,15 +267,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> NSManagedObjectID? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchObjectID(from, fetchClauses)
return try self.mainContext.fetchObjectID(from, fetchClauses)
}
/**
@@ -278,15 +289,16 @@ extension DataStack: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) -> NSManagedObjectID? {
public func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> NSManagedObjectID? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchObjectID(clauseChain)
return try self.mainContext.fetchObjectID(clauseChain)
}
/**
@@ -294,15 +306,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [NSManagedObjectID] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchObjectIDs(from, fetchClauses)
return try self.mainContext.fetchObjectIDs(from, fetchClauses)
}
/**
@@ -310,15 +323,16 @@ extension DataStack: FetchableSource, QueryableSource {
- 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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [NSManagedObjectID] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchObjectIDs(from, fetchClauses)
return try self.mainContext.fetchObjectIDs(from, fetchClauses)
}
/**
@@ -331,15 +345,16 @@ extension DataStack: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) -> [NSManagedObjectID]? {
public func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [NSManagedObjectID] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.fetchObjectIDs(clauseChain)
return try self.mainContext.fetchObjectIDs(clauseChain)
}
@@ -353,15 +368,16 @@ extension DataStack: FetchableSource, QueryableSource {
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- returns: the result of the the query, or `nil` if no match was found. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) -> U? {
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) throws -> U? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.queryValue(from, selectClause, queryClauses)
return try self.mainContext.queryValue(from, selectClause, queryClauses)
}
/**
@@ -372,15 +388,16 @@ extension DataStack: FetchableSource, QueryableSource {
- parameter from: a `From` clause indicating the entity type
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- returns: the result of the the query, or `nil` if no match was found. The type of the return value is specified by the generic type of the `Select<U>` parameter.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) -> U? {
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) throws -> U? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.queryValue(from, selectClause, queryClauses)
return try self.mainContext.queryValue(from, selectClause, queryClauses)
}
/**
@@ -395,15 +412,16 @@ extension DataStack: FetchableSource, QueryableSource {
)
```
- parameter clauseChain: a `QueryChainableBuilderType` indicating the property/aggregate to fetch and the series of queries for the request.
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
- returns: the result of the the query as specified by the `QueryChainableBuilderType`, or `nil` if no match was found.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) -> B.ResultType? where B.ResultType: QueryableAttributeType {
public func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) throws -> B.ResultType? where B.ResultType: QueryableAttributeType {
CoreStore.assert(
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
return try self.mainContext.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
/**
@@ -415,14 +433,15 @@ extension DataStack: FetchableSource, QueryableSource {
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- 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.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) throws -> [[String: Any]] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.queryAttributes(from, selectClause, queryClauses)
return try self.mainContext.queryAttributes(from, selectClause, queryClauses)
}
/**
@@ -434,14 +453,15 @@ extension DataStack: FetchableSource, QueryableSource {
- parameter selectClause: a `Select<U>` clause indicating the properties to fetch, and with the generic type indicating the return type.
- 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.
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) throws -> [[String: Any]] {
CoreStore.assert(
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.queryAttributes(from, selectClause, queryClauses)
return try self.mainContext.queryAttributes(from, selectClause, queryClauses)
}
/**
@@ -466,14 +486,15 @@ extension DataStack: FetchableSource, QueryableSource {
```
- parameter clauseChain: a `QueryChainableBuilderType` indicating the properties to fetch and the series of queries for the request.
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
public func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) -> [[String: Any]]? where B.ResultType == NSDictionary {
public func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) throws -> [[String: Any]] where B.ResultType == NSDictionary {
CoreStore.assert(
Thread.isMainThread,
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
)
return self.mainContext.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
return try self.mainContext.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
@@ -490,7 +511,7 @@ extension DataStack: FetchableSource, QueryableSource {
// MARK: Obsoleted
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
@available(swift, obsoleted: 3.1, renamed: "unsafeContext()")
public func internalContext() -> NSManagedObjectContext {
fatalError()

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - DataStack
public extension DataStack {
extension DataStack {
/**
Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.

View File

@@ -43,7 +43,7 @@ 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 xcodeModelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set (e.g. in Unit Tests).
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
- parameter bundle: an optional bundle to load .xcdatamodeld 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(xcodeModelName: XcodeDataModelFileName = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
@@ -345,6 +345,18 @@ public final class DataStack: Equatable {
)
return storage
}
catch let error as NSError where storage.localStorageOptions.contains(.allowSynchronousLightweightMigration) && error.isCoreDataMigrationError {
let storeError = CoreStoreError.asynchronousMigrationRequired(
localStoreURL: fileURL,
NSError: error
)
CoreStore.log(
storeError,
"Failed to add \(cs_typeName(storage)) to the stack."
)
throw storeError
}
}
catch {
@@ -644,13 +656,13 @@ public final class DataStack: Equatable {
// MARK: Obsolete
@available(*, obsoleted: 3.1, renamed: "entityDescription(for:)")
@available(swift, obsoleted: 3.1, renamed: "entityDescription(for:)")
public func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
return self.entityDescription(for: type)
}
@available(*, obsoleted: 3.1, renamed: "objectID(forURIRepresentation:)")
@available(swift, obsoleted: 3.1, renamed: "objectID(forURIRepresentation:)")
public func objectIDForURIRepresentation(_ url: URL) -> NSManagedObjectID? {
return self.objectID(forURIRepresentation: url)

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - DispatchQueue
internal extension DispatchQueue {
extension DispatchQueue {
@nonobjc @inline(__always)
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {

View File

@@ -24,6 +24,7 @@
//
import Foundation
import CoreData
// MARK: - AnyDynamicKeyPath
@@ -47,7 +48,7 @@ public protocol DynamicKeyPath: AnyDynamicKeyPath {
/**
The DynamicObject type
*/
associatedtype ObjectType
associatedtype ObjectType: DynamicObject
/**
The Value type
@@ -58,7 +59,7 @@ public protocol DynamicKeyPath: AnyDynamicKeyPath {
// MARK: - KeyPathString
public extension KeyPathString {
extension KeyPathString {
/**
Extracts the keyPath string from the property.
@@ -66,7 +67,7 @@ public extension KeyPathString {
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: NSManagedObject, V>(keyPath: KeyPath<O, V>) {
public init<O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(keyPath: KeyPath<O, V>) {
self = keyPath.cs_keyPathString
}
@@ -78,17 +79,27 @@ public extension KeyPathString {
```
*/
public init<O: CoreStoreObject, K: DynamicKeyPath>(keyPath: KeyPath<O, K>) {
self = O.meta[keyPath: keyPath].cs_keyPathString
}
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: DynamicObject, T, V>(keyPath: Where<O>.Expression<T, V>) {
self = keyPath.cs_keyPathString
}
}
// MARK: - KeyPath: DynamicKeyPath
// TODO: SE-0143 is not implemented: https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: ImportableAttributeType {
extension KeyPath: DynamicKeyPath {
extension KeyPath: DynamicKeyPath, AnyDynamicKeyPath where Root: DynamicObject, Value: AllowedObjectiveCKeyPathValue {
public typealias ObjectType = Root
public typealias ValueType = Value

View File

@@ -24,6 +24,7 @@
//
import Foundation
import CoreData
// MARK: - DynamicObject

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - DynamicSchema
public extension DynamicSchema {
extension DynamicSchema {
/**
Prints the `DynamicSchema` as their corresponding `CoreStoreObject` Swift declarations. This is useful for converting current `XcodeDataModelSchema`-based models into the new `CoreStoreSchema` framework. Additional adjustments may need to be done to the generated source code; for example: `Transformable` concrete types need to be provided, as well as `default` values.

View File

@@ -70,7 +70,8 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
@available(macOS 10.11, *)
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]]) {
self.init(
O.self,
@@ -81,6 +82,27 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
uniqueConstraints: uniqueConstraints
)
}
/**
Initializes an `Entity`. Always provide a concrete generic type to `Entity`.
```
Entity<Animal>("Animal")
```
- parameter entityName: the `NSEntityDescription` name to use for the entity
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
*/
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = []) {
self.init(
O.self,
entityName,
isAbstract: isAbstract,
versionHashModifier: versionHashModifier,
indexes: indexes
)
}
/**
Initializes an `Entity`.
@@ -94,7 +116,8 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
@available(macOS 10.11, *)
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]]) {
let meta = O.meta
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
@@ -113,6 +136,38 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
uniqueConstraints: uniqueConstraints.map(toStringArray)
)
}
/**
Initializes an `Entity`.
```
Entity(Animal.self, "Animal")
```
- parameter type: the `DynamicObject` type associated with the entity
- parameter entityName: the `NSEntityDescription` name to use for the entity
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = []) {
let meta = O.meta
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
return $0.map {
return (meta[keyPath: $0] as! AnyDynamicKeyPath).cs_keyPathString
}
}
super.init(
type: type,
entityName: entityName,
isAbstract: isAbstract,
versionHashModifier: versionHashModifier,
indexes: indexes.map(toStringArray),
uniqueConstraints: []
)
}
}

View File

@@ -71,18 +71,20 @@ public protocol FetchableSource: class {
- 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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> D?
func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> D?
/**
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 `DynamicObject` instance that satisfies the specified `FetchClause`s
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> D?
func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> D?
/**
Fetches the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
@@ -94,27 +96,30 @@ public protocol FetchableSource: class {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) -> B.ObjectType?
func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> B.ObjectType?
/**
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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [D]?
func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [D]
/**
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 `DynamicObject` instances that satisfy the specified `FetchClause`s
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [D]?
func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [D]
/**
Fetches all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
@@ -126,27 +131,30 @@ public protocol FetchableSource: class {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]?
func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [B.ObjectType]
/**
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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> Int?
func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> Int
/**
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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the number of `DynamicObject`s that satisfy the specified `FetchClause`s
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> Int?
func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> Int
/**
Fetches the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
@@ -158,27 +166,30 @@ public protocol FetchableSource: class {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the number `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int?
func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> Int
/**
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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> NSManagedObjectID?
func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> NSManagedObjectID?
/**
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 `DynamicObject` that satisfies the specified `FetchClause`s
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID?
func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> NSManagedObjectID?
/**
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
@@ -190,27 +201,30 @@ public protocol FetchableSource: class {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`, or `nil` if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) -> NSManagedObjectID?
func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> NSManagedObjectID?
/**
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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]?
func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) throws -> [NSManagedObjectID]
/**
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 `DynamicObject`s that satisfy the specified `FetchClause`s
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]?
func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [NSManagedObjectID]
/**
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
@@ -222,9 +236,10 @@ public protocol FetchableSource: class {
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`, or an empty array if no match was found
- throws: `CoreStoreError.persistentStoreNotFound` if the specified entity could not be found in any store's schema.
*/
func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) -> [NSManagedObjectID]?
func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) throws -> [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.

View File

@@ -86,9 +86,13 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
return
}
self.deletedSections = []
self.insertedSections = []
if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *) {}
else {
self.deletedSections = []
self.insertedSections = []
}
self.handler?.controllerWillChangeContent(controller)
}
@@ -115,6 +119,18 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
return
}
if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *) {
self.handler?.controller(
controller,
didChangeObject: anObject,
atIndexPath: indexPath,
forChangeType: type,
newIndexPath: newIndexPath
)
return
}
guard var actualType = NSFetchedResultsChangeType(rawValue: type.rawValue) else {
@@ -129,15 +145,11 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
// https://forums.developer.apple.com/message/9998#9998
// https://forums.developer.apple.com/message/31849#31849
if #available(iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
// I don't know if iOS 10 even attempted to fix this mess...
if case .update = actualType,
indexPath != nil,
newIndexPath != nil {
actualType = .move
}
if case .update = actualType,
indexPath != nil,
newIndexPath != nil {
actualType = .move
}
switch actualType {
@@ -185,10 +197,6 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
)
return
}
guard #available(iOS 9.0, tvOS 9.0, watchOS 3.0, *) else {
return
}
self.handler?.controller(
controller,
didChangeObject: anObject,
@@ -218,12 +226,16 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
return
}
switch type {
case .delete: self.deletedSections.insert(sectionIndex)
case .insert: self.insertedSections.insert(sectionIndex)
default: break
if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *) {}
else {
switch type {
case .delete: self.deletedSections.insert(sectionIndex)
case .insert: self.insertedSections.insert(sectionIndex)
default: break
}
}
self.handler?.controller(

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - From
public extension From {
extension From {
/**
Creates a `FetchChainBuilder` that starts with the specified `Where` clause
@@ -65,6 +65,17 @@ public extension From {
return self.fetchChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Creates a `FetchChainBuilder` that starts with the specified `OrderBy` clause.
- parameter clause: the `OrderBy` clause to create a `FetchChainBuilder` with
- returns: a `FetchChainBuilder` that starts with the specified `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> FetchChainBuilder<D> {
return self.fetchChain(appending: clause)
}
/**
Creates a `FetchChainBuilder` with a series of `SortKey`s
@@ -77,6 +88,17 @@ public extension From {
return self.fetchChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Creates a `FetchChainBuilder` with a series of `SortKey`s
- parameter sortKeys: a series of `SortKey`s
- returns: a `FetchChainBuilder` with a series of `SortKey`s
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> FetchChainBuilder<D> {
return self.fetchChain(appending: OrderBy<D>(sortKeys))
}
/**
Creates a `FetchChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -215,7 +237,10 @@ public extension From {
}
}
public extension From where D: NSManagedObject {
// MARK: - From where D: NSManagedObject
extension From where D: NSManagedObject {
/**
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
@@ -255,7 +280,10 @@ public extension From where D: NSManagedObject {
}
}
public extension From where D: CoreStoreObject {
// MARK: - From where D: CoreStoreObject
extension From where D: CoreStoreObject {
/**
Creates a `FetchChainBuilder` that starts with the specified `Where` clause
@@ -267,6 +295,11 @@ public extension From where D: CoreStoreObject {
return self.fetchChain(appending: clause(D.meta))
}
public func `where`(combinedByAnd clause: Where<D>, _ others: Where<D>...) -> FetchChainBuilder<D> {
return self.fetchChain(appending: ([clause] + others).combinedByAnd())
}
/**
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
@@ -417,7 +450,10 @@ public extension From where D: CoreStoreObject {
}
}
public extension FetchChainBuilder {
// MARK: - FetchChainBuilder
extension FetchChainBuilder {
/**
Adds a `Where` clause to the `FetchChainBuilder`
@@ -453,6 +489,17 @@ public extension FetchChainBuilder {
return self.fetchChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Adds an `OrderBy` clause to the `FetchChainBuilder`
- parameter clause: the `OrderBy` clause to add
- returns: a new `FetchChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> FetchChainBuilder<D> {
return self.fetchChain(appending: clause)
}
/**
Adds an `OrderBy` clause to the `FetchChainBuilder`
@@ -465,6 +512,17 @@ public extension FetchChainBuilder {
return self.fetchChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Adds an `OrderBy` clause to the `FetchChainBuilder`
- parameter sortKeys: a series of `SortKey`s
- returns: a new `FetchChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> FetchChainBuilder<D> {
return self.fetchChain(appending: OrderBy<D>(sortKeys))
}
/**
Adds a `Tweak` clause to the `FetchChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -519,7 +577,10 @@ public extension FetchChainBuilder {
}
}
public extension FetchChainBuilder where D: CoreStoreObject {
// MARK: - FetchChainBuilder where D: CoreStoreObject
extension FetchChainBuilder where D: CoreStoreObject {
public func `where`<T: AnyWhereClause>(_ clause: (D) -> T) -> FetchChainBuilder<D> {
@@ -527,7 +588,10 @@ public extension FetchChainBuilder where D: CoreStoreObject {
}
}
public extension QueryChainBuilder {
// MARK: - QueryChainBuilder
extension QueryChainBuilder {
/**
Adds a `Where` clause to the `QueryChainBuilder`
@@ -563,6 +627,17 @@ public extension QueryChainBuilder {
return self.queryChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Adds an `OrderBy` clause to the `QueryChainBuilder`
- parameter clause: the `OrderBy` clause to add
- returns: a new `QueryChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> QueryChainBuilder<D, R> {
return self.queryChain(appending: clause)
}
/**
Adds an `OrderBy` clause to the `QueryChainBuilder`
@@ -575,6 +650,17 @@ public extension QueryChainBuilder {
return self.queryChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Adds an `OrderBy` clause to the `QueryChainBuild`
- parameter sortKeys: a series of `SortKey`s
- returns: a new `QueryChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> QueryChainBuilder<D, R> {
return self.queryChain(appending: OrderBy<D>(sortKeys))
}
/**
Adds a `Tweak` clause to the `QueryChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -665,7 +751,10 @@ public extension QueryChainBuilder {
}
}
public extension QueryChainBuilder where D: NSManagedObject {
// MARK: - QueryChainBuilder where D: NSManagedObject
extension QueryChainBuilder where D: NSManagedObject {
/**
Adds a `GroupBy` clause to the `QueryChainBuilder`
@@ -679,7 +768,10 @@ public extension QueryChainBuilder where D: NSManagedObject {
}
}
public extension QueryChainBuilder where D: CoreStoreObject {
// MARK: - QueryChainBuilder where D: CoreStoreObject
extension QueryChainBuilder where D: CoreStoreObject {
/**
Adds a `Where` clause to the `QueryChainBuilder`
@@ -737,8 +829,11 @@ public extension QueryChainBuilder where D: CoreStoreObject {
}
}
// MARK: - SectionMonitorChainBuilder
@available(macOS 10.12, *)
public extension SectionMonitorChainBuilder {
extension SectionMonitorChainBuilder {
/**
Adds a `Where` clause to the `SectionMonitorChainBuilder`
@@ -774,6 +869,17 @@ public extension SectionMonitorChainBuilder {
return self.sectionMonitorChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
- parameter clause: the `OrderBy` clause to add
- returns: a new `SectionMonitorChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> SectionMonitorChainBuilder<D> {
return self.sectionMonitorChain(appending: clause)
}
/**
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
@@ -786,6 +892,17 @@ public extension SectionMonitorChainBuilder {
return self.sectionMonitorChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
- parameter sortKeys: a series of `SortKey`s
- returns: a new `SectionMonitorChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> SectionMonitorChainBuilder<D> {
return self.sectionMonitorChain(appending: OrderBy<D>(sortKeys))
}
/**
Adds a `Tweak` clause to the `SectionMonitorChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -842,8 +959,11 @@ public extension SectionMonitorChainBuilder {
}
}
// MARK: - SectionMonitorChainBuilder where D: CoreStoreObject
@available(macOS 10.12, *)
public extension SectionMonitorChainBuilder where D: CoreStoreObject {
extension SectionMonitorChainBuilder where D: CoreStoreObject {
/**
Adds a `Where` clause to the `SectionMonitorChainBuilder`

View File

@@ -139,29 +139,40 @@ public struct From<D: DynamicObject> {
self.findPersistentStores = findPersistentStores
}
internal func applyToFetchRequest<ResultType>(_ fetchRequest: NSFetchRequest<ResultType>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) -> Bool {
internal func applyToFetchRequest<U>(_ fetchRequest: CoreStoreFetchRequest<U>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) throws {
fetchRequest.entity = context.parentStack!.entityDescription(for: EntityIdentifier(self.entityClass))!
guard applyAffectedStores else {
return true
return
}
if self.applyAffectedStoresForFetchedRequest(fetchRequest, context: context) {
return true
do {
try self.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
}
catch let error as CoreStoreError {
CoreStore.log(
error,
"Attempted to perform a fetch but could not find any persistent store for the entity \(cs_typeName(fetchRequest.entityName))"
)
throw error
}
catch {
throw error
}
CoreStore.log(
.warning,
message: "Attempted to perform a fetch but could not find any persistent store for the entity \(cs_typeName(fetchRequest.entityName))"
)
return false
}
internal func applyAffectedStoresForFetchedRequest<U>(_ fetchRequest: NSFetchRequest<U>, context: NSManagedObjectContext) -> Bool {
internal func applyAffectedStoresForFetchedRequest<U>(_ fetchRequest: CoreStoreFetchRequest<U>, context: NSManagedObjectContext) throws {
let stores = self.findPersistentStores(context)
fetchRequest.affectedStores = stores
return stores?.isEmpty == false
if stores?.isEmpty == false {
return
}
throw CoreStoreError.persistentStoreNotFound(entity: self.entityClass)
}

View File

@@ -103,7 +103,7 @@ public struct GroupBy<D: DynamicObject>: GroupByClause, QueryClause, Hashable {
}
}
public extension GroupBy where D: NSManagedObject {
extension GroupBy where D: NSManagedObject {
/**
Initializes a `GroupBy` clause with a key path
@@ -116,7 +116,7 @@ public extension GroupBy where D: NSManagedObject {
}
}
public extension GroupBy where D: CoreStoreObject {
extension GroupBy where D: CoreStoreObject {
/**
Initializes a `GroupBy` clause with a key path

View File

@@ -34,7 +34,8 @@ import CoreData
/**
A storage interface backed by an SQLite database managed by iCloud.
*/
public final class ICloudStore: CloudStorage {
@available(*, deprecated, message: "Please see the release notes and Core Data documentation.")
public final class ICloudStore: CloudStorage, CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
/**
Initializes an iCloud store interface from the given ubiquitous store information. Returns `nil` if the container could not be located or if iCloud storage is unavailable for the current user or device
@@ -446,6 +447,65 @@ public final class ICloudStore: CloudStorage {
)
}
}
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
func formattedValue(_ any: Any) -> String {
switch any {
case let any as CoreStoreDebugStringConvertible:
return any.coreStoreDumpString
default:
return "\(any)"
}
}
var string = "(\(String(reflecting: type(of: self)))) "
string.append(formattedValue(self))
return string
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
func formattedValue(_ any: Any) -> String {
switch any {
case let any as CoreStoreDebugStringConvertible:
return any.coreStoreDumpString
default:
return "\(any)"
}
}
func createFormattedString(_ firstLine: String, _ lastLine: String, _ info: [(key: String, value: Any)]) -> String {
var string = firstLine
for (key, value) in info {
string.append("\n.\(key) = \(formattedValue(value));")
}
string = string.replacingOccurrences(of: "\n", with: "\n\(String(repeating: " ", count: 4))")
string.append("\n\(lastLine)")
return string
}
return createFormattedString(
"(", ")",
[
("configuration", self.configuration as Any),
("storeOptions", self.storeOptions as Any),
("cacheFileURL", self.cacheFileURL),
("cloudStorageOptions", self.cloudStorageOptions)
]
)
}
// MARK: Private
@@ -494,7 +554,7 @@ public final class ICloudStore: CloudStorage {
// MARK: - Notification Keys
fileprivate extension Notification.Name {
extension Notification.Name {
fileprivate static let iCloudUbiquitousStoreWillFinishInitialImport = Notification.Name(rawValue: "iCloudUbiquitousStoreWillFinishInitialImport")
fileprivate static let iCloudUbiquitousStoreDidFinishInitialImport = Notification.Name(rawValue: "iCloudUbiquitousStoreDidFinishInitialImport")

Some files were not shown because too many files have changed in this diff Show More