Compare commits

...

279 Commits

Author SHA1 Message Date
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
John Estropia
20d581d536 version bump 2018-09-19 18:48:45 +09:00
John Estropia
45e110755d deleted unnecessary Equatable and Hashable custom implementations 2018-09-19 11:06:19 +09:00
John Estropia
ab40532801 fix issue with early-deallocated CoreStoreObjects 2018-09-18 23:50:14 +09:00
John Estropia
40f458a09c Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2018-09-15 12:56:21 +09:00
John Estropia
1ad233ca9d Swift 4.2 support 2018-09-15 12:56:08 +09:00
John Estropia
3a8e394272 Merge pull request #269 from congbach/develop
Fixed bug where ListObjectObserver didUpdateObject was not called on …
2018-09-10 19:30:06 +09:00
Ken Bach
1f54daa528 Fixed bug where ListObjectObserver.didUpdateObject was not called on watchos. 2018-08-21 22:47:54 +01:00
John Estropia
f25879b6fe fix compile error on tvOS and watchOS 2018-08-09 21:04:09 +09:00
John Estropia
8fa3109e91 version bump 2018-08-09 20:45:46 +09:00
John Estropia
808e8ff97a stabilize NSProgress when lightweight migration falls back to InferredMappingModel 2018-08-09 18:18:21 +09:00
John Estropia
30685d4355 Use InferredMappingModel in case lightweight migration fails for some reason 2018-08-09 02:09:54 +09:00
John Estropia
7152962026 revert 2018-08-09 01:39:16 +09:00
John Estropia
91735e38d1 Fix issue where CoreStoreObjects nested in a type is mismatching classnames before migration 2018-08-08 23:52:47 +09:00
John Estropia
333a50ad9e Merge pull request #256 from vGubriienko/demo-fix
Fixed issue with brightness observing in the Demo
2018-08-03 17:44:40 +09:00
John Rommel Estropia
b7a602fc67 iOS 11 Core Data changes 2018-07-29 23:33:51 +09:00
Viktor Gubriienko
2ff7ecef96 Fixed issue with brightness observing in the Demo 2018-06-12 17:53:00 +03:00
John Rommel Estropia
e3f9139304 version bump 2018-06-10 11:52:47 +09:00
John Rommel Estropia
4aa461872f specify swift version in podspec 2018-06-10 11:47:03 +09:00
John Rommel Estropia
3d43314076 update readme 2018-04-14 09:05:13 +09:00
John Rommel Estropia
7b1075b759 support compound indexes and unique constraints on CoreStore properties 2018-03-17 23:56:42 +09:00
John Rommel Estropia
0c29e07ddb support allowsExternalBinaryDataStorage option on Transformable CoreStoreObject properties 2018-03-17 23:56:01 +09:00
John Rommel Estropia
ce91cf22f9 Swift 4.1 support 2018-03-17 23:53:24 +09:00
John Rommel Estropia
2dd033c002 Merge branch 'develop' into prototype/Swift_4_1 2018-03-10 21:09:29 +09:00
John Rommel Estropia
c7fcba112e Fix bug where ListMonitor sectionIndexTitles are not updated on refetch (fixes #218) 2018-03-10 21:09:18 +09:00
John Rommel Estropia
c8b1c4358f Fix bug where ListMonitor sectionIndexTitles are not updated on refetch (fixes #218) 2018-03-10 21:08:40 +09:00
John Rommel Estropia
5431e2e974 Swift 4.1 support 2018-03-10 21:07:53 +09:00
John Rommel Estropia
83e6082c56 Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2018-01-07 23:25:11 +09:00
John Rommel Estropia
c7bdbbde57 convert value to native type before formatting predicates 2018-01-07 21:06:35 +09:00
John Estropia
abf15c8aa8 Merge pull request #232 from kf99916/external-storage-migration
External storage migration
2018-01-06 17:48:38 +09:00
Zheng-Xiang Ke
d9db7e4a82 Typo 2018-01-06 15:00:53 +08:00
John Estropia
65dbc22ddd Merge pull request #231 from doodzik/patch-1
Fix syntax error in readme
2018-01-06 15:11:48 +09:00
Zheng-Xiang Ke
51961dd737 Migrate external storage 2018-01-06 10:22:44 +08:00
Frederik Dudzik
18a7055cdf Fix syntax error 2018-01-05 21:16:04 +01:00
John Rommel Estropia
4b9fddad6a Merge branch 'develop' 2017-12-29 01:09:07 +09:00
John Rommel Estropia
fbe7bd7bf8 update podfile 2017-12-29 00:53:48 +09:00
John Rommel Estropia
15edabdbb5 changed keyPath string utility to use String initializer 2017-12-29 00:05:11 +09:00
John Rommel Estropia
f447bcfb95 Merge branch 'develop' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/DataStack+Migration.swift
#	Sources/Info.plist
2017-11-19 15:35:29 +09:00
John Rommel Estropia
15e5e4fdf6 delete shm file after converting to DELETE journal mode 2017-11-19 15:34:09 +09:00
John Rommel Estropia
583c6b7249 minor code cleanup 2017-11-19 13:49:21 +09:00
John Rommel Estropia
18b933957e version bump 2017-11-16 02:28:18 +09:00
John Rommel Estropia
2c7039232e merge sqlite journal files before migration 2017-11-16 02:27:06 +09:00
John Rommel Estropia
d3b3b5ff4a added fake progress for lightweight migrations 2017-11-16 02:26:56 +09:00
John Rommel Estropia
d90e8d1303 force true lightweight migration 2017-11-16 02:26:44 +09:00
John Rommel Estropia
b55dd13dff merge sqlite journal files before migration 2017-11-15 23:50:10 +09:00
John Rommel Estropia
66dd5b6f27 added fake progress for lightweight migrations 2017-11-13 02:44:26 +09:00
John Estropia
49c4b770eb WIP: Readme 2017-11-10 19:19:48 +09:00
John Rommel Estropia
662aaa1e75 force true lightweight migration 2017-11-10 02:48:37 +09:00
John Rommel Estropia
dd4e47d7f9 revert null overloads, remove optional objectIDs as condition 2017-11-09 23:26:53 +09:00
John Estropia
9ea5073bc8 Merge branch 'master' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-11-09 19:52:29 +09:00
John Estropia
e314db8f56 version bump 2017-11-09 19:45:21 +09:00
John Estropia
48d936d068 Fix regression for ARC bugfix (fixes #221) 2017-11-09 19:44:27 +09:00
John Estropia
b2ff8a15ef add query overloads to == so comparison with nil don't confuse the compiler 2017-11-09 19:27:56 +09:00
John Estropia
8a4d1cd7c6 fix demo app warnings 2017-11-09 19:27:05 +09:00
John Rommel Estropia
8ce26c213d more source docs, deprecated some Where clause utilities 2017-11-04 10:37:54 +09:00
John Estropia
f3816b9abf update for Xcode 9.1 2017-11-01 19:49:42 +09:00
John Estropia
21961780d4 force dynamic typing on DynamicObject.Type to mitigate optimization issues 2017-11-01 19:38:38 +09:00
John Rommel Estropia
305e2b61a0 fix compile errors for Xcode 9.1 beta 2017-11-01 19:37:53 +09:00
John Estropia
0430f66240 force dynamic typing on DynamicObject.Type to mitigate optimization issues 2017-11-01 11:33:41 +09:00
John Estropia
65772edd00 Merge pull request #208 from volodg/prototype/Swift_4_0
(Xcode 9.1) fix compile error:
2017-10-29 18:55:13 +09:00
John Rommel Estropia
02d7870d75 fix compile errors for Xcode 9.1 beta 2017-10-29 15:20:58 +09:00
John Rommel Estropia
aca1709e13 WIP: documentation 2017-10-29 15:06:57 +09:00
John Rommel Estropia
b6ee0b014f WIP: documentations 2017-10-24 00:31:27 +09:00
John Estropia
e37186da73 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-10-17 13:42:04 +09:00
John Estropia
588fa35c84 version bump 2017-10-17 13:39:57 +09:00
John Estropia
f6614cda66 Merge branch 'develop' 2017-10-17 13:39:20 +09:00
John Estropia
639574d8c2 remove inline casts because optimized builds seem to trip on them 2017-10-17 13:38:25 +09:00
John Rommel Estropia
094703155c Merge branch 'master' into prototype/Swift_4_0
# Conflicts:
#	.swift-version
2017-10-13 08:14:20 +09:00
John Rommel Estropia
6dd254e713 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-10-13 08:10:56 +09:00
John Rommel Estropia
204025721c version bump 2017-10-13 08:10:26 +09:00
John Rommel Estropia
27ffc1d225 Merge branch 'develop'
# Conflicts:
#	CoreStore.podspec
#	Sources/Info.plist
2017-10-13 08:01:30 +09:00
John Rommel Estropia
ba6f0c39d5 swift version 3.2 2017-10-13 08:00:39 +09:00
John Rommel Estropia
ab2eac8f6c Swift 3.2 README update 2017-10-13 07:58:37 +09:00
John Rommel Estropia
f460a0b30f CI: test demo app 2017-10-12 01:10:08 +09:00
John Rommel Estropia
50bc3ace06 travis 2017-10-12 00:02:39 +09:00
John Rommel Estropia
d2ddf2002f version update 2017-10-11 22:40:27 +09:00
John Rommel Estropia
b4117eeb02 updated documentation (fixes #198) 2017-10-11 07:50:24 +09:00
Vladimir
106275b2dd fix compile error:
inheritance from 'AnyObject'
2017-10-07 12:21:27 +08:00
John Rommel Estropia
08d9298be0 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	Sources/OrderBy.swift
2017-10-07 01:13:30 +09:00
John Rommel Estropia
ff0c4d94fc Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-10-07 01:10:28 +09:00
John Rommel Estropia
50e50c0613 Merge branch 'develop' into prototype/Swift_3_2 2017-10-07 01:07:09 +09:00
John Rommel Estropia
5c8a0e425b version bump 2017-10-07 00:59:37 +09:00
John Rommel Estropia
03b71caf7e Merge branch 'develop' 2017-10-07 00:58:04 +09:00
John Rommel Estropia
7ff29d6086 version bump 2017-10-07 00:57:41 +09:00
John Rommel Estropia
8d86425875 always create subclass type from cs_rawObject 2017-10-07 00:56:19 +09:00
John Estropia
97242d9726 added type-erasers for CoreStoreObject property containers 2017-10-02 12:00:45 +09:00
John Estropia
780ff4e60b fix compile errors 2017-10-02 11:10:28 +09:00
John Estropia
11743dfb5f oops 2017-10-02 11:08:44 +09:00
John Estropia
9eaf85388c relax generic type requirements for some Where utilities 2017-10-02 10:33:59 +09:00
John Rommel Estropia
06635c9d2f orderby utilities 2017-10-02 08:04:28 +09:00
John Rommel Estropia
1d2eef7894 revert 2017-10-01 01:01:10 +09:00
John Rommel Estropia
85ed815ec2 WIP: more chain clause builder utilities 2017-10-01 00:45:21 +09:00
John Estropia
096e5493a6 WIP: protocol cleanup 2017-09-29 20:33:10 +09:00
John Estropia
0aa8c03424 Merge pull request #205 from jannon/case-insensitive-orderby
add case-insensitive sortkeys
2017-09-29 19:38:36 +09:00
John Estropia
4ead3c34dd delete errant operator 2017-09-26 11:59:28 +09:00
John Rommel Estropia
645034dde5 keyPath utilities for SectionBy clauses 2017-09-24 10:38:17 +09:00
John Rommel Estropia
85706a3c57 version bump 2017-09-22 23:43:19 +09:00
John Rommel Estropia
c5ae4606b9 move cocoapods.yml 2017-09-22 23:41:07 +09:00
John Rommel Estropia
fa682215c5 version bump 2017-09-22 23:26:15 +09:00
John Rommel Estropia
e814733ae9 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	Sources/DynamicObject.swift
2017-09-22 23:20:16 +09:00
John Rommel Estropia
e2236698fa Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-09-22 23:18:38 +09:00
John Rommel Estropia
be5da632b3 fix segmentation fault 2017-09-22 23:18:25 +09:00
John Estropia
dc73cd6dd9 added a yml file for pod try (#200) 2017-09-22 15:48:02 +09:00
John Rommel Estropia
7beb3bec75 rename methods 2017-09-22 08:02:13 +09:00
Jannon Frank
53100b202d add case-insensitive sortkeys 2017-09-21 11:38:29 -07:00
John Rommel Estropia
cc84b1f8bd minor 2017-09-22 01:00:03 +09:00
John Rommel Estropia
474f52ed2b alow nil comparison for relationship keypaths 2017-09-22 00:30:02 +09:00
John Rommel Estropia
16225fc4c6 allow optionals in relationship keyPaths 2017-09-22 00:20:55 +09:00
John Rommel Estropia
03bb7619da added queryBuilder utilities for clause sequences 2017-09-22 00:08:01 +09:00
John Rommel Estropia
1bfb7451c3 keyPath utilities for Select queries 2017-09-21 07:56:02 +09:00
John Rommel Estropia
3e082d5ed4 queryBuilders for list monitors 2017-09-20 00:45:38 +09:00
John Rommel Estropia
e45d67252c CoreStore querying utilities 2017-09-20 00:24:03 +09:00
John Rommel Estropia
3d427c29c4 added required settings 2017-09-20 00:09:57 +09:00
John Rommel Estropia
1068517b94 Merge branch 'prototype/queryBuilders' of github.com:JohnEstropia/CoreStore into prototype/queryBuilders 2017-09-20 00:02:36 +09:00
John Estropia
0d23ce1598 fix Demo app compiler errors 2017-09-19 16:22:59 +09:00
John Estropia
fd1ce20863 set swift version 2017-09-19 16:04:26 +09:00
John Estropia
2c5fa63f40 revert 2017-09-19 15:55:51 +09:00
John Estropia
78e43a37a5 fix OSX compiler errors 2017-09-19 15:54:15 +09:00
John Rommel Estropia
fde85a9743 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-09-17 01:15:55 +09:00
John Rommel Estropia
dbbc0adae5 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-09-17 01:10:11 +09:00
John Rommel Estropia
2a62770552 Merge branch 'develop' into prototype/Swift_3_2 2017-09-10 12:31:30 +09:00
John Rommel Estropia
f436b26e8e allow compound keypaths in Select terms 2017-09-08 01:28:24 +09:00
John Rommel Estropia
c566226747 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-08-31 23:50:12 +09:00
John Rommel Estropia
cd405e038e updated demo app 2017-08-31 23:00:17 +09:00
John Estropia
92a37053b0 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-08-31 18:33:28 +09:00
John Estropia
0b57cff27d Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	Sources/DynamicSchema+Convenience.swift
2017-08-31 18:33:12 +09:00
John Estropia
3ebc44b546 optimize redundant casting in printCoreStoreSchema() 2017-08-31 18:28:23 +09:00
John Estropia
68f1027ba7 fix code misuse in readme 2017-08-31 17:55:10 +09:00
John Rommel Estropia
005729be85 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-08-26 14:29:16 +09:00
John Estropia
8bac4aa901 Fixed Xcode 9 beta 6 errors 2017-08-24 10:11:12 +09:00
John Estropia
da170c7e51 Fixed Xcode 9 beta 6 errors 2017-08-23 18:40:06 +09:00
John Estropia
211e69023e version bump 2017-08-23 12:59:36 +09:00
John Rommel Estropia
2912dcf010 iOS 11 fixed the NSFetchRequest.affectedStores bug 2017-08-23 12:55:02 +09:00
John Rommel Estropia
3e00a3da06 fix demo app errors 2017-08-17 09:24:33 +09:00
John Rommel Estropia
a33e248828 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	Sources/NSManagedObjectContext+Querying.swift
2017-08-16 21:09:09 +09:00
John Rommel Estropia
75e14fbbed Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0
# Conflicts:
#	Sources/NSManagedObjectContext+Querying.swift
2017-08-16 21:08:33 +09:00
John Rommel Estropia
9922deac4d Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	Sources/AttributeProtocol.swift
#	Sources/DynamicSchema+Convenience.swift
#	Sources/ImportableAttributeType.swift
#	Sources/Relationship.swift
#	Sources/RelationshipProtocol.swift
#	Sources/Transformable.swift
#	Sources/Value.swift
2017-08-16 21:07:34 +09:00
John Rommel Estropia
86be046c9f updated podspec 2017-08-16 20:43:10 +09:00
John Rommel Estropia
0f10bc3349 version bump 2017-08-16 20:26:22 +09:00
John Rommel Estropia
9685f0aef2 #191 2017-08-16 20:21:26 +09:00
John Estropia
1e51000155 Merge pull request #191 from sidmani/prototype/Swift_4_0
Corrected type-checking in fetchExisting to preserve input type
2017-08-16 20:20:23 +09:00
John Rommel Estropia
3bd459bb1a updated docs 2017-08-16 20:09:09 +09:00
Sid Mani
c89bc3c227 Corrected type-checking in fetchExisting to preserve input type 2017-08-16 00:36:06 -07:00
John Rommel Estropia
0f405a50aa WIP: KeyPath utilities for all clauses 2017-08-10 00:42:29 +09:00
John Estropia
f5e1643ef7 minor cleanup 2017-08-10 00:10:15 +09:00
John Rommel Estropia
f62137fb58 rename file 2017-08-10 00:10:08 +09:00
John Rommel Estropia
37fbedd799 WIP: keypath utilities for all raw clauses 2017-08-09 08:11:41 +09:00
John Rommel Estropia
28b43f33fa Value.Required now requires an "initial:" parameter. For previous CoreStoreObject users, use the appropriate empty value for your existing properties (0 for numeric types, false for Bool, "" for String) 2017-08-08 18:36:25 +09:00
John Rommel Estropia
81a72f29ea Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders 2017-08-08 08:02:17 +09:00
John Rommel Estropia
f7aaf4fb2a Fix compile errors for Xcode 9 beta 5 2017-08-08 08:02:05 +09:00
John Rommel Estropia
a52acf2ebd Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-08-08 07:56:32 +09:00
John Rommel Estropia
74c64619c3 Fix compile error for Xcode 9 beta 5 2017-08-08 07:56:21 +09:00
John Rommel Estropia
4a5bc6450b complete query utilities 2017-08-08 07:36:52 +09:00
John Rommel Estropia
fe69e7c6c4 Merge branch 'prototype/Swift_4_0' into prototype/queryBuilders
# Conflicts:
#	CoreStore.xcodeproj/project.pbxproj
#	Sources/Relationship.swift
#	Sources/Value.swift
2017-08-05 23:02:00 +09:00
John Rommel Estropia
ccf7c62aad Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-08-05 08:25:49 +09:00
John Rommel Estropia
f36cb8af63 iOS 11 fixed the NSFetchRequest.affectedStores bug 2017-08-05 08:25:28 +09:00
John Rommel Estropia
10ccadd96c update demo app 2017-08-05 08:25:03 +09:00
John Rommel Estropia
5c0e78bd53 Deleted EmptyableAttributeType and require "initial" parameter for Value.Required 2017-08-05 00:03:17 +09:00
John Rommel Estropia
8a09688117 Merge branch 'develop' into prototype/Swift_3_2 2017-07-15 21:30:05 +09:00
John Estropia
a366bcf1a3 Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop 2017-07-11 15:47:20 +09:00
John Rommel Estropia
fcd4be9011 WIP: chained queries for section monitors 2017-07-10 08:23:59 +09:00
John Rommel Estropia
535eb76adc WIP: query chains! 2017-07-09 10:44:53 +09:00
John Rommel Estropia
c6e68ac24f reset transactions' context on deinit to break reference cycles in unsafed many-to-many relationships 2017-07-05 23:32:45 +09:00
John Rommel Estropia
aff966aac9 WIP: Query builders 2017-07-05 08:45:10 +09:00
John Rommel Estropia
32743b3aee Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-07-04 23:16:49 +09:00
John Rommel Estropia
a20ad87583 Merge branch 'develop' into prototype/Swift_3_2 2017-07-04 23:14:06 +09:00
John Estropia
a11915db12 minor cleanup 2017-07-04 12:21:46 +09:00
John Rommel Estropia
961f39a806 add internal utilities to force checkpoint operations on SQLite 2017-07-01 17:05:10 +09:00
John Rommel Estropia
3096cb784c add internal utilities to force checkpoint operations on SQLite 2017-07-01 16:45:11 +09:00
John Rommel Estropia
809aa4ff96 allow querying file size on SQLiteStore 2017-07-01 11:50:23 +09:00
John Estropia
8d926d25ec Merge pull request #177 from blender/feature/optional-where-chaining
Add optional && and || operators to Where clause
2017-06-28 13:32:16 +09:00
Tommaso Piazza
790454f514 Add optional && and || operators to Where clause 2017-06-27 13:58:16 +02:00
John Rommel Estropia
9a38707c58 Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-26 00:36:07 +09:00
John Rommel Estropia
fb7e2f7f7f Merge branch 'develop' into prototype/Swift_3_2 2017-06-26 00:34:32 +09:00
John Rommel Estropia
f72efc80b2 added utilities for combining Where arrays and OrderBy arrays 2017-06-24 17:42:56 +09:00
John Estropia
fcda5399da Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-23 17:58:49 +09:00
John Estropia
fd3a9b00ec fix FRC breaking again for iOS 8 2017-06-23 17:58:34 +09:00
John Estropia
f56c37f9ee Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-23 12:43:20 +09:00
John Estropia
5f5000218a Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/Palette.swift
#	Sources/Value.swift
2017-06-23 12:43:03 +09:00
John Estropia
e8eb309d82 Added source docs on usage of custom getters and setters for CoreStoreObject properties (Value.Required, etc) 2017-06-20 20:32:27 +09:00
John Rommel Estropia
d0c3203e63 force reset contexts after autocommit 2017-06-17 21:50:21 +09:00
John Rommel Estropia
f5b3901caa fix tests and demo app 2017-06-17 02:13:54 +09:00
John Rommel Estropia
1a99fea820 complete PartialObject utilities 2017-06-17 01:55:36 +09:00
John Rommel Estropia
195b60615b added missing utilities 2017-06-16 01:42:09 +09:00
John Rommel Estropia
2c394965b8 remove direct access to CoreStoreObject.primitiveValues and replace PartialObject<O> 2017-06-16 01:02:23 +09:00
John Rommel Estropia
746d697691 WIP: new PartialObject to act as faster KVC wrappers when implementing custom getters and setters for CoreStoreObject 2017-06-15 08:27:08 +09:00
John Estropia
5689158b43 version bump 2017-06-14 21:50:58 +09:00
John Estropia
6fcdf3d011 fix logger demo 2017-06-14 17:43:34 +09:00
John Estropia
e26573c18e converted the Demo app's observer demo to use CoreStoreObject instead of NSManagedObject 2017-06-14 17:39:57 +09:00
John Estropia
801cf8d9f0 Fixed ListMonitor bug for CoreStoreObjects where ListObservers don't get update notifications 2017-06-14 17:37:46 +09:00
John Rommel Estropia
eced8f2e93 fixed compile error on release mode 2017-06-12 22:39:06 +09:00
John Rommel Estropia
3b735d07ec fix merge compile errors 2017-06-11 09:33:25 +09:00
John Rommel Estropia
5eb5476e3a Merge branch 'prototype/Swift_3_2' into prototype/Swift_4_0 2017-06-11 09:17:03 +09:00
John Rommel Estropia
6a42a0054e Merge branch 'develop' into prototype/Swift_3_2
# Conflicts:
#	Sources/CoreStoreManagedObject.swift
#	Sources/CoreStoreSchema.swift
#	Sources/NSEntityDescription+DynamicModel.swift
#	Sources/Value.swift
2017-06-11 09:16:34 +09:00
John Rommel Estropia
8c437e19b8 version bump 2017-06-10 23:19:02 +09:00
John Rommel Estropia
9cd3b6c879 code cleanup 2017-06-10 22:13:32 +09:00
John Rommel Estropia
fe135acbec Improve CoreStoreObjects KVO behavior 2017-06-10 21:02:36 +09:00
John Estropia
997c5bdcfa uniquify subclass names across model versions 2017-06-09 12:47:22 +09:00
John Estropia
23e12c4539 add constraints to Value.Optional and Value.Required native types 2017-06-09 11:30:09 +09:00
John Estropia
ca9798be14 add constraints to Value.Optional and Value.Required native types 2017-06-09 11:29:51 +09:00
John Estropia
6e01a58c85 Swift 4 support 2017-06-09 11:25:28 +09:00
John Estropia
f618617053 work around issue that crashes the Swift 3.2 compiler (fixes #171) 2017-06-08 20:18:50 +09:00
John Rommel Estropia
49b8b9c372 Merge branch 'master' into prototype/Swift_3_2 2017-06-08 08:10:59 +09:00
John Rommel Estropia
129f975d96 version bump 2017-06-08 01:17:39 +09:00
John Rommel Estropia
a2e463e58c Merge branch 'prototype/customMigrationTest' of github.com:JohnEstropia/CoreStore into prototype/customMigrationTest 2017-06-08 01:07:00 +09:00
John Rommel Estropia
5fd50f0e15 fix migration for CoreStoreObject relationships 2017-06-08 01:06:51 +09:00
John Estropia
7f9a915d71 WIP: Swift 3.2 2017-06-07 20:07:43 +09:00
John Estropia
0a81736b7a Merge branch 'develop' into prototype/customMigrationTest 2017-06-07 12:31:42 +09:00
John Estropia
f9b6dd0c6a fix bug when using ObjectMonitor with CoreStoreObjects 2017-06-06 17:40:29 +09:00
John Rommel Estropia
0354401b56 WIP: bugfix for CustomSchemaMappingProvider relationship migration bug 2017-06-06 08:39:59 +09:00
John Rommel Estropia
0304067beb fix ToManyOrdered and ToManyUnordered enumeration crash 2017-06-06 00:49:16 +09:00
John Rommel Estropia
ddd83da434 add Where comparison operators for optional values 2017-06-05 23:09:19 +09:00
John Estropia
fc7df671de Fixes https://bugs.swift.org/browse/SR-4981 2017-06-05 12:45:35 +09:00
John Rommel Estropia
5fde9030c7 use stronger namespace for CoreStoreObject's internal managed object type 2017-06-05 08:03:37 +09:00
John Rommel Estropia
d7b07b3f00 Added alternative way to set keyPathsForValuesAffectingValue(forKey:) for CoreStoreObjects 2017-06-05 01:30:26 +09:00
John Rommel Estropia
ddd1ffb29f added ~= operation to create Where clauses for value arrays 2017-06-03 08:51:52 +09:00
John Rommel Estropia
98094000bb Merge branch 'master' into develop 2017-06-02 23:10:31 +09:00
John Estropia
d5026ef996 Merge branch 'temp/develop' into develop 2017-06-02 19:35:01 +09:00
John Estropia
2cd913b9dd added more utilities for CoreStoreObject meta 2017-06-02 19:34:54 +09:00
John Estropia
ad9520abbc Update README.md 2017-06-02 13:24:15 +09:00
John Estropia
c0fc57d10c Update README.md 2017-06-02 11:34:04 +09:00
John Estropia
0cf4d303e4 Added README sample on how to version CoreStoreObjects 2017-06-02 11:32:48 +09:00
John Rommel Estropia
6de397958a fix demo app warnings 2017-06-02 02:06:47 +09:00
John Rommel Estropia
55292a84dc made mapping modell providers public 2017-06-02 02:03:41 +09:00
605 changed files with 436258 additions and 6169 deletions

2
.cocoapods.yml Normal file
View File

@@ -0,0 +1,2 @@
try:
project: 'CoreStore.xcworkspace'

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 +0,0 @@
3.1

View File

@@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode8.3
osx_image: xcode10
sudo: false
git:
submodules: false
@@ -10,24 +10,25 @@ env:
- LC_CTYPE=en_US.UTF-8
- LANG=en_US.UTF-8
matrix:
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.12 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
- 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
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.23.0/Carthage.pkg"
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.26.0/Carthage.pkg"
- sudo installer -pkg "Carthage.pkg" -target /
- rm "Carthage.pkg"
- npm install ios-sim -g
- ios-sim start --devicetypeid "com.apple.CoreSimulator.SimDeviceType.iPhone-8, 11.0"
before_script:
- carthage update --use-submodules
script:
@@ -38,8 +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 "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "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,16 +1,18 @@
Pod::Spec.new do |s|
s.name = "CoreStore"
s.version = "4.0.1"
s.version = "6.2.0"
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 = "8.0"
s.osx.deployment_target = "10.10"
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

@@ -34,7 +34,7 @@
82BA18B51C4BBD3F00A0916E /* BaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */; };
82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */; };
82BA18B71C4BBD3F00A0916E /* CoreStore+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */; };
82BA18B81C4BBD4200A0916E /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; };
82BA18B81C4BBD4200A0916E /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F011AFF847B0064E85B /* From.swift */; };
82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F031AFF847B0064E85B /* Select.swift */; };
82BA18BB1C4BBD4A00A0916E /* Where.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F051AFF847B0064E85B /* Where.swift */; };
@@ -101,6 +101,18 @@
B51FE5AF1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
B5215CA41FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
B5215CA51FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
B5215CA61FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
B5215CA71FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
B5215CA91FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
B5215CAA1FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
B5215CAB1FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
B5215CAC1FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
B5215CAF1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
B5215CB01FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
B5215CB11FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
B5220E081D0C5F8D009BC71E /* ObjectObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */; };
B5220E091D0C5F8D009BC71E /* ObjectObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */; };
B5220E0C1D0D0D19009BC71E /* ImportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5220E0B1D0D0D19009BC71E /* ImportTests.swift */; };
@@ -153,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 */; };
@@ -184,7 +192,7 @@
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */; };
B52DD1A81BE1F93200949AFE /* DataStack+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */; };
B52DD1A91BE1F93200949AFE /* CoreStore+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */; };
B52DD1AA1BE1F93500949AFE /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; };
B52DD1AA1BE1F93500949AFE /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
B52DD1AB1BE1F93900949AFE /* From.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F011AFF847B0064E85B /* From.swift */; };
B52DD1AC1BE1F93900949AFE /* Select.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F031AFF847B0064E85B /* Select.swift */; };
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F051AFF847B0064E85B /* Where.swift */; };
@@ -238,6 +246,14 @@
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
B53B275F1EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
@@ -316,6 +332,10 @@
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
B5519A621CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
B55514EA1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
B55514EB1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
B55514EC1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
B55514ED1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
B55717441D15B09E009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
B55717451D15B09F009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
B55717461D15B0A1009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -354,7 +374,7 @@
B56321921BD65216006C9394 /* BaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */; };
B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */; };
B56321941BD65216006C9394 /* CoreStore+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */; };
B56321951BD65216006C9394 /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; };
B56321951BD65216006C9394 /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
B56321961BD65216006C9394 /* From.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F011AFF847B0064E85B /* From.swift */; };
B56321971BD65216006C9394 /* Select.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F031AFF847B0064E85B /* Select.swift */; };
B56321981BD65216006C9394 /* Where.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F051AFF847B0064E85B /* Where.swift */; };
@@ -441,6 +461,24 @@
B580857A1CDF808C004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
B5831B701F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
B5831B711F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
B5831B721F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
B5831B731F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
B5831B7A1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
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 */; };
@@ -465,6 +503,10 @@
B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
B5A1DAC81F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
B5A1DAC91F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
B5A1DACA1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
B5A1DACB1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A261201B64BFDB006EB6D3 /* MigrationType.swift */; };
B5A5F2661CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
@@ -488,6 +530,14 @@
B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
B5CA2B081F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
B5CA2B091F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
B5CA2B0A1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
B5CA2B0B1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
B5CA2B121F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5CA2B131F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5CA2B141F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5CA2B151F81DBFF004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; };
B5D339B41E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
B5D339B51E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
@@ -530,6 +580,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 */; };
@@ -610,7 +662,11 @@
B5E84F361AFF85470064E85B /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
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 /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.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 */; };
@@ -729,9 +785,13 @@
B51260921E9B28F100402229 /* EntityIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntityIdentifier.swift; sourceTree = "<group>"; };
B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+CustomDebugStringConvertible.swift"; sourceTree = "<group>"; };
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFetchedResultsController+Convenience.swift"; sourceTree = "<group>"; };
B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchChainBuilder.swift; sourceTree = "<group>"; };
B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryChainBuilder.swift; sourceTree = "<group>"; };
B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionMonitorBuilder.swift; sourceTree = "<group>"; };
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>"; };
@@ -740,7 +800,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; };
@@ -752,6 +811,8 @@
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Logging.swift"; sourceTree = "<group>"; };
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PartialObject.swift; sourceTree = "<group>"; };
B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = "<group>"; };
B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = "<group>"; };
B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = "<group>"; };
@@ -776,6 +837,7 @@
B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSAsynchronousDataTransaction.swift; sourceTree = "<group>"; };
B5548CD51BD65AE00077652A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
B5548CD71BD65AE50077652A /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
B55514E91EED8BF900BAB888 /* From+Querying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "From+Querying.swift"; sourceTree = "<group>"; };
B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreStoreBridge.h; sourceTree = "<group>"; };
B559CD421CAA8B6300E4D58B /* CSSetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSetupResult.swift; sourceTree = "<group>"; };
B559CD481CAA8C6D00E4D58B /* CSStorageInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSStorageInterface.swift; sourceTree = "<group>"; };
@@ -801,19 +863,25 @@
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>"; };
B58085741CDF7F00004C2EEB /* SetupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupTests.swift; sourceTree = "<group>"; };
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributeProtocol.swift; sourceTree = "<group>"; };
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelationshipProtocol.swift; sourceTree = "<group>"; };
B5831B791F34ACBA00A9F647 /* Transformable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transformable.swift; sourceTree = "<group>"; };
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+DynamicModel.swift"; sourceTree = "<group>"; };
B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvenienceTests.swift; sourceTree = "<group>"; };
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchableSource.swift; sourceTree = "<group>"; };
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryableSource.swift; sourceTree = "<group>"; };
B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSPersistentStoreCoordinator+Setup.swift"; sourceTree = "<group>"; };
B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStore.swift; sourceTree = "<group>"; };
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyPath+Querying.swift"; sourceTree = "<group>"; };
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = "<group>"; };
B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = "<group>"; };
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_macOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_iOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionLock.swift; sourceTree = "<group>"; };
B5A9921E1EA898710091A2E3 /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = "<group>"; };
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
@@ -822,7 +890,10 @@
B5BDC9271C2024F2008147CD /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = SOURCE_ROOT; };
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = "<group>"; };
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = "<group>"; };
B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhereClauseType.swift; sourceTree = "<group>"; };
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicKeyPath.swift; sourceTree = "<group>"; };
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = "<group>"; };
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .cocoapods.yml; sourceTree = SOURCE_ROOT; };
B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicModelTests.swift; sourceTree = "<group>"; };
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreObject.swift; sourceTree = "<group>"; };
B5D339DC1E9489C700C880DE /* DynamicObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicObject.swift; sourceTree = "<group>"; };
@@ -836,6 +907,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>"; };
@@ -888,7 +961,8 @@
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Setup.swift"; sourceTree = "<group>"; };
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 /* ClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClauseTypes.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>"; };
@@ -979,6 +1053,8 @@
2F03A52619C5C6DA005002A5 = {
isa = PBXGroup;
children = (
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */,
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */,
2F291E3119C6D4D3007AF63F /* Frameworks */,
2F03A53219C5C6DA005002A5 /* Sources */,
2F03A53C19C5C6DA005002A5 /* CoreStoreTests */,
@@ -1019,7 +1095,9 @@
B5E84ED91AFF82360064E85B /* LICENSE */,
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */,
B5BDC91A1C202269008147CD /* Cartfile */,
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */,
B5BDC9271C2024F2008147CD /* .travis.yml */,
B524E78721CA20AC00BEB794 /* .jazzy.yaml */,
B5AD60CD1C90141E00F2B2E8 /* Package.swift */,
);
name = "Supporting Files";
@@ -1102,6 +1180,17 @@
name = Observing;
sourceTree = "<group>";
};
B5215CA21FA47BF300139E3A /* Chained Clauses */ = {
isa = PBXGroup;
children = (
B55514E91EED8BF900BAB888 /* From+Querying.swift */,
B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */,
B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */,
B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */,
);
name = "Chained Clauses";
sourceTree = "<group>";
};
B52F74391E9B8724005F3DAC /* Dynamic Schema */ = {
isa = PBXGroup;
children = (
@@ -1224,17 +1313,38 @@
isa = PBXGroup;
children = (
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */,
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */,
B5831B6E1F3355C300A9F647 /* Properties */,
B52F74391E9B8724005F3DAC /* Dynamic Schema */,
B5D339DC1E9489C700C880DE /* DynamicObject.swift */,
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */,
B5D339E61E9493A500C880DE /* Entity.swift */,
B5D33A001E96012400C880DE /* Relationship.swift */,
B5D339E11E948C3600C880DE /* Value.swift */,
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */,
);
name = "Dynamic Models";
sourceTree = "<group>";
};
B5831B6E1F3355C300A9F647 /* Properties */ = {
isa = PBXGroup;
children = (
B5D33A001E96012400C880DE /* Relationship.swift */,
B5D339E11E948C3600C880DE /* Value.swift */,
B5831B791F34ACBA00A9F647 /* Transformable.swift */,
);
name = Properties;
sourceTree = "<group>";
};
B5A1DAC61F111BBE003CF369 /* KeyPath Utilities */ = {
isa = PBXGroup;
children = (
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */,
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */,
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */,
);
name = "KeyPath Utilities";
sourceTree = "<group>";
};
B5A5F26B1CAFF8D0004AB9AF /* Swift */ = {
isa = PBXGroup;
children = (
@@ -1358,13 +1468,14 @@
B5E84EFD1AFF847B0064E85B /* Fetching and Querying */ = {
isa = PBXGroup;
children = (
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */,
B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */,
B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */,
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */,
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */,
B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */,
B5215CA21FA47BF300139E3A /* Chained Clauses */,
B5A1DAC61F111BBE003CF369 /* KeyPath Utilities */,
B5E84F0A1AFF847B0064E85B /* Protocol Clauses */,
B5E84EFF1AFF847B0064E85B /* Concrete Clauses */,
);
@@ -1377,6 +1488,7 @@
B5E84F011AFF847B0064E85B /* From.swift */,
B5E84F031AFF847B0064E85B /* Select.swift */,
B5E84F051AFF847B0064E85B /* Where.swift */,
B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */,
B5E84F041AFF847B0064E85B /* OrderBy.swift */,
B5E84F021AFF847B0064E85B /* GroupBy.swift */,
B5E84F001AFF847B0064E85B /* Tweak.swift */,
@@ -1387,7 +1499,8 @@
B5E84F0A1AFF847B0064E85B /* Protocol Clauses */ = {
isa = PBXGroup;
children = (
B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */,
B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */,
B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */,
);
name = "Protocol Clauses";
sourceTree = "<group>";
@@ -1398,6 +1511,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 */,
@@ -1423,18 +1537,20 @@
B5E84F291AFF849C0064E85B /* Internal */ = {
isa = PBXGroup;
children = (
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */,
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */,
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
B51260921E9B28F100402229 /* EntityIdentifier.swift */,
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */,
B5E834BA1B7691F3001D3D50 /* Functions.swift */,
B5FAD6AB1B51285300714891 /* MigrationManager.swift */,
B5E84F2B1AFF849C0064E85B /* NotificationObserver.swift */,
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */,
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
B5E84F2C1AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift */,
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */,
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */,
@@ -1656,32 +1772,32 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = "John Rommel Estropia";
TargetAttributes = {
2F03A52F19C5C6DA005002A5 = {
CreatedOnToolsVersion = 6.0;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
2F03A53A19C5C6DA005002A5 = {
CreatedOnToolsVersion = 6.0;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
82BA18881C4BBCBA00A0916E = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
82BA18911C4BBCBA00A0916E = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
B52DD1731BE1F8CC00949AFE = {
CreatedOnToolsVersion = 7.1;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
B52DD17C1BE1F8CC00949AFE = {
CreatedOnToolsVersion = 7.1;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
B563216E1BD65082006C9394 = {
CreatedOnToolsVersion = 7.0.1;
@@ -1771,6 +1887,7 @@
files = (
B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */,
B5ECDBF91CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
B5CA2B081F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
B56923F51EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */,
@@ -1782,10 +1899,12 @@
B5D339D81E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
B56923FA1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
B55514EA1EED8BF900BAB888 /* From+Querying.swift in Sources */,
B596BBBB1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */,
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
@@ -1802,6 +1921,7 @@
B5ECDC1D1CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
@@ -1820,14 +1940,15 @@
B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */,
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */,
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
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 */,
@@ -1840,10 +1961,11 @@
B501FDE71CA8D20500BE22EF /* CSListObserver.swift in Sources */,
B5E41EC01EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
B501FDE21CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
B5A1DAC81F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
2F291E2719C6D3CF007AF63F /* CoreStore.swift in Sources */,
B5ECDC111CA816E500C7F112 /* CSTweak.swift in Sources */,
B56923C41EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
B5E84F411AFF8CCD0064E85B /* ClauseTypes.swift in Sources */,
B5E84F411AFF8CCD0064E85B /* TypeErasedClauses.swift in Sources */,
B5E84F0D1AFF847B0064E85B /* BaseDataTransaction+Querying.swift in Sources */,
B52F74451E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
B5FAD6AC1B51285300714891 /* MigrationManager.swift in Sources */,
@@ -1868,6 +1990,7 @@
B5E84F0F1AFF847B0064E85B /* From.swift in Sources */,
B5FAD6A91B50A4B400714891 /* Progress+Convenience.swift in Sources */,
B5E84EFC1AFF846E0064E85B /* SynchronousDataTransaction.swift in Sources */,
B5215CA91FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
B5E222231CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
B5E84F281AFF84920064E85B /* NSManagedObject+Convenience.swift in Sources */,
B52F744A1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
@@ -1875,6 +1998,8 @@
B5E2222A1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */,
B56923E81EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
B53B275F1EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
B5215CA41FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
B5D33A011E96012400C880DE /* Relationship.swift in Sources */,
B5E84EE81AFF84610064E85B /* CoreStoreLogger.swift in Sources */,
B56923C91EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
@@ -1892,21 +2017,26 @@
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */,
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
B5831B7A1F34ACBA00A9F647 /* Transformable.swift in Sources */,
B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
B53FBA1E1CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
B549F65E1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */,
B559CD431CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
B5CA2B121F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72021C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B56923EC1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */,
B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */,
B53FBA041CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
B5E84EF41AFF846E0064E85B /* AsynchronousDataTransaction.swift in Sources */,
B5831B701F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
B546F95D1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
B5D339E71E9493A500C880DE /* Entity.swift in Sources */,
@@ -1955,6 +2085,7 @@
files = (
82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */,
B5ECDBFB1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
B5CA2B091F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
B56923F61EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
82BA18A21C4BBD1D00A0916E /* CoreStoreError.swift in Sources */,
@@ -1966,6 +2097,7 @@
B5D339D91E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
82BA18CE1C4BBD7100A0916E /* FetchedResultsControllerDelegate.swift in Sources */,
B56923FB1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
B55514EB1EED8BF900BAB888 /* From+Querying.swift in Sources */,
B596BBBC1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */,
B5ECDC071CA8138100C7F112 /* CSOrderBy.swift in Sources */,
@@ -1986,6 +2118,7 @@
B5ECDC1F1CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
B53FBA141CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
B5E1B5AA1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
B5D339F21E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
@@ -2004,8 +2137,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 */,
@@ -2013,7 +2149,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 */,
@@ -2024,6 +2159,7 @@
B501FDE91CA8D20500BE22EF /* CSListObserver.swift in Sources */,
B5E41EC11EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
B501FDE41CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
B5A1DAC91F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
B5FE4DA31C8481E100FA6A91 /* StorageInterface.swift in Sources */,
B5ECDC131CA816E500C7F112 /* CSTweak.swift in Sources */,
B56923C51EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
@@ -2052,6 +2188,7 @@
82BA18C71C4BBD5900A0916E /* CoreStore+Migration.swift in Sources */,
B5E222251CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
82BA18C41C4BBD5300A0916E /* ListMonitor.swift in Sources */,
B5215CAA1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */,
B52F744B1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
@@ -2059,6 +2196,8 @@
82BA18A71C4BBD2900A0916E /* CoreStore+Logging.swift in Sources */,
82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */,
B56923E91EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
B5215CA51FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
B5D33A021E96012400C880DE /* Relationship.swift in Sources */,
B559CD4B1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
B56923CA1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
@@ -2076,21 +2215,26 @@
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */,
B53FBA201CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
82BA18A81C4BBD2900A0916E /* CoreStoreLogger.swift in Sources */,
B549F65F1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B559CD451CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
82BA18B81C4BBD4200A0916E /* ClauseTypes.swift in Sources */,
82BA18B81C4BBD4200A0916E /* TypeErasedClauses.swift in Sources */,
B5CA2B131F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72121C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CAF1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
B56923ED1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */,
B53FBA061CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
82BA18BE1C4BBD4A00A0916E /* Tweak.swift in Sources */,
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
B5831B711F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
B546F95E1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
B5ECDC0D1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
B5D339E81E9493A500C880DE /* Entity.swift in Sources */,
@@ -2139,6 +2283,7 @@
files = (
B5220E1E1D13080D009BC71E /* CSListMonitor.swift in Sources */,
B5DBE2D01C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
B5CA2B0B1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
B5677D411CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
B56923F81EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
B52DD1BE1BE1F94300949AFE /* Progress+Convenience.swift in Sources */,
@@ -2150,6 +2295,7 @@
B5D339DB1E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */,
B56923FD1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
B55514ED1EED8BF900BAB888 /* From+Querying.swift in Sources */,
B596BBBE1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
B546F9601C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
B5ECDC0F1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
@@ -2170,6 +2316,7 @@
B5D3F6481C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
B5220E1C1D130801009BC71E /* FetchedResultsControllerDelegate.swift in Sources */,
B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */,
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */,
B5D339F41E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B5220E241D13085E009BC71E /* NSFetchedResultsController+Convenience.swift in Sources */,
@@ -2188,8 +2335,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 */,
@@ -2198,7 +2348,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 */,
@@ -2208,6 +2357,7 @@
B559CD4D1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
B5E41EC31EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
B5ECDBE91CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
B5A1DACB1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
B52DD1B81BE1F94000949AFE /* DataStack+Migration.swift in Sources */,
B5ECDC091CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B56923C71EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
@@ -2236,6 +2386,7 @@
B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */,
B52DD1C11BE1F94600949AFE /* Functions.swift in Sources */,
B5220E1A1D130791009BC71E /* CoreStoreFetchedResultsController.swift in Sources */,
B5215CAC1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
B53FBA0F1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
B52F744D1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */,
@@ -2243,6 +2394,8 @@
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */,
B546F96C1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
B56923EB1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
B5215CA71FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
B5D33A041E96012400C880DE /* Relationship.swift in Sources */,
B52DD1C61BE1F94600949AFE /* NSManagedObjectContext+CoreStore.swift in Sources */,
B56923CC1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
@@ -2260,25 +2413,30 @@
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
B5ECDC331CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */,
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */,
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */,
B5220E151D130663009BC71E /* CoreStore+Observing.swift in Sources */,
B549F6611E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */,
B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */,
B5CA2B151F81DBFF004B1936 /* DynamicKeyPath.swift in Sources */,
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72321C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CB11FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
B56923EF1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
B53FBA081CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
B52DD1B91BE1F94000949AFE /* CoreStore+Migration.swift in Sources */,
B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B5831B731F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
B5D339EA1E9493A500C880DE /* Entity.swift in Sources */,
B52DD1AA1BE1F93500949AFE /* ClauseTypes.swift in Sources */,
B52DD1AA1BE1F93500949AFE /* TypeErasedClauses.swift in Sources */,
B53FBA021CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B51FE5AF1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
);
@@ -2323,6 +2481,7 @@
files = (
B56321A91BD65219006C9394 /* Progress+Convenience.swift in Sources */,
B5ECDBFC1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
B5CA2B0A1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
B56923F71EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
B56321801BD65216006C9394 /* CoreStoreError.swift in Sources */,
@@ -2334,6 +2493,7 @@
B5D339DA1E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
B5ECDC021CA80CBA00C7F112 /* CSWhere.swift in Sources */,
B56923FC1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
B55514EC1EED8BF900BAB888 /* From+Querying.swift in Sources */,
B596BBBD1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
B5ECDC081CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B5E1B59B1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
@@ -2354,6 +2514,7 @@
B5C976E51C6C9F9B00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
B5D339F31E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B5E1B5A01CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
@@ -2372,13 +2533,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 */,
@@ -2392,6 +2555,7 @@
B501FDE51CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
B5E41EC21EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
B5ECDC141CA816E500C7F112 /* CSTweak.swift in Sources */,
B5A1DACA1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
B56321AE1BD6521C006C9394 /* NotificationObserver.swift in Sources */,
B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */,
B56923C61EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
@@ -2420,6 +2584,7 @@
B563218E1BD65216006C9394 /* SaveResult.swift in Sources */,
B5E222261CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
B56321A21BD65216006C9394 /* ListObserver.swift in Sources */,
B5215CAB1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
B563218A1BD65216006C9394 /* SynchronousDataTransaction.swift in Sources */,
B52F744C1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
@@ -2427,6 +2592,8 @@
B563219F1BD65216006C9394 /* ObjectMonitor.swift in Sources */,
B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */,
B56923EA1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
B5215CA61FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
B5D33A031E96012400C880DE /* Relationship.swift in Sources */,
B559CD4C1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
B56923CB1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
@@ -2444,27 +2611,32 @@
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */,
B53FBA211CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */,
B549F6601E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B559CD461CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
B56321A61BD65216006C9394 /* MigrationType.swift in Sources */,
B5CA2B141F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
B5E8A72221C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
B5215CB01FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
B56923EE1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */,
B53FBA071CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
B56321841BD65216006C9394 /* DefaultLogger.swift in Sources */,
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
B5831B721F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
B546F95F1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
B5ECDC0E1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
B5D339E91E9493A500C880DE /* Entity.swift in Sources */,
B56321A41BD65216006C9394 /* CoreStore+Migration.swift in Sources */,
B56321A01BD65216006C9394 /* ObjectObserver.swift in Sources */,
B56321951BD65216006C9394 /* ClauseTypes.swift in Sources */,
B56321951BD65216006C9394 /* TypeErasedClauses.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2498,15 +2670,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -2531,8 +2711,8 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = Sources/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "-D DEBUG";
@@ -2540,11 +2720,13 @@
PRODUCT_NAME = CoreStore;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
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;
};
@@ -2557,15 +2739,23 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -2585,19 +2775,21 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = Sources/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore;
PRODUCT_NAME = CoreStore;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
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;
};
@@ -2615,7 +2807,7 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Debug;
};
@@ -2633,7 +2825,7 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Release;
};
@@ -2653,7 +2845,7 @@
SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Debug;
};
@@ -2668,7 +2860,7 @@
PRODUCT_NAME = CoreStoreTests;
SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Release;
};
@@ -2688,7 +2880,7 @@
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
@@ -2709,7 +2901,7 @@
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
@@ -2727,7 +2919,7 @@
SDKROOT = appletvos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
@@ -2745,7 +2937,7 @@
PRODUCT_NAME = CoreStoreTests;
SDKROOT = appletvos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
@@ -2769,7 +2961,7 @@
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Debug;
};
@@ -2793,7 +2985,7 @@
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Release;
};
@@ -2813,7 +3005,7 @@
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Debug;
};
@@ -2833,7 +3025,7 @@
PRODUCT_NAME = CoreStoreTests;
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
};
name = Release;
};
@@ -2854,7 +3046,7 @@
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
TARGETED_DEVICE_FAMILY = 4;
};
name = Debug;
@@ -2877,7 +3069,7 @@
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
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

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -89,6 +89,12 @@
ReferencedContainer = "container:CoreStore.xcodeproj">
</BuildableReference>
</MacroExpansion>
<CommandLineArguments>
<CommandLineArgument
argument = "-com.apple.CoreData.SQLDebug 2"
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

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

@@ -265,12 +265,12 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = "John Rommel Estropia";
TargetAttributes = {
B54AAD481AF4D26E00848AE0 = {
CreatedOnToolsVersion = 6.3;
LastSwiftMigration = 0800;
LastSwiftMigration = 0900;
};
};
};
@@ -371,14 +371,22 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -402,11 +410,13 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@@ -418,14 +428,22 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -442,9 +460,11 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -454,11 +474,11 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@@ -467,12 +487,12 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
};
name = Release;
};

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
@@ -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,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10112" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10083"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
@@ -12,10 +14,10 @@
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright © 2015 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright © 2018 John Rommel Estropia. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="440" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView userInteractionEnabled="NO" contentMode="center" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="CoreStoreIcon" translatesAutoresizingMaskIntoConstraints="NO" id="q8C-V6-gXH">
@@ -24,11 +26,11 @@
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="CoreStore" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="273" width="440" height="57.5"/>
<fontDescription key="fontDescription" name="HelveticaNeue-UltraLight" family="Helvetica Neue" pointSize="50"/>
<color key="textColor" red="0.92549019607843142" green="0.94117647058823528" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" red="0.90744441747665405" green="0.9265514612197876" blue="0.93116652965545654" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.20392156862745098" green="0.28627450980392155" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" red="0.15542715787887573" green="0.2203737199306488" blue="0.2959403395652771" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>

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="12113" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Ni8-QF-XHB">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="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="12078"/>
<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"/>
@@ -459,8 +456,8 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="301.5"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
<rect key="frame" x="20" y="69.5" width="552" height="36.5"/>
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
<rect key="frame" x="16" y="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"/>
@@ -511,8 +508,8 @@
<action selector="brightnessSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="F09-EP-2iD"/>
</connections>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p4O-tf-dgt">
<rect key="frame" x="20" y="49" width="552" height="20.5"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p4O-tf-dgt">
<rect key="frame" x="16" y="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 clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="V2U-0R-Ts0">
<rect key="frame" x="0.0" y="0.0" width="375" height="536"/>
<mapView verifyAmbiguity="ignoreSizes" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" 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>
@@ -806,7 +803,7 @@
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="RZg-hi-T8O" firstAttribute="top" secondItem="V2U-0R-Ts0" secondAttribute="bottom" id="GcS-Jz-Wcm"/>
<constraint firstItem="RZg-hi-T8O" firstAttribute="top" secondItem="V2U-0R-Ts0" secondAttribute="bottom" id="N9r-9J-68d"/>
<constraint firstItem="V2U-0R-Ts0" firstAttribute="top" secondItem="k4s-iL-Krh" secondAttribute="top" id="S5Z-Da-V6J"/>
<constraint firstAttribute="trailing" secondItem="V2U-0R-Ts0" secondAttribute="trailing" id="YPc-RK-5ib"/>
<constraint firstItem="V2U-0R-Ts0" firstAttribute="leading" secondItem="k4s-iL-Krh" secondAttribute="leading" id="hk5-Rz-FyU"/>
@@ -820,7 +817,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="YnG-TD-zxQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="3694" y="2020"/>
<point key="canvasLocation" x="3693.5" y="2019.5"/>
</scene>
<!--Logger-->
<scene sceneID="n7W-0g-bbY">
@@ -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"/>
@@ -927,7 +924,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bordered" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="YVj-dA-fyV">
<rect key="frame" x="20" y="26" width="560" height="29"/>
<rect key="frame" x="20" y="26" width="335" height="29"/>
<segments>
<segment title="Fetch"/>
<segment title="Query"/>
@@ -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

@@ -1,36 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="10169.1" systemVersion="15D21" minimumToolsVersion="Automatic">
<entity name="Palette" representedClassName="CoreStoreDemo.Palette">
<attribute name="brightness" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
<attribute name="colorName" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
<attribute name="hue" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
<attribute name="saturation" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
<userInfo/>
</entity>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16F73" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="Place" representedClassName="CoreStoreDemo.Place" syncable="YES">
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="subtitle" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<entity name="TimeZone" representedClassName="CoreStoreDemo.TimeZone" syncable="YES">
<attribute name="abbreviation" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" syncable="YES"/>
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
</entity>
<configuration name="FetchingAndQueryingDemo">
<memberEntity name="TimeZone"/>
</configuration>
<configuration name="ObservingDemo">
<memberEntity name="Palette"/>
</configuration>
<configuration name="TransactionsDemo">
<memberEntity name="Place"/>
</configuration>
<elements>
<element name="Palette" positionX="261" positionY="189" width="128" height="105"/>
<element name="Place" positionX="261" positionY="225" width="128" height="105"/>
<element name="TimeZone" positionX="297" positionY="270" width="128" height="120"/>
</elements>

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/12.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
@@ -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,67 +164,80 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
title: "All Time Zones",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
OrderBy(.ascending(#keyPath(TimeZone.name)))
)!
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.orderBy(.ascending(\.name))
)
}
),
(
title: "Time Zones in Asia",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Asia"),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
)!
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"Asia"
)
.orderBy(.ascending(\.secondsFromGMT))
)
}
),
(
title: "Time Zones in America and Europe",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America")
|| Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Europe"),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
)!
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@ OR %K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"America",
#keyPath(TimeZone.name),
"Europe"
)
.orderBy(.ascending(\.secondsFromGMT))
)
}
),
(
title: "All Time Zones Except America",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
!Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America"),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
)!
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(
format: "%K BEGINSWITH[c] %@",
#keyPath(TimeZone.name),
"America"
)
.orderBy(.ascending(\.secondsFromGMT))
)
}
),
(
title: "Time Zones with Summer Time",
fetch: { () -> [TimeZone] in
return Static.timeZonesStack.fetchAll(
From<TimeZone>(),
Where("hasDaylightSavingTime", isEqualTo: true),
OrderBy(.ascending(#keyPath(TimeZone.name)))
)!
return try! Static.timeZonesStack.fetchAll(
From<TimeZone>()
.where(\.hasDaylightSavingTime == true)
.orderBy(.ascending(\.name))
)
}
)
]
private let queryingItems = [
private let queryingItems: [(title: String, query: () -> Any)] = [
(
title: "Number of Time Zones",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
From<TimeZone>(),
Select<NSNumber>(.count(#keyPath(TimeZone.name)))
return try! Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(NSNumber.self, .count(\.name))
)!
}
),
@@ -232,10 +245,10 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
title: "Abbreviation For Tokyo's Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryValue(
From<TimeZone>(),
Select<String>(#keyPath(TimeZone.abbreviation)),
Where("%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
return try! Static.timeZonesStack.queryValue(
From<TimeZone>()
.select(String.self, .attribute(\.abbreviation))
.where(format: "%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
)!
}
),
@@ -243,38 +256,53 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
title: "All Abbreviations",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>(),
Select<NSDictionary>(#keyPath(TimeZone.name), #keyPath(TimeZone.abbreviation)),
OrderBy(.ascending(#keyPath(TimeZone.name)))
)!
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.attribute(\.name),
.attribute(\.abbreviation)
)
.orderBy(.ascending(\.name))
)
}
),
(
title: "Number of Countries per Time Zone",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>(),
Select<NSDictionary>(.count(#keyPath(TimeZone.abbreviation)), #keyPath(TimeZone.abbreviation)),
GroupBy(#keyPath(TimeZone.abbreviation)),
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)), .ascending(#keyPath(TimeZone.name)))
)!
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.count(\.abbreviation),
.attribute(\.abbreviation)
)
.groupBy(\.abbreviation)
.orderBy(
.ascending(\.secondsFromGMT),
.ascending(\.name)
)
)
}
),
(
title: "Number of Countries with Summer Time",
query: { () -> Any in
return Static.timeZonesStack.queryAttributes(
From<TimeZone>(),
Select<NSDictionary>(
.count(#keyPath(TimeZone.hasDaylightSavingTime), as: "numberOfCountries"),
#keyPath(TimeZone.hasDaylightSavingTime)
),
GroupBy(#keyPath(TimeZone.hasDaylightSavingTime)),
OrderBy(.descending(#keyPath(TimeZone.hasDaylightSavingTime)))
)!
return try! Static.timeZonesStack.queryAttributes(
From<TimeZone>()
.select(
NSDictionary.self,
.count(\.hasDaylightSavingTime, as: "numberOfCountries"),
.attribute(\.hasDaylightSavingTime)
)
.groupBy(\.hasDaylightSavingTime)
.orderBy(
.descending(\.hasDaylightSavingTime),
.ascending(\.name)
)
)
}
)
]

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/17.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/17.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/15.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

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>4.0.1</string>
<string>6.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -3,14 +3,14 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/02.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import CoreStore
private struct Static {
struct ColorsDemo {
enum Filter: String {
@@ -28,13 +28,13 @@ private struct Static {
}
}
func whereClause() -> Where {
func whereClause() -> Where<Palette> {
switch self {
case .all: return Where(true)
case .light: return Where("%K >= %@", #keyPath(Palette.brightness), 0.9)
case .dark: return Where("%K <= %@", #keyPath(Palette.brightness), 0.4)
case .all: return .init()
case .light: return (\Palette.brightness >= 0.9)
case .dark: return (\Palette.brightness <= 0.4)
}
}
}
@@ -45,25 +45,38 @@ private struct Static {
self.palettes.refetch(
self.filter.whereClause(),
OrderBy(.ascending(#keyPath(Palette.hue)))
OrderBy<Palette>(.ascending(\.hue))
)
}
}
static let stack: DataStack = {
return DataStack(
CoreStoreSchema(
modelVersion: "ColorsDemo",
entities: [
Entity<Palette>("Palette"),
],
versionLock: [
"Palette": [0x8c25aa53c7c90a28, 0xa243a34d25f1a3a7, 0x56565b6935b6055a, 0x4f988bb257bf274f]
]
)
)
}()
static let palettes: ListMonitor<Palette> = {
try! CoreStore.addStorageAndWait(
try! ColorsDemo.stack.addStorageAndWait(
SQLiteStore(
fileName: "ColorsDemo.sqlite",
configuration: "ObservingDemo",
localStorageOptions: .recreateStoreOnModelMismatch
)
)
return CoreStore.monitorSectionedList(
From<Palette>(),
SectionBy(#keyPath(Palette.colorName)),
OrderBy(.ascending(#keyPath(Palette.hue)))
return ColorsDemo.stack.monitorSectionedList(
From<Palette>()
.sectionBy(\.colorName)
.orderBy(.ascending(\.hue))
)
}()
}
@@ -77,7 +90,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
deinit {
Static.palettes.removeObserver(self)
ColorsDemo.palettes.removeObserver(self)
}
@@ -98,7 +111,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
]
let filterBarButton = UIBarButtonItem(
title: Static.filter.rawValue,
title: ColorsDemo.filter.rawValue,
style: .plain,
target: self,
action: #selector(self.filterBarButtonItemTouched(_:))
@@ -109,13 +122,18 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
target: self,
action: #selector(self.addBarButtonItemTouched(_:))
),
UIBarButtonItem(
barButtonSystemItem: .refresh,
target: self,
action: #selector(self.shuffleBarButtonItemTouched(_:))
),
filterBarButton
]
self.filterBarButton = filterBarButton
Static.palettes.addObserver(self)
ColorsDemo.palettes.addObserver(self)
self.setTable(enabled: !Static.palettes.isPendingRefetch)
self.setTable(enabled: !ColorsDemo.palettes.isPendingRefetch)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
@@ -137,19 +155,19 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
override func numberOfSections(in tableView: UITableView) -> Int {
return Static.palettes.numberOfSections()
return ColorsDemo.palettes.numberOfSections()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Static.palettes.numberOfObjectsInSection(section)
return ColorsDemo.palettes.numberOfObjects(in: section)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell
let palette = Static.palettes[indexPath]
let palette = ColorsDemo.palettes[indexPath]
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
@@ -165,7 +183,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
self.performSegue(
withIdentifier: "ObjectObserverDemoViewController",
sender: Static.palettes[indexPath]
sender: ColorsDemo.palettes[indexPath]
)
}
@@ -174,8 +192,8 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
switch editingStyle {
case .delete:
let palette = Static.palettes[indexPath]
CoreStore.perform(
let palette = ColorsDemo.palettes[indexPath]
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
transaction.delete(palette)
@@ -190,7 +208,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return Static.palettes.sectionInfoAtIndex(section).name
return ColorsDemo.palettes.sectionInfo(at: section).name
}
@@ -213,7 +231,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
func listMonitorDidRefetch(_ monitor: ListMonitor<Palette>) {
self.filterBarButton?.title = Static.filter.rawValue
self.filterBarButton?.title = ColorsDemo.filter.rawValue
self.tableView.reloadData()
self.setTable(enabled: true)
}
@@ -235,7 +253,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
if let cell = self.tableView.cellForRow(at: indexPath) as? PaletteTableViewCell {
let palette = Static.palettes[indexPath]
let palette = ColorsDemo.palettes[indexPath]
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
}
@@ -255,7 +273,6 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
}
func listMonitor(_ monitor: ListMonitor<Palette>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) {
self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
@@ -268,10 +285,10 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
CoreStore.perform(
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
transaction.deleteAll(From<Palette>())
try transaction.deleteAll(From<Palette>())
},
completion: { _ in }
)
@@ -279,23 +296,43 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
Static.filter = Static.filter.next()
ColorsDemo.filter = ColorsDemo.filter.next()
}
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
CoreStore.perform(
ColorsDemo.stack.perform(
asynchronous: { (transaction) in
let palette = transaction.create(Into<Palette>())
palette.setInitialValues()
palette.setInitialValues(in: transaction)
},
completion: { _ in }
)
}
@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,
@@ -305,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

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/06.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
@@ -29,7 +29,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
if let palette = newValue {
self.monitor = CoreStore.monitorObject(palette)
self.monitor = ColorsDemo.stack.monitorObject(palette)
}
else {
@@ -50,22 +50,22 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
required init?(coder aDecoder: NSCoder) {
if let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue)))) {
if let palette = try! ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue))) {
self.monitor = CoreStore.monitorObject(palette)
self.monitor = ColorsDemo.stack.monitorObject(palette)
}
else {
_ = try? CoreStore.perform(
_ = try? ColorsDemo.stack.perform(
synchronous: { (transaction) in
let palette = transaction.create(Into(Palette.self))
palette.setInitialValues()
let palette = transaction.create(Into<Palette>())
palette.setInitialValues(in: transaction)
}
)
let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue))))!
self.monitor = CoreStore.monitorObject(palette)
let palette = try! ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue)))!
self.monitor = ColorsDemo.stack.monitorObject(palette)
}
super.init(coder: aDecoder)
@@ -85,7 +85,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
// MARK: ObjectObserver
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPath>) {
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPathString>) {
self.reloadPaletteInfo(object, changedKeys: changedPersistentKeys)
}
@@ -121,12 +121,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
let hue = self.hueSlider?.value ?? 0
CoreStore.perform(
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.hue = Int32(hue)
palette.hue .= Int(hue)
}
},
completion: { _ in }
@@ -136,12 +136,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
let saturation = self.saturationSlider?.value ?? 0
CoreStore.perform(
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.saturation = saturation
palette.saturation .= saturation
}
},
completion: { _ in }
@@ -151,12 +151,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
let brightness = self.brightnessSlider?.value ?? 0
CoreStore.perform(
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
if let palette = transaction.edit(self?.monitor?.object) {
palette.brightness = brightness
palette.brightness .= brightness
}
},
completion: { _ in }
@@ -165,7 +165,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
CoreStore.perform(
ColorsDemo.stack.perform(
asynchronous: { [weak self] (transaction) in
transaction.delete(self?.monitor?.object)
@@ -176,7 +176,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
self.colorNameLabel?.text = palette.colorName
self.colorNameLabel?.text = palette.colorName.value
let color = palette.color
self.colorNameLabel?.textColor = color
@@ -184,17 +184,17 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
self.hsbLabel?.text = palette.colorText
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.hue)) == true {
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.hue)) == true {
self.hueSlider?.value = Float(palette.hue)
self.hueSlider?.value = Float(palette.hue.value)
}
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.saturation)) == true {
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.saturation)) == true {
self.saturationSlider?.value = palette.saturation
self.saturationSlider?.value = palette.saturation.value
}
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.brightness)) == true {
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.brightness)) == true {
self.brightnessSlider?.value = palette.brightness
self.brightnessSlider?.value = palette.brightness.value
}
}
}

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/05.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation
@@ -14,64 +14,70 @@ import CoreStore
// MARK: - Palette
class Palette: NSManagedObject {
@NSManaged var hue: Int32
@NSManaged var saturation: Float
@NSManaged var brightness: Float
final class Palette: CoreStoreObject {
@objc dynamic var colorName: String {
let hue = Value.Required<Int>("hue", initial: 0)
let saturation = Value.Required<Float>("saturation", initial: 0)
let brightness = Value.Required<Float>("brightness", initial: 0)
let colorName = Value.Optional<String>(
"colorName",
isTransient: true,
customGetter: Palette.getColorName
)
static func randomHue() -> Int {
return Int(arc4random_uniform(360))
}
private static func getColorName(_ partialObject: PartialObject<Palette>) -> String? {
get {
if let colorName = partialObject.primitiveValue(for: { $0.colorName }) {
let KVCKey = #keyPath(Palette.colorName)
if let colorName = self.getValue(forKvcKey: KVCKey) as? String {
return colorName
}
let colorName: String
switch self.hue % 360 {
case 0 ..< 20: colorName = "Lower Reds"
case 20 ..< 57: colorName = "Oranges and Browns"
case 57 ..< 90: colorName = "Yellow-Greens"
case 90 ..< 159: colorName = "Greens"
case 159 ..< 197: colorName = "Blue-Greens"
case 197 ..< 241: colorName = "Blues"
case 241 ..< 297: colorName = "Violets"
case 297 ..< 331: colorName = "Magentas"
default: colorName = "Upper Reds"
}
self.setPrimitiveValue(colorName, forKey: KVCKey)
return colorName
}
set {
let colorName: String
switch partialObject.value(for: { $0.hue }) % 360 {
self.setValue(newValue.cs_toImportableNativeType(), forKvcKey: #keyPath(Palette.colorName))
case 0 ..< 20: colorName = "Lower Reds"
case 20 ..< 57: colorName = "Oranges and Browns"
case 57 ..< 90: colorName = "Yellow-Greens"
case 90 ..< 159: colorName = "Greens"
case 159 ..< 197: colorName = "Blue-Greens"
case 197 ..< 241: colorName = "Blues"
case 241 ..< 297: colorName = "Violets"
case 297 ..< 331: colorName = "Magentas"
default: colorName = "Upper Reds"
}
partialObject.setPrimitiveValue(colorName, for: { $0.colorName })
return colorName
}
}
extension Palette {
var color: UIColor {
return UIColor(
hue: CGFloat(self.hue) / 360.0,
saturation: CGFloat(self.saturation),
brightness: CGFloat(self.brightness),
hue: CGFloat(self.hue.value) / 360.0,
saturation: CGFloat(self.saturation.value),
brightness: CGFloat(self.brightness.value),
alpha: 1.0
)
}
var colorText: String {
return "H: \(self.hue)˚, S: \(round(self.saturation * 100.0))%, B: \(round(self.brightness * 100.0))%"
return "H: \(self.hue.value)˚, S: \(round(self.saturation.value * 100.0))%, B: \(round(self.brightness.value * 100.0))%"
}
func setInitialValues() {
func setInitialValues(in transaction: BaseDataTransaction) {
self.hue = Int32(arc4random_uniform(360))
self.saturation = 1.0
self.brightness = Float(arc4random_uniform(70) + 30) / 100.0
self.hue .= Palette.randomHue()
self.saturation .= Float(1.0)
self.brightness .= Float(arc4random_uniform(70) + 30) / 100.0
}
}

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/05.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/05.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
@@ -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
@@ -99,8 +102,8 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
case 0?:
let request = NSFetchRequest<NSFetchRequestResult>()
Where(true).applyToFetchRequest(request)
Where(false).applyToFetchRequest(request)
Where<NSManagedObject>(true).applyToFetchRequest(request)
Where<NSManagedObject>(false).applyToFetchRequest(request)
case 1?:
_ = try? dataStack.addStorageAndWait(
@@ -113,7 +116,7 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
case 2?:
DispatchQueue.global(qos: .background).async {
_ = self.dataStack.fetchOne(From<Palette>())
_ = try! self.dataStack.fetchOne(From<Place>())
}
default:

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
@@ -46,7 +46,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
self.present(alert, animated: true, completion: nil)
let modelMetadata = withExtendedLifetime(DataStack(modelName: "MigrationDemo")) {
let modelMetadata = withExtendedLifetime(DataStack(xcodeModelName: "MigrationDemo")) {
(dataStack: DataStack) -> ModelMetadata in
let models = self.models
@@ -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 {
@@ -109,7 +109,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
let dna = (self.listMonitor?[indexPath] as? OrganismProtocol)?.dna.description ?? ""
cell.dnaLabel?.text = "DNA: \(dna)"
cell.mutateButtonHandler = { [weak self] _ -> Void in
cell.mutateButtonHandler = { [weak self] () -> Void in
guard let `self` = self,
let dataStack = self.dataStack,
@@ -286,9 +286,9 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
self.set(dataStack: dataStack, model: model, scrollToSelection: true)
let count = dataStack.queryValue(
From(model.entityType),
Select<Int>(.count(#keyPath(OrganismV1.dna))))!
let count = try! dataStack.queryValue(
From<NSManagedObject>(model.entityType)
.select(Int.self, .count(#keyPath(OrganismV1.dna))))!
if count > 0 {
self.setEnabled(true)
@@ -361,20 +361,24 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
self.segmentedControl?.selectedSegmentIndex = self.models
.index(
where: { (_, _, schemaHistory) -> Bool in
where: { (arg) -> Bool in
schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
let (_, _, schemaHistory) = arg
return schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
}
)!
self._dataStack = dataStack
let listMonitor = dataStack.monitorList(From(model.entityType), OrderBy(.descending("dna")))
let listMonitor = dataStack.monitorList(
From(model.entityType),
OrderBy<NSManagedObject>(.descending(#keyPath(OrganismV1.dna)))
)
listMonitor.addObserver(self)
self._listMonitor = listMonitor
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

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/07/12.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/21.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import CoreData

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/27.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/06.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/06/06.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
@@ -17,7 +17,7 @@ private struct Static {
static let facebookStack: DataStack = {
let dataStack = DataStack(modelName: "StackSetupDemo")
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_FB_Male.sqlite",
@@ -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"
@@ -55,7 +55,7 @@ private struct Static {
static let twitterStack: DataStack = {
let dataStack = DataStack(modelName: "StackSetupDemo")
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
try! dataStack.addStorageAndWait(
SQLiteStore(
fileName: "AccountsDemo_TW_Male.sqlite",
@@ -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

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,7 +3,7 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import Foundation

View File

@@ -3,10 +3,11 @@
// CoreStoreDemo
//
// Created by John Rommel Estropia on 2015/05/24.
// Copyright © 2015 John Rommel Estropia. All rights reserved.
// Copyright © 2018 John Rommel Estropia. All rights reserved.
//
import UIKit
import Contacts
import CoreLocation
import MapKit
import AddressBookUI
@@ -25,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(
@@ -35,7 +36,7 @@ private struct Static {
place.setInitialValues()
}
)
place = CoreStore.fetchOne(From<Place>())
place = try! CoreStore.fetchOne(From<Place>())
}
return CoreStore.monitorObject(place!)
@@ -131,7 +132,7 @@ class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, Objec
// none
}
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPath>) {
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPathString>) {
if let mapView = self.mapView {
@@ -203,11 +204,23 @@ class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, Objec
CLLocation(latitude: place.latitude, longitude: place.longitude),
completionHandler: { [weak self] (placemarks, error) -> Void in
if let placemark = placemarks?.first, let addressDictionary = placemark.addressDictionary {
if let placemark = placemarks?.first, let dictionary = placemark.addressDictionary {
let place = transaction.edit(Static.placeController.object)
place?.title = placemark.name
place?.subtitle = ABCreateStringWithAddressDictionary(addressDictionary, true)
place?.subtitle = CNPostalAddressFormatter.string(
from: autoreleasepool {
let address = CNMutablePostalAddress()
(dictionary["Street"] as? String).flatMap({ address.street = $0 })
(dictionary["State"] as? String).flatMap({ address.state = $0 })
(dictionary["City"] as? String).flatMap({ address.city = $0 })
(dictionary["Country"] as? String).flatMap({ address.country = $0 })
(dictionary["ZIP"] as? String).flatMap({ address.postalCode = $0 })
return address
},
style: .mailingAddress
)
transaction.commit { (_) -> Void in }
}

View File

@@ -2,7 +2,7 @@
// BaseTestCase.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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

@@ -2,8 +2,25 @@
// BaseTestDataTestCase.swift
// CoreStore
//
// Created by John Rommel Estropia on 2016/06/11.
// Copyright © 2016 John Rommel Estropia. All rights reserved.
// 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

View File

@@ -2,7 +2,7 @@
// BridgingTests.h
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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

View File

@@ -2,7 +2,7 @@
// BridgingTests.m
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -193,7 +193,17 @@
XCTAssertEqualObjects([[sqliteStorage class] storeType], [CSSQLiteStore storeType]);
XCTAssertEqualObjects([[sqliteStorage class] storeType], NSSQLiteStoreType);
XCTAssertNil(sqliteStorage.configuration);
XCTAssertEqualObjects(sqliteStorage.storeOptions, @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" } });
NSDictionary *storeOptions;
if (@available(iOS 11.0, macOS 10.13, tvOS 11.0, *)) {
storeOptions = @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" },
NSBinaryStoreInsecureDecodingCompatibilityOption: @YES };
}
else {
storeOptions = @{ NSSQLitePragmasOption: @{ @"journal_mode": @"WAL" }};
}
XCTAssertEqualObjects(sqliteStorage.storeOptions, storeOptions);
XCTAssertNil(sqliteError);
}

View File

@@ -2,7 +2,7 @@
// ConvenienceTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -29,7 +29,7 @@ import CoreStore
// MARK: - ConvenienceTests
@available(OSX 10.12, *)
@available(macOS 10.12, *)
class ConvenienceTests: BaseTestCase {
@objc
@@ -40,8 +40,8 @@ class ConvenienceTests: BaseTestCase {
let controller = stack.createFetchedResultsController(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testString)),
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
OrderBy(.ascending(#keyPath(TestEntity1.testString))),
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
Tweak { $0.fetchLimit = 10 }
)
XCTAssertEqual(controller.managedObjectContext, stack.mainContext)
@@ -49,11 +49,11 @@ class ConvenienceTests: BaseTestCase {
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
XCTAssertEqual(
controller.fetchRequest.sortDescriptors!,
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
)
XCTAssertEqual(
controller.fetchRequest.predicate,
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
)
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
}
@@ -69,8 +69,8 @@ class ConvenienceTests: BaseTestCase {
let controller = transaction.createFetchedResultsController(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testString)),
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
OrderBy(.ascending(#keyPath(TestEntity1.testString))),
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
Tweak { $0.fetchLimit = 10 }
)
XCTAssertEqual(controller.managedObjectContext, transaction.context)
@@ -78,11 +78,11 @@ class ConvenienceTests: BaseTestCase {
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
XCTAssertEqual(
controller.fetchRequest.sortDescriptors!,
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
)
XCTAssertEqual(
controller.fetchRequest.predicate,
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
)
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
}

View File

@@ -2,7 +2,7 @@
// DynamicModelTests.swift
// CoreStore
//
// Copyright © 2017 John Rommel Estropia
// 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
@@ -28,16 +28,17 @@ import XCTest
@testable
import CoreStore
#if os(OSX)
#if os(macOS)
typealias Color = NSColor
#else
typealias Color = UIColor
#endif
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", default: "Swift")
let species = Value.Required<String>("species", initial: "Swift")
let master = Relationship.ToOne<Person>("master")
let color = Transformable.Optional<Color>("color")
}
@@ -45,21 +46,71 @@ class Animal: CoreStoreObject {
class Dog: Animal {
let nickname = Value.Optional<String>("nickname")
let age = Value.Required<Int>("age", default: 1)
let age = Value.Required<Int>("age", initial: 1)
let friends = Relationship.ToManyOrdered<Dog>("friends")
let friendedBy = Relationship.ToManyUnordered<Dog>("friendedBy", inverse: { $0.friends })
}
class Person: CoreStoreObject {
let title = Value.Required<String>("title", default: "Mr.")
let title = Value.Required<String>(
"title",
initial: "Mr.",
customSetter: Person.setTitle
)
let name = Value.Required<String>(
"name",
customGetter: { (`self`, getValue) in
return "\(self.title.value) \(getValue())"
}
initial: "",
customSetter: Person.setName
)
let displayName = Value.Optional<String>(
"displayName",
isTransient: true,
customGetter: Person.getDisplayName(_:),
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
)
let 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) {
partialObject.setPrimitiveValue(newValue, for: { $0.title })
partialObject.setPrimitiveValue(nil, for: { $0.displayName })
}
private static func setName(_ partialObject: PartialObject<Person>, _ newValue: String) {
partialObject.setPrimitiveValue(newValue, for: { $0.name })
partialObject.setPrimitiveValue(nil, for: { $0.displayName })
}
static func getDisplayName(_ partialObject: PartialObject<Person>) -> String? {
if let displayName = partialObject.primitiveValue(for: { $0.displayName }) {
return displayName
}
let title = partialObject.value(for: { $0.title })
let name = partialObject.value(for: { $0.name })
let displayName = "\(title) \(name)"
partialObject.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
static func keyPathsAffectingDisplayName() -> Set<String> {
return [
String(keyPath: \Person.title),
String(keyPath: \Person.name)
]
}
}
@@ -67,7 +118,8 @@ class Person: CoreStoreObject {
class DynamicModelTests: BaseTestDataTestCase {
func testDynamicModels_CanBeDeclaredCorrectly() {
@objc
dynamic func test_ThatDynamicModels_CanBeDeclaredCorrectly() {
let dataStack = DataStack(
CoreStoreSchema(
@@ -80,23 +132,26 @@ class DynamicModelTests: BaseTestDataTestCase {
versionLock: [
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
"Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b]
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
]
)
)
self.prepareStack(dataStack, configurations: [nil]) { (stack) in
let k1 = Animal.keyPath({ $0.species })
let k1 = String(keyPath: \Animal.species)
XCTAssertEqual(k1, "species")
let k2 = Dog.keyPath({ $0.species })
let k2 = String(keyPath: \Dog.species)
XCTAssertEqual(k2, "species")
let k3 = Dog.keyPath({ $0.nickname })
let k3 = String(keyPath: \Dog.nickname)
XCTAssertEqual(k3, "nickname")
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
@@ -114,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")
@@ -124,11 +212,25 @@ class DynamicModelTests: BaseTestDataTestCase {
let person = transaction.create(Into<Person>())
XCTAssertTrue(person.pets.value.isEmpty)
XCTAssertEqual(
cs_dynamicType(of: person.rawObject!).keyPathsForValuesAffectingValue(forKey: "displayName"),
["title", "name"]
)
person.name .= "Joe"
XCTAssertEqual(person.rawObject!.value(forKey: "name") as! String?, "Joe")
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "Mr. Joe")
person.rawObject!.setValue("AAAA", forKey: "displayName")
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "AAAA")
person.name .= "John"
XCTAssertEqual(person.name.value, "Mr. John") // Custom getter
XCTAssertEqual(person.name.value, "John")
XCTAssertEqual(person.displayName.value, "Mr. John") // Custom getter
person.title .= "Sir"
XCTAssertEqual(person.name.value, "Sir John")
XCTAssertEqual(person.displayName.value, "Sir John")
person.pets.value.insert(dog)
XCTAssertEqual(person.pets.count, 1)
@@ -137,7 +239,7 @@ class DynamicModelTests: BaseTestDataTestCase {
XCTAssertEqual(dog.master.value, person)
XCTAssertEqual(dog.master.value?.pets.value.first, dog)
},
success: {
success: { _ in
updateDone.fulfill()
},
@@ -149,29 +251,62 @@ class DynamicModelTests: BaseTestDataTestCase {
stack.perform(
asynchronous: { (transaction) in
let p1 = Animal.where({ $0.species == "Sparrow" })
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 = Dog.where({ $0.nickname == "Spot" })
let p2 = Where<Dog>({ $0.nickname == "Spot" })
XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot"))
let dog = transaction.fetchOne(From<Dog>(), p2)
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 = Dog.where({ $0.age == 10 })
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)
_ = try transaction.fetchAll(
From<Dog>()
.where(\Animal.species == "Dog" && \Dog.age == 10)
)
_ = try transaction.fetchAll(
From<Dog>()
.where(\Dog.age == 10 && \Animal.species == "Dog")
.orderBy(.ascending({ $0.species }))
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.age > 10 && $0.age <= 15 })
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.species == "Dog" && $0.age == 10 })
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.age == 10 && $0.species == "Dog" })
)
_ = try transaction.fetchAll(
From<Dog>(),
Where<Dog>({ $0.age > 10 && $0.age <= 15 })
)
_ = try transaction.fetchAll(
From<Dog>(),
(\Dog.age > 10 && \Dog.age <= 15)
)
},
success: {
success: { _ in
fetchDone.fulfill()
},
@@ -184,6 +319,13 @@ class DynamicModelTests: BaseTestDataTestCase {
}
}
@objc
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
XCTAssertEqual(String(keyPath: \Animal.species), "species")
XCTAssertEqual(String(keyPath: \Dog.species), "species")
}
@nonobjc
func prepareStack(_ dataStack: DataStack, configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> Void) {

View File

@@ -2,7 +2,7 @@
// ErrorTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
// FromTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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 = NSFetchRequest<NSFetchRequestResult>()
try from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>()
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"])
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let storesFound = self.expectLogger([.logWarning]) {
let request = NSFetchRequest<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)
XCTAssertNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.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 = NSFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.affectedStores)
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"])
}
}

View File

@@ -2,7 +2,7 @@
// GroupByTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -38,14 +38,14 @@ final class GroupByTests: BaseTestCase {
do {
let groupBy = GroupBy()
let groupBy = GroupBy<NSManagedObject>()
XCTAssertEqual(groupBy, GroupBy([] as [String]))
XCTAssertNotEqual(groupBy, GroupBy("key"))
XCTAssertTrue(groupBy.keyPaths.isEmpty)
}
do {
let groupBy = GroupBy("key1")
let groupBy = GroupBy<NSManagedObject>("key1")
XCTAssertEqual(groupBy, GroupBy("key1"))
XCTAssertEqual(groupBy, GroupBy(["key1"]))
XCTAssertNotEqual(groupBy, GroupBy("key2"))
@@ -53,7 +53,7 @@ final class GroupByTests: BaseTestCase {
}
do {
let groupBy = GroupBy("key1", "key2")
let groupBy = GroupBy<NSManagedObject>("key1", "key2")
XCTAssertEqual(groupBy, GroupBy("key1", "key2"))
XCTAssertEqual(groupBy, GroupBy(["key1", "key2"]))
XCTAssertNotEqual(groupBy, GroupBy("key2", "key1"))
@@ -66,10 +66,10 @@ final class GroupByTests: BaseTestCase {
self.prepareStack { (dataStack) in
let groupBy = GroupBy(#keyPath(TestEntity1.testString))
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
let request = CoreStoreFetchRequest()
_ = From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
let request = NSFetchRequest<NSFetchRequestResult>()
try From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
groupBy.applyToFetchRequest(request)
XCTAssertNotNil(request.propertiesToGroupBy)

View File

@@ -2,7 +2,7 @@
// ImportTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -36,33 +36,33 @@ class ImportTests: BaseTestDataTestCase {
@objc
dynamic func test_ThatAttributeProtocols_BehaveCorrectly() {
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: true))?.boolValue, true)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: true))?.boolValue, true)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: true)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT)))
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT))))
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: true)))
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max)))
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max)))
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max)))
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT)))
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT))))
XCTAssertEqual(true.cs_toQueryableNativeType(), NSNumber(value: true))
XCTAssertEqual(Int16.max.cs_toQueryableNativeType(), NSNumber(value: Int16.max))
@@ -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(#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]
@@ -565,7 +564,9 @@ class ImportTests: BaseTestDataTestCase {
XCTAssertEqual(objects.count, 2)
zip(objects, sourceArray)
.forEach { object, dictionary in
.forEach {
let (object, dictionary) = $0
XCTAssertEqual(object.testEntityID, dictionary[(#keyPath(TestEntity1.testEntityID))] as? NSNumber)
XCTAssertEqual(object.testBoolean, dictionary[(#keyPath(TestEntity1.testBoolean))] as? NSNumber)
XCTAssertEqual(object.testNumber, dictionary[(#keyPath(TestEntity1.testNumber))] as? NSNumber)
@@ -616,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(#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)
@@ -655,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(#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()
}
@@ -708,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))
@@ -733,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))
@@ -743,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(#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)
}
}
@@ -797,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]
@@ -862,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(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#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()
@@ -908,7 +906,7 @@ class ImportTests: BaseTestDataTestCase {
errorExpectation.fulfill()
let object = transaction.fetchOne(From<TestEntity1>(), Where(#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)
@@ -949,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(#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))
@@ -961,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(#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()
@@ -1016,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]
@@ -1030,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(#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>1.0</string>
<string>6.2.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -2,7 +2,7 @@
// IntoTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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

View File

@@ -2,7 +2,7 @@
// ListObserverTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -31,7 +31,7 @@ import CoreStore
// MARK: - ListObserverTests
@available(OSX 10.12, *)
@available(macOS 10.12, *)
class ListObserverTests: BaseTestDataTestCase {
@objc
@@ -43,7 +43,7 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
monitor.addObserver(observer)
@@ -54,7 +54,7 @@ class ListObserverTests: BaseTestDataTestCase {
var events = 0
let willChangeExpectation = self.expectation(
forNotification: "listMonitorWillChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -68,7 +68,7 @@ class ListObserverTests: BaseTestDataTestCase {
}
)
let didInsertSectionExpectation = self.expectation(
forNotification: "listMonitor:didInsertSection:toSectionIndex:",
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertSection:toSectionIndex:"),
object: observer,
handler: { (note) -> Bool in
@@ -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
)
@@ -88,7 +88,7 @@ class ListObserverTests: BaseTestDataTestCase {
}
)
let didInsertObjectExpectation = self.expectation(
forNotification: "listMonitor:didInsertObject:toIndexPath:",
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
object: observer,
handler: { (note) -> Bool in
@@ -120,7 +120,7 @@ class ListObserverTests: BaseTestDataTestCase {
}
)
let didChangeExpectation = self.expectation(
forNotification: "listMonitorDidChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -171,21 +171,21 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
monitor.addObserver(observer)
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
let willChangeExpectation = self.expectation(
forNotification: "listMonitorWillChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -198,62 +198,60 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0
}
)
for _ in 1 ... 2 {
let didUpdateObjectExpectation = self.expectation(
forNotification: "listMonitor:didUpdateObject:atIndexPath:",
object: observer,
handler: { (note) -> Bool in
let didUpdateObjectExpectation = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didUpdateObject:atIndexPath:"),
object: observer,
handler: { (note) -> Bool in
XCTAssert(events == 1 || events == 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
let object = userInfo?["object"] as? TestEntity1
switch object?.testEntityID {
XCTAssert(events == 1 || events == 2)
case NSNumber(value: 101)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
["indexPath", "object"]
)
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
let object = userInfo?["object"] as? TestEntity1
case NSNumber(value: 102)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
switch object?.testEntityID {
case NSNumber(value: 101)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
case NSNumber(value: 102)?:
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
default:
XCTFail()
}
defer {
events += 1
}
return events == 1 || events == 2
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
default:
XCTFail()
}
)
}
defer {
events += 1
}
return events == 1 || events == 2
}
)
let didChangeExpectation = self.expectation(
forNotification: "listMonitorDidChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -270,9 +268,9 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
if let object = transaction.fetchOne(
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
object.testNumber = NSNumber(value: 11)
object.testDecimal = NSDecimalNumber(string: "11")
@@ -284,9 +282,9 @@ class ListObserverTests: BaseTestDataTestCase {
XCTFail()
}
if let object = transaction.fetchOne(
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
object.testNumber = NSNumber(value: 22)
object.testDecimal = NSDecimalNumber(string: "22")
@@ -325,14 +323,14 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
monitor.addObserver(observer)
var events = 0
let willChangeExpectation = self.expectation(
forNotification: "listMonitorWillChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -346,7 +344,7 @@ class ListObserverTests: BaseTestDataTestCase {
}
)
let didMoveObjectExpectation = self.expectation(
forNotification: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:",
forNotification: NSNotification.Name(rawValue: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:"),
object: observer,
handler: { (note) -> Bool in
@@ -379,7 +377,7 @@ class ListObserverTests: BaseTestDataTestCase {
}
)
let didChangeExpectation = self.expectation(
forNotification: "listMonitorDidChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -396,9 +394,9 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
if let object = transaction.fetchOne(
if let object = try transaction.fetchOne(
From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
object.testBoolean = NSNumber(value: true)
}
@@ -433,14 +431,14 @@ class ListObserverTests: BaseTestDataTestCase {
let monitor = stack.monitorSectionedList(
From<TestEntity1>(),
SectionBy(#keyPath(TestEntity1.testBoolean)),
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
)
monitor.addObserver(observer)
var events = 0
let willChangeExpectation = self.expectation(
forNotification: "listMonitorWillChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -453,40 +451,37 @@ class ListObserverTests: BaseTestDataTestCase {
return events == 0
}
)
for _ in 1 ... 2 {
let didUpdateObjectExpectation = self.expectation(
forNotification: "listMonitor:didDeleteObject:fromIndexPath:",
object: observer,
handler: { (note) -> Bool in
let didUpdateObjectExpectation = self.expectation(
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteObject:fromIndexPath:"),
object: observer,
handler: { (note) -> Bool in
XCTAssert(events == 1 || events == 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.isDeleted, true)
defer {
XCTAssert(events == 1 || events == 2)
let userInfo = note.userInfo
XCTAssertNotNil(userInfo)
XCTAssertEqual(
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
["indexPath", "object"]
)
let indexPath = userInfo?["indexPath"] as? NSIndexPath
XCTAssertEqual(indexPath?.section, 0)
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
let object = userInfo?["object"] as? TestEntity1
XCTAssertEqual(object?.isDeleted, true)
defer {
events += 1
}
return events == 1 || events == 2
events += 1
}
)
}
return events == 1 || events == 2
}
)
let didDeleteSectionExpectation = self.expectation(
forNotification: "listMonitor:didDeleteSection:fromSectionIndex:",
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteSection:fromSectionIndex:"),
object: observer,
handler: { (note) -> Bool in
@@ -514,7 +509,7 @@ class ListObserverTests: BaseTestDataTestCase {
}
)
let didChangeExpectation = self.expectation(
forNotification: "listMonitorDidChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -531,10 +526,11 @@ class ListObserverTests: BaseTestDataTestCase {
stack.perform(
asynchronous: { (transaction) -> Bool in
transaction.deleteAll(
let count = try transaction.deleteAll(
From<TestEntity1>(),
Where(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
)
XCTAssertEqual(count, 2)
return transaction.hasChanges
},
success: { (hasChanges) in
@@ -555,7 +551,7 @@ class ListObserverTests: BaseTestDataTestCase {
// MARK: TestListObserver
@available(OSX 10.12, *)
@available(macOS 10.12, *)
class TestListObserver: ListSectionObserver {
// MARK: ListObserver

View File

@@ -2,7 +2,7 @@
// MigrationChainTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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

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

@@ -2,7 +2,7 @@
// ObjectObserverTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -31,7 +31,7 @@ import CoreStore
// MARK: - ObjectObserverTests
@available(OSX 10.12, *)
@available(macOS 10.12, *)
class ObjectObserverTests: BaseTestDataTestCase {
@objc
@@ -41,9 +41,9 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne(
guard let object = try stack.fetchOne(
From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
XCTFail()
return
@@ -58,7 +58,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
var events = 0
let willUpdateExpectation = self.expectation(
forNotification: "objectMonitor:willUpdateObject:",
forNotification: NSNotification.Name(rawValue: "objectMonitor:willUpdateObject:"),
object: observer,
handler: { (note) -> Bool in
@@ -75,7 +75,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
}
)
let didUpdateExpectation = self.expectation(
forNotification: "objectMonitor:didUpdateObject:changedPersistentKeys:",
forNotification: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
object: observer,
handler: { (note) -> Bool in
@@ -138,9 +138,9 @@ class ObjectObserverTests: BaseTestDataTestCase {
self.prepareTestDataForStack(stack)
guard let object = stack.fetchOne(
guard let object = try stack.fetchOne(
From<TestEntity1>(),
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
XCTFail()
return
@@ -155,7 +155,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
var events = 0
let didDeleteExpectation = self.expectation(
forNotification: "objectMonitor:didDeleteObject:",
forNotification: NSNotification.Name(rawValue: "objectMonitor:didDeleteObject:"),
object: observer,
handler: { (note) -> Bool in
@@ -203,7 +203,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
// MARK: TestObjectObserver
@available(OSX 10.12, *)
@available(macOS 10.12, *)
class TestObjectObserver: ObjectObserver {
typealias ObjectEntityType = TestEntity1
@@ -219,7 +219,7 @@ class TestObjectObserver: ObjectObserver {
)
}
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<KeyPath>) {
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<String>) {
NotificationCenter.default.post(
name: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),

View File

@@ -2,7 +2,7 @@
// OrderByTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -38,21 +38,21 @@ final class OrderByTests: XCTestCase {
do {
let orderBy = OrderBy()
XCTAssertEqual(orderBy, OrderBy([NSSortDescriptor]()))
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key", ascending: false)))
let orderBy = OrderBy<NSManagedObject>()
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([NSSortDescriptor]()))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key", ascending: false)))
XCTAssertTrue(orderBy.sortDescriptors.isEmpty)
}
do {
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
let orderBy = OrderBy(sortDescriptor)
let orderBy = OrderBy<NSManagedObject>(sortDescriptor)
XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key1", ascending: false)))
XCTAssertEqual(orderBy, OrderBy([sortDescriptor]))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key1", ascending: false)))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
}
do {
@@ -61,76 +61,76 @@ final class OrderByTests: XCTestCase {
NSSortDescriptor(key: "key1", ascending: true),
NSSortDescriptor(key: "key2", ascending: false)
]
let orderBy = OrderBy(sortDescriptors)
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
let orderBy = OrderBy<NSManagedObject>(sortDescriptors)
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertNotEqual(
orderBy,
OrderBy(
OrderBy<NSManagedObject>(
[
NSSortDescriptor(key: "key1", ascending: false),
NSSortDescriptor(key: "key2", ascending: false)
]
)
)
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
}
do {
let orderBy = OrderBy(.ascending("key1"))
let orderBy = OrderBy<NSManagedObject>(.ascending("key1"))
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2")))
XCTAssertEqual(orderBy, OrderBy([sortDescriptor]))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptor))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
}
do {
let orderBy = OrderBy(.ascending("key1"), .descending("key2"))
let orderBy = OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"))
let sortDescriptors = [
NSSortDescriptor(key: "key1", ascending: true),
NSSortDescriptor(key: "key2", ascending: false)
]
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertNotEqual(
orderBy,
OrderBy(
OrderBy<NSManagedObject>(
[
NSSortDescriptor(key: "key1", ascending: false),
NSSortDescriptor(key: "key2", ascending: false)
]
)
)
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
}
do {
let sortKeys: [SortKey] = [.ascending("key1"), .descending("key2")]
let orderBy = OrderBy(sortKeys)
let sortKeys: [OrderBy<NSManagedObject>.SortKey] = [.ascending("key1"), .descending("key2")]
let orderBy = OrderBy<NSManagedObject>(sortKeys)
let sortDescriptors = [
NSSortDescriptor(key: "key1", ascending: true),
NSSortDescriptor(key: "key2", ascending: false)
]
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertNotEqual(
orderBy,
OrderBy(
OrderBy<NSManagedObject>(
[
NSSortDescriptor(key: "key1", ascending: false),
NSSortDescriptor(key: "key2", ascending: false)
]
)
)
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
}
}
@@ -138,15 +138,15 @@ final class OrderByTests: XCTestCase {
@objc
dynamic func test_ThatOrderByClauseOperations_ComputeCorrectly() {
let orderBy1 = OrderBy(.ascending("key1"))
let orderBy2 = OrderBy(.descending("key2"))
let orderBy3 = OrderBy(.ascending("key3"))
let orderBy1 = OrderBy<NSManagedObject>(.ascending("key1"))
let orderBy2 = OrderBy<NSManagedObject>(.descending("key2"))
let orderBy3 = OrderBy<NSManagedObject>(.ascending("key3"))
do {
let plusOrderBy = orderBy1 + orderBy2 + orderBy3
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2"), .ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2"), .ascending("key3")))
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
@@ -158,14 +158,14 @@ final class OrderByTests: XCTestCase {
var plusOrderBy = orderBy1
plusOrderBy += orderBy2
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2")))
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2")))
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2")))
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1)
XCTAssertEqual(plusOrderBy.sortDescriptors, orderBy1.sortDescriptors + orderBy2.sortDescriptors)
plusOrderBy += orderBy3
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2")) + OrderBy(.ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")) + OrderBy<NSManagedObject>(.ascending("key3")))
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
@@ -178,8 +178,8 @@ final class OrderByTests: XCTestCase {
@objc
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
let orderBy = OrderBy(.ascending("key"))
let request = CoreStoreFetchRequest()
let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
let request = NSFetchRequest<NSFetchRequestResult>()
orderBy.applyToFetchRequest(request)
XCTAssertNotNil(request.sortDescriptors)
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
// SectionByTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -31,7 +31,7 @@ import CoreStore
//MARK: - SectionByTests
@available(OSX 10.12, *)
@available(macOS 10.12, *)
final class SectionByTests: XCTestCase {
@objc
@@ -39,13 +39,13 @@ final class SectionByTests: XCTestCase {
do {
let sectionBy = SectionBy("key")
let sectionBy = SectionBy<NSManagedObject>("key")
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key")
}
do {
let sectionBy = SectionBy("key") { $0.flatMap { "\($0):suffix" } }
let sectionBy = SectionBy<NSManagedObject>("key") { $0.flatMap { "\($0):suffix" } }
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key:suffix")
XCTAssertNil(sectionBy.sectionIndexTransformer(nil))

View File

@@ -2,7 +2,7 @@
// SelectTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -38,7 +38,7 @@ final class SelectTests: XCTestCase {
do {
let term: SelectTerm = "attribute"
let term: SelectTerm<NSManagedObject> = "attribute"
XCTAssertEqual(term, SelectTerm.attribute("attribute"))
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
@@ -58,7 +58,7 @@ final class SelectTests: XCTestCase {
}
do {
let term = SelectTerm.attribute("attribute")
let term = SelectTerm<NSManagedObject>.attribute("attribute")
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
XCTAssertNotEqual(term, SelectTerm.count("attribute"))
@@ -82,7 +82,7 @@ final class SelectTests: XCTestCase {
do {
let term = SelectTerm.average("attribute")
let term = SelectTerm<NSManagedObject>.average("attribute")
XCTAssertEqual(term, SelectTerm.average("attribute"))
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
@@ -106,7 +106,7 @@ final class SelectTests: XCTestCase {
}
do {
let term = SelectTerm.average("attribute", as: "alias")
let term = SelectTerm<NSManagedObject>.average("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.average("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
@@ -135,7 +135,7 @@ final class SelectTests: XCTestCase {
do {
let term = SelectTerm.count("attribute")
let term = SelectTerm<NSManagedObject>.count("attribute")
XCTAssertEqual(term, SelectTerm.count("attribute"))
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
@@ -159,7 +159,7 @@ final class SelectTests: XCTestCase {
}
do {
let term = SelectTerm.count("attribute", as: "alias")
let term = SelectTerm<NSManagedObject>.count("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.count("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
@@ -188,7 +188,7 @@ final class SelectTests: XCTestCase {
do {
let term = SelectTerm.maximum("attribute")
let term = SelectTerm<NSManagedObject>.maximum("attribute")
XCTAssertEqual(term, SelectTerm.maximum("attribute"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
@@ -212,7 +212,7 @@ final class SelectTests: XCTestCase {
}
do {
let term = SelectTerm.maximum("attribute", as: "alias")
let term = SelectTerm<NSManagedObject>.maximum("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.maximum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
@@ -241,7 +241,7 @@ final class SelectTests: XCTestCase {
do {
let term = SelectTerm.minimum("attribute")
let term = SelectTerm<NSManagedObject>.minimum("attribute")
XCTAssertEqual(term, SelectTerm.minimum("attribute"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
@@ -265,7 +265,7 @@ final class SelectTests: XCTestCase {
}
do {
let term = SelectTerm.minimum("attribute", as: "alias")
let term = SelectTerm<NSManagedObject>.minimum("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.minimum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
@@ -294,7 +294,7 @@ final class SelectTests: XCTestCase {
do {
let term = SelectTerm.sum("attribute")
let term = SelectTerm<NSManagedObject>.sum("attribute")
XCTAssertEqual(term, SelectTerm.sum("attribute"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
@@ -318,7 +318,7 @@ final class SelectTests: XCTestCase {
}
do {
let term = SelectTerm.sum("attribute", as: "alias")
let term = SelectTerm<NSManagedObject>.sum("attribute", as: "alias")
XCTAssertEqual(term, SelectTerm.sum("attribute", as: "alias"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
@@ -347,7 +347,7 @@ final class SelectTests: XCTestCase {
do {
let term = SelectTerm.objectID()
let term = SelectTerm<NSManagedObject>.objectID()
XCTAssertEqual(term, SelectTerm.objectID())
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias"))
XCTAssertNotEqual(term, SelectTerm.attribute("attribute"))
@@ -368,7 +368,7 @@ final class SelectTests: XCTestCase {
}
do {
let term = SelectTerm.objectID(as: "alias")
let term = SelectTerm<NSManagedObject>.objectID(as: "alias")
XCTAssertEqual(term, SelectTerm.objectID(as: "alias"))
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias2"))
XCTAssertNotEqual(term, SelectTerm.objectID())
@@ -393,12 +393,12 @@ final class SelectTests: XCTestCase {
@objc
dynamic func test_ThatSelectClauses_ConfigureCorrectly() {
let term1 = SelectTerm.attribute("attribute1")
let term2 = SelectTerm.attribute("attribute2")
let term3 = SelectTerm.attribute("attribute3")
let term1 = SelectTerm<NSManagedObject>.attribute("attribute1")
let term2 = SelectTerm<NSManagedObject>.attribute("attribute2")
let term3 = SelectTerm<NSManagedObject>.attribute("attribute3")
do {
let select = Select<Int>(term1, term2, term3)
let select = Select<NSManagedObject, Int>(term1, term2, term3)
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
@@ -408,7 +408,7 @@ final class SelectTests: XCTestCase {
}
do {
let select = Select<Int>([term1, term2, term3])
let select = Select<NSManagedObject, Int>([term1, term2, term3])
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])

View File

@@ -2,7 +2,7 @@
// SetupTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// StorageInterfaceTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -83,7 +83,21 @@ final class StorageInterfaceTests: XCTestCase {
let store = SQLiteStore()
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertNil(store.configuration)
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(store.fileURL, SQLiteStore.defaultFileURL)
XCTAssertTrue(store.migrationMappingProviders.isEmpty)
@@ -93,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",
@@ -109,7 +123,21 @@ final class StorageInterfaceTests: XCTestCase {
)
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1")
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(store.fileURL, fileURL)
XCTAssertEqual(store.migrationMappingProviders as! [XcodeSchemaMappingProvider], [mappingProvider])
@@ -132,7 +160,21 @@ final class StorageInterfaceTests: XCTestCase {
)
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1")
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.defaultRootDirectory)
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)
@@ -167,7 +209,21 @@ final class StorageInterfaceTests: XCTestCase {
let store = SQLiteStore.legacy()
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertNil(store.configuration)
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(store.fileURL, SQLiteStore.legacyDefaultFileURL)
XCTAssertTrue(store.migrationMappingProviders.isEmpty)
@@ -190,7 +246,21 @@ final class StorageInterfaceTests: XCTestCase {
)
XCTAssertEqual(type(of: store).storeType, NSSQLiteStoreType)
XCTAssertEqual(store.configuration, "config1")
XCTAssertEqual(store.storeOptions as NSDictionary?, [NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary)
if #available(iOS 11.0, macOS 10.13, tvOS 11.0, *) {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"],
NSBinaryStoreInsecureDecodingCompatibilityOption: true] as NSDictionary
)
}
else {
XCTAssertEqual(
store.storeOptions as NSDictionary?,
[NSSQLitePragmasOption: ["journal_mode": "WAL"]] as NSDictionary
)
}
XCTAssertEqual(store.fileURL.deletingLastPathComponent(), SQLiteStore.legacyDefaultRootDirectory)
XCTAssertEqual(store.fileURL.lastPathComponent, fileName)

View File

@@ -2,7 +2,7 @@
// TestEntity1.swift
// CoreStore
//
// Copyright © 2014 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// TestEntity1.swift
// CoreStore
//
// Copyright © 2014 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// TransactionTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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")
@@ -387,7 +384,7 @@ final class TransactionTests: BaseTestCase {
}
@available(OSX 10.12, *)
@available(macOS 10.12, *)
@objc
dynamic func test_ThatSynchronousTransactions_CanCommitWithoutWaitingForMerges() {
@@ -396,7 +393,7 @@ final class TransactionTests: BaseTestCase {
let observer = TestListObserver()
let monitor = stack.monitorList(
From<TestEntity1>(),
OrderBy(.ascending("testEntityID"))
OrderBy<TestEntity1>(.ascending("testEntityID"))
)
monitor.addObserver(observer)
@@ -404,7 +401,7 @@ final class TransactionTests: BaseTestCase {
var events = 0
let willChangeExpectation = self.expectation(
forNotification: "listMonitorWillChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -418,7 +415,7 @@ final class TransactionTests: BaseTestCase {
}
)
let didInsertObjectExpectation = self.expectation(
forNotification: "listMonitor:didInsertObject:toIndexPath:",
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
object: observer,
handler: { (note) -> Bool in
@@ -448,7 +445,7 @@ final class TransactionTests: BaseTestCase {
}
)
let didChangeExpectation = self.expectation(
forNotification: "listMonitorDidChange:",
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
object: observer,
handler: { (note) -> Bool in
@@ -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
@@ -737,7 +779,7 @@ final class TransactionTests: BaseTestCase {
createDiscardExpectation.fulfill()
try transaction.cancel()
},
success: {
success: { _ in
XCTFail()
},
@@ -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
@@ -795,7 +837,7 @@ final class TransactionTests: BaseTestCase {
try transaction.cancel()
},
success: {
success: { _ in
XCTFail()
},
@@ -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()
@@ -828,22 +870,29 @@ final class TransactionTests: BaseTestCase {
try transaction.cancel()
},
success: {
success: { _ in
XCTFail()
},
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

@@ -2,7 +2,7 @@
// TweakTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -43,7 +43,7 @@ final class TweakTests: XCTestCase {
$0.fetchLimit = 200
$0.predicate = predicate
}
let request = CoreStoreFetchRequest()
let request = NSFetchRequest<NSFetchRequestResult>()
tweak.applyToFetchRequest(request)
XCTAssertEqual(request.fetchOffset, 100)
XCTAssertEqual(request.fetchLimit, 200)

View File

@@ -2,7 +2,7 @@
// WhereTests.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -31,12 +31,12 @@ import CoreStore
// MARK: - XCTAssertAllEqual
private func XCTAssertAllEqual(_ whereClauses: Where...) {
private func XCTAssertAllEqual<D>(_ whereClauses: Where<D>...) {
XCTAssertAllEqual(whereClauses)
}
private func XCTAssertAllEqual(_ whereClauses: [Where]) {
private func XCTAssertAllEqual<D>(_ whereClauses: [Where<D>]) {
for i in whereClauses.indices {
@@ -52,56 +52,331 @@ private func XCTAssertAllEqual(_ whereClauses: [Where]) {
final class WhereTests: XCTestCase {
@objc
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
dynamic func test_ThatWhereClauses_ConfigureCorrectly() {
do {
let whereClause = Where()
XCTAssertEqual(whereClause, Where(true))
XCTAssertNotEqual(whereClause, Where(false))
let whereClause = Where<NSManagedObject>()
XCTAssertEqual(whereClause, Where<NSManagedObject>(true))
XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false))
XCTAssertEqual(whereClause.predicate, NSPredicate(value: true))
}
do {
let whereClause = Where(true)
XCTAssertEqual(whereClause, Where())
XCTAssertNotEqual(whereClause, Where(false))
let whereClause = Where<NSManagedObject>(true)
XCTAssertEqual(whereClause, Where<NSManagedObject>())
XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false))
XCTAssertEqual(whereClause.predicate, NSPredicate(value: true))
}
do {
let predicate = NSPredicate(format: "%K == %@", "key", "value")
let whereClause = Where(predicate)
XCTAssertEqual(whereClause, Where(predicate))
let whereClause = Where<NSManagedObject>(predicate)
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause = Where("%K == %@", "key", "value")
let whereClause = Where<NSManagedObject>("%K == %@", "key", "value")
let predicate = NSPredicate(format: "%K == %@", "key", "value")
XCTAssertEqual(whereClause, Where(predicate))
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause = Where("%K == %@", argumentArray: ["key", "value"])
let whereClause = Where<NSManagedObject>("%K == %@", argumentArray: ["key", "value"])
let predicate = NSPredicate(format: "%K == %@", "key", "value")
XCTAssertEqual(whereClause, Where(predicate))
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause = Where("key", isEqualTo: "value")
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
let predicate = NSPredicate(format: "%K == %@", "key", "value")
XCTAssertEqual(whereClause, Where(predicate))
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause = Where("key", isMemberOf: ["value1", "value2", "value3"])
let whereClause = Where<NSManagedObject>("key", isMemberOf: ["value1", "value2", "value3"])
let predicate = NSPredicate(format: "%K IN %@", "key", ["value1", "value2", "value3"])
XCTAssertEqual(whereClause, Where(predicate))
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
@@ -113,112 +388,112 @@ final class WhereTests: XCTestCase {
let value: Int = 100
XCTAssertAllEqual(
Where("%K == %d", "key", value),
Where("%K == %d", "key", value as AnyObject),
Where("%K == %d", "key", NSNumber(value: value)),
Where("%K == %@", "key", value),
Where("%K == %@", "key", value as AnyObject),
Where("%K == %@", "key", NSNumber(value: value)),
Where("key", isEqualTo: value),
Where("key", isEqualTo: NSNumber(value: value))
Where<NSManagedObject>("%K == %d", "key", value),
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
Where<NSManagedObject>("%K == %d", "key", NSNumber(value: value)),
Where<NSManagedObject>("%K == %@", "key", value),
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
Where<NSManagedObject>("%K == %@", "key", NSNumber(value: value)),
Where<NSManagedObject>("key", isEqualTo: value),
Where<NSManagedObject>("key", isEqualTo: NSNumber(value: value))
)
}
do {
let value = NSNumber(value: 100)
XCTAssertAllEqual(
Where("%K == %d", "key", value),
Where("%K == %d", "key", value as AnyObject),
Where("%K == %d", "key", value.intValue),
Where("%K == %@", "key", value),
Where("%K == %@", "key", value as AnyObject),
Where("%K == %@", "key", value.intValue),
Where("key", isEqualTo: value),
Where("key", isEqualTo: value.intValue)
Where<NSManagedObject>("%K == %d", "key", value),
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
Where<NSManagedObject>("%K == %d", "key", value.intValue),
Where<NSManagedObject>("%K == %@", "key", value),
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
Where<NSManagedObject>("%K == %@", "key", value.intValue),
Where<NSManagedObject>("key", isEqualTo: value),
Where<NSManagedObject>("key", isEqualTo: value.intValue)
)
}
do {
let value: Int64 = Int64.max
XCTAssertAllEqual(
Where("%K == %d", "key", value),
Where("%K == %d", "key", value as AnyObject),
Where("%K == %d", "key", NSNumber(value: value)),
Where("%K == %@", "key", value),
Where("%K == %@", "key", value as AnyObject),
Where("%K == %@", "key", NSNumber(value: value)),
Where("key", isEqualTo: value),
Where("key", isEqualTo: NSNumber(value: value))
Where<NSManagedObject>("%K == %d", "key", value),
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
Where<NSManagedObject>("%K == %d", "key", NSNumber(value: value)),
Where<NSManagedObject>("%K == %@", "key", value),
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
Where<NSManagedObject>("%K == %@", "key", NSNumber(value: value)),
Where<NSManagedObject>("key", isEqualTo: value),
Where<NSManagedObject>("key", isEqualTo: NSNumber(value: value))
)
}
do {
let value = NSNumber(value: Int64.max)
XCTAssertAllEqual(
Where("%K == %d", "key", value),
Where("%K == %d", "key", value as AnyObject),
Where("%K == %d", "key", value.int64Value),
Where("%K == %@", "key", value),
Where("%K == %@", "key", value as AnyObject),
Where("%K == %@", "key", value.int64Value),
Where("key", isEqualTo: value),
Where("key", isEqualTo: value.int64Value)
Where<NSManagedObject>("%K == %d", "key", value),
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
Where<NSManagedObject>("%K == %d", "key", value.int64Value),
Where<NSManagedObject>("%K == %@", "key", value),
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
Where<NSManagedObject>("%K == %@", "key", value.int64Value),
Where<NSManagedObject>("key", isEqualTo: value),
Where<NSManagedObject>("key", isEqualTo: value.int64Value)
)
}
do {
let value: String = "value"
XCTAssertAllEqual(
Where("%K == %s", "key", value),
Where("%K == %s", "key", value as AnyObject),
Where("%K == %s", "key", NSString(string: value)),
Where("%K == %@", "key", value),
Where("%K == %@", "key", value as AnyObject),
Where("%K == %@", "key", NSString(string: value)),
Where("key", isEqualTo: value),
Where("key", isEqualTo: value as NSString),
Where("key", isEqualTo: NSString(string: value))
Where<NSManagedObject>("%K == %s", "key", value),
Where<NSManagedObject>("%K == %s", "key", value as AnyObject),
Where<NSManagedObject>("%K == %s", "key", NSString(string: value)),
Where<NSManagedObject>("%K == %@", "key", value),
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
Where<NSManagedObject>("%K == %@", "key", NSString(string: value)),
Where<NSManagedObject>("key", isEqualTo: value),
Where<NSManagedObject>("key", isEqualTo: value as NSString),
Where<NSManagedObject>("key", isEqualTo: NSString(string: value))
)
}
do {
let value = NSString(string: "value")
XCTAssertAllEqual(
Where("%K == %s", "key", value),
Where("%K == %s", "key", value as String),
Where("%K == %s", "key", value as String as AnyObject),
Where("%K == %@", "key", value),
Where("%K == %@", "key", value as String),
Where("%K == %@", "key", value as String as AnyObject),
Where("key", isEqualTo: value),
Where("key", isEqualTo: value as String),
Where("key", isEqualTo: value as String as NSString)
Where<NSManagedObject>("%K == %s", "key", value),
Where<NSManagedObject>("%K == %s", "key", value as String),
Where<NSManagedObject>("%K == %s", "key", value as String as AnyObject),
Where<NSManagedObject>("%K == %@", "key", value),
Where<NSManagedObject>("%K == %@", "key", value as String),
Where<NSManagedObject>("%K == %@", "key", value as String as AnyObject),
Where<NSManagedObject>("key", isEqualTo: value),
Where<NSManagedObject>("key", isEqualTo: value as String),
Where<NSManagedObject>("key", isEqualTo: value as String as NSString)
)
}
do {
let value: [Int] = [100, 200]
XCTAssertAllEqual(
Where("%K IN %@", "key", value),
Where("%K IN %@", "key", value as AnyObject),
Where("%K IN %@", "key", value as [AnyObject]),
Where("%K IN %@", "key", value as NSArray),
Where("%K IN %@", "key", NSArray(array: value)),
Where("%K IN %@", "key", value as AnyObject as! NSArray),
Where("key", isMemberOf: value)
Where<NSManagedObject>("%K IN %@", "key", value),
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject),
Where<NSManagedObject>("%K IN %@", "key", value as [AnyObject]),
Where<NSManagedObject>("%K IN %@", "key", value as NSArray),
Where<NSManagedObject>("%K IN %@", "key", NSArray(array: value)),
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject as! NSArray),
Where<NSManagedObject>("key", isMemberOf: value)
)
}
do {
let value: [Int64] = [Int64.min, 100, Int64.max]
XCTAssertAllEqual(
Where("%K IN %@", "key", value),
Where("%K IN %@", "key", value as AnyObject),
Where("%K IN %@", "key", value as [AnyObject]),
Where("%K IN %@", "key", value as NSArray),
Where("%K IN %@", "key", NSArray(array: value)),
Where("%K IN %@", "key", value as AnyObject as! NSArray),
Where("key", isMemberOf: value)
Where<NSManagedObject>("%K IN %@", "key", value),
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject),
Where<NSManagedObject>("%K IN %@", "key", value as [AnyObject]),
Where<NSManagedObject>("%K IN %@", "key", value as NSArray),
Where<NSManagedObject>("%K IN %@", "key", NSArray(array: value)),
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject as! NSArray),
Where<NSManagedObject>("key", isMemberOf: value)
)
}
}
@@ -226,9 +501,9 @@ final class WhereTests: XCTestCase {
@objc
dynamic func test_ThatWhereClauseOperations_ComputeCorrectly() {
let whereClause1 = Where("key1", isEqualTo: "value1")
let whereClause2 = Where("key2", isEqualTo: "value2")
let whereClause3 = Where("key3", isEqualTo: "value3")
let whereClause1 = Where<NSManagedObject>("key1", isEqualTo: "value1")
let whereClause2 = Where<NSManagedObject>("key2", isEqualTo: "value2")
let whereClause3 = Where<NSManagedObject>("key3", isEqualTo: "value3")
do {
@@ -256,6 +531,21 @@ final class WhereTests: XCTestCase {
XCTAssertEqual(andWhere.predicate, andPredicate)
XCTAssertEqual(andWhere, whereClause1 && whereClause2 && whereClause3)
}
do {
let andWhere = whereClause1 && whereClause2 && whereClause3
let noneWhere: Where<NSManagedObject>? = nil
let someWhere: Where<NSManagedObject>? = Where<NSManagedObject>("key4", isEqualTo: "value4")
let finalNoneWhere = andWhere &&? noneWhere
let finalSomeWhere = andWhere &&? someWhere
let unwrappedFinalSomeWhere = andWhere && someWhere!
XCTAssertEqual(andWhere.predicate, finalNoneWhere.predicate)
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
}
do {
let orWhere = whereClause1 || whereClause2 || whereClause3
@@ -272,13 +562,28 @@ final class WhereTests: XCTestCase {
XCTAssertEqual(orWhere.predicate, orPredicate)
XCTAssertEqual(orWhere, whereClause1 || whereClause2 || whereClause3)
}
do {
let orWhere = whereClause1 || whereClause2 || whereClause3
let noneWhere: Where<NSManagedObject>? = nil
let someWhere: Where<NSManagedObject>? = Where<NSManagedObject>("key4", isEqualTo: "value4")
let finalNoneWhere = orWhere &&? noneWhere
let finalSomeWhere = orWhere &&? someWhere
let unwrappedFinalSomeWhere = orWhere && someWhere!
XCTAssertEqual(orWhere.predicate, finalNoneWhere.predicate)
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
}
}
@objc
dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() {
let whereClause = Where("key", isEqualTo: "value")
let request = CoreStoreFetchRequest()
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
let request = NSFetchRequest<NSFetchRequestResult>()
whereClause.applyToFetchRequest(request)
XCTAssertNotNil(request.predicate)
XCTAssertEqual(request.predicate, whereClause.predicate)

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright © 2014 John Rommel Estropia
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

View File

@@ -1,8 +1,9 @@
// swift-tools-version:4.2
//
// Package.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -25,21 +26,18 @@
import PackageDescription
let targets: [Target]
#if os(iOS)
targets = [Target(name: "CoreStore iOS")]
#elseif os(OSX)
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>

411
README.md
View File

@@ -6,47 +6,48 @@ 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 3.1:** iOS 8+ / 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 3.x to 4.x? Check out the [new features](#features) and make sure to read the [Migration guide](#upgrading-from-3xx-to-4xx).
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).
## Why use CoreStore?
CoreStore is the answer to the [challenges](http://inessential.com/2010/02/26/on_switching_away_from_core_data) [of](http://bsktapp.com/blog/why-is-realm-great-and-why-are-we-not-using-it/) [using](https://www.quora.com/Why-would-you-use-Realm-over-Core-Data) [Core](http://sebastiandobrincu.com/blog/5-reasons-why-you-should-choose-realm-over-coredata) [Data](https://medium.com/the-way-north/ditching-core-data-865c1bb5564c#.a5h8ou6ri).
CoreStore was (and is) heavily shaped by real-world needs of developing data-dependent apps. It enforces safe and convenient Core Data usage while letting you take advantage of the industry's encouraged best practices.
### Features
- **Tight design around Swifts code elegance and type safety.** CoreStore fully utilizes Swift's community-driven language features.
- **Safer concurrency architecture.** CoreStore makes it hard to fall into common concurrency mistakes. The main `NSManagedObjectContext` is strictly read-only, while all updates are done through serial *transactions*. *(See [Saving and processing transactions](#saving-and-processing-transactions))*
- **Clean fetching and querying API.** Fetching objects is easy, but querying for raw aggregates (`min`, `max`, etc.) and raw property values is now just as convenient. *(See [Fetching and querying](#fetching-and-querying))*
- **Type-safe, easy to configure observers.** You don't have to deal with the burden of setting up `NSFetchedResultsController`s and KVO. As an added bonus, `ListMonitor`s and `ObjectMonitor`s can have multiple observers. This means you can have multiple view controllers efficiently share a single resource! *(See [Observing changes and notifications](#observing-changes-and-notifications))*
- **Efficient importing utilities.** Map your entities once with their corresponding import source (JSON for example), and importing from *transactions* becomes elegant. Uniquing is also done with an efficient find-and-replace algorithm. *(See [Importing data](#importing-data))*
- ⭐️ **New in 4.0: Say goodbye to *.xcdatamodeld* files!** The new `CoreStoreObject` is *the* replacement to `NSManagedObject`. `CoreStoreObject` subclasses can declare type-safe properties all in Swift code, no need to maintain separate resource files for the models. As bonus, these special properties support custom types, and can be used to create type-safe keypaths and queries. *(See [Type-safe `CoreStoreObject`s](#type-safe-corestoreobjects))*
- **Progressive migrations.** No need to think how to migrate from all previous model versions to your latest model. Just tell the `DataStack` the sequence of version strings (`MigrationChain`s) and CoreStore will automatically use progressive migrations when needed. *(See [Migrations](#migrations))*
- ⭐️ **New in 4.0: Easier custom migrations.** Say goodbye to *.xcmappingmodel* files; CoreStore can now infer entity mappings when possible, while still allowing an easy way to write custom mappings. *(See [Migrations](#migrations))*
- **Plug-in your own logging framework.** Although a default logger is built-in, all logging, asserting, and error reporting can be funneled to `CoreStoreLogger` protocol implementations. *(See [Logging and error reporting](#logging-and-error-reporting))*
- **Heavy support for multiple persistent stores per data stack.** CoreStore lets you manage separate stores in a single `DataStack`, just the way *.xcdatamodeld* configurations are designed to. CoreStore will also manage one stack by default, but you can create and manage as many as you need. *(See [Setting up](#setting-up))*
- **Free to name entities and their class names independently.** CoreStore gets around a restriction with other Core Data wrappers where the entity name should be the same as the `NSManagedObject` subclass name. CoreStore loads entity-to-class mappings from the managed object model file, so you can assign different names for the entities and their class names.
- **Full Documentation.** No magic here; all public classes, functions, properties, etc. have detailed *Apple Docs*. This *README* also introduces a lot of concepts and explains a lot of CoreStore's behavior.
- **Informative (and pretty) logs.** All CoreStore and Core Data-related types now have very informative and pretty print outputs! *(See [Logging and error reporting](#logging-and-error-reporting))*
- **Objective-C support!** Is your project transitioning from Objective-C to Swift but still can't quite fully convert some huge classes to Swift yet? CoreStore adjusts to the ever-increasing Swift adoption. While still written in pure Swift, all CoreStore types have their corresponding Objective-C-visible "bridging classes". *(See [Objective-C support](#objective-c-support))*
- **More extensive Unit Tests.** Extending CoreStore is safe without having to worry about breaking old behavior.
- **💎Tight design around Swifts code elegance and type safety.** CoreStore fully utilizes Swift's community-driven language features.
- **🚦Safer concurrency architecture.** CoreStore makes it hard to fall into common concurrency mistakes. The main `NSManagedObjectContext` is strictly read-only, while all updates are done through serial *transactions*. *(See [Saving and processing transactions](#saving-and-processing-transactions))*
- **🔍Clean fetching and querying API.** Fetching objects is easy, but querying for raw aggregates (`min`, `max`, etc.) and raw property values is now just as convenient. *(See [Fetching and querying](#fetching-and-querying))*
- **🔭Type-safe, easy to configure observers.** You don't have to deal with the burden of setting up `NSFetchedResultsController`s and KVO. As an added bonus, `ListMonitor`s and `ObjectMonitor`s can have multiple observers. This means you can have multiple view controllers efficiently share a single resource! *(See [Observing changes and notifications](#observing-changes-and-notifications))*
- **📥Efficient importing utilities.** Map your entities once with their corresponding import source (JSON for example), and importing from *transactions* becomes elegant. Uniquing is also done with an efficient find-and-replace algorithm. *(See [Importing data](#importing-data))*
- **🗑Say goodbye to *.xcdatamodeld* files!** The new `CoreStoreObject` is *the* replacement to `NSManagedObject`. `CoreStoreObject` subclasses can declare type-safe properties all in Swift code, no need to maintain separate resource files for the models. As bonus, these special properties support custom types, and can be used to create type-safe keypaths and queries. *(See [Type-safe `CoreStoreObject`s](#type-safe-corestoreobjects))*
- **🔗Progressive migrations.** No need to think how to migrate from all previous model versions to your latest model. Just tell the `DataStack` the sequence of version strings (`MigrationChain`s) and CoreStore will automatically use progressive migrations when needed. *(See [Migrations](#migrations))*
- **Easier custom migrations.** Say goodbye to *.xcmappingmodel* files; CoreStore can now infer entity mappings when possible, while still allowing an easy way to write custom mappings. *(See [Migrations](#migrations))*
- **📝Plug-in your own logging framework.** Although a default logger is built-in, all logging, asserting, and error reporting can be funneled to `CoreStoreLogger` protocol implementations. *(See [Logging and error reporting](#logging-and-error-reporting))*
- **Heavy support for multiple persistent stores per data stack.** CoreStore lets you manage separate stores in a single `DataStack`, just the way *.xcdatamodeld* configurations are designed to. CoreStore will also manage one stack by default, but you can create and manage as many as you need. *(See [Setting up](#setting-up))*
- **🎯Free to name entities and their class names independently.** CoreStore gets around a restriction with other Core Data wrappers where the entity name should be the same as the `NSManagedObject` subclass name. CoreStore loads entity-to-class mappings from the managed object model file, so you can assign different names for the entities and their class names.
- **📙Full Documentation.** No magic here; all public classes, functions, properties, etc. have detailed *Apple Docs*. This *README* also introduces a lot of concepts and explains a lot of CoreStore's behavior.
- **Informative (and pretty) logs.** All CoreStore and Core Data-related types now have very informative and pretty print outputs! *(See [Logging and error reporting](#logging-and-error-reporting))*
- **🎗Objective-C support!** Is your project transitioning from Objective-C to Swift but still can't quite fully convert some huge classes to Swift yet? CoreStore adjusts to the ever-increasing Swift adoption. While still written in pure Swift, all CoreStore types have their corresponding Objective-C-visible "bridging classes". *(See [Objective-C support](#objective-c-support))*
- **🛡More extensive Unit Tests.** Extending CoreStore is safe without having to worry about breaking old behavior.
*Have ideas that may benefit other Core Data users? [Feature Request](https://github.com/JohnEstropia/CoreStore/issues)s are welcome!*
@@ -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)
@@ -85,7 +86,8 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
- [`Select<T>` clause](#selectt-clause)
- [`GroupBy` clause](#groupby-clause)
- [Logging and error reporting](#logging-and-error-reporting)
- [Observing changes and notifications](#observing-changes-and-notifications) (unavailable on macOS)
- [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)
@@ -94,8 +96,6 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
- [Roadmap](#roadmap)
- [Installation](#installation)
- [Changesets](#changesets)
- [Upgrading from 3.x.x to 4.x.x](#upgrading-from-3xx-to-4xx)
- [Other Releases](#other-releases)
- [Contact](#contact)
- [Who uses CoreStore?](#who-uses-corestore)
- [License](#license)
@@ -141,26 +141,24 @@ 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(
From<MyPersonEntity>(),
Where("age > 30"),
OrderBy(.ascending("name"), .descending("age")),
Tweak { (fetchRequest) -> Void in
fetchRequest.includesPendingChanges = false
}
let people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30),
.orderBy(.ascending(\.name), .descending(.\age)),
.tweak({ $0.includesPendingChanges = false })
)
```
Querying values:
```swift
let maxAge = CoreStore.queryValue(
From<MyPersonEntity>(),
Select<Int>(.maximum("age"))
let maxAge = try CoreStore.queryValue(
From<MyPersonEntity>()
.select(Int.self, .maximum(\.age))
)
```
@@ -219,9 +217,9 @@ let migrationProgress = dataStack.addStorage(
completion: { (result) -> Void in
switch result {
case .success(let storage):
print("Successfully added sqlite store: \(storage)"
print("Successfully added sqlite store: \(storage)")
case .failure(let error):
print("Failed adding sqlite store with error: \(error)"
print("Failed adding sqlite store with error: \(error)")
}
}
)
@@ -229,8 +227,8 @@ let migrationProgress = dataStack.addStorage(
CoreStore.defaultStack = dataStack // pass the dataStack to CoreStore for easier access later on
```
(If you have never heard of "Configurations", you'll find them in your *.xcdatamodeld* file)
<img src="https://cloud.githubusercontent.com/assets/3029684/8333192/e52cfaac-1acc-11e5-9902-08724f9f1324.png" alt="xcode configurations screenshot" height=212 />
> 💡If you have never heard of "Configurations", you'll find them in your *.xcdatamodeld* file
> <img src="https://cloud.githubusercontent.com/assets/3029684/8333192/e52cfaac-1acc-11e5-9902-08724f9f1324.png" alt="xcode configurations screenshot" height=212 />
In our sample code above, note that you don't need to do the `CoreStore.defaultStack = dataStack` line. You can just as well hold a reference to the `DataStack` like below and call all its instance methods directly:
```swift
@@ -263,12 +261,14 @@ class MyViewController: UIViewController {
}
}
func methodToBeCalledLaterOn() {
let objects = CoreStore.fetchAll(From(MyEntity))
let objects = CoreStore.fetchAll(From<MyEntity>())
print(objects)
}
}
```
> 💡By default, CoreStore will initialize `NSManagedObject`s from *.xcdatamodeld* files, but you can create models completely from source code using `CoreStoreObject`s and `CoreStoreSchema`. To use this feature, refer to [Type-safe `CoreStoreObject`s](#type-safe-corestoreobjects).
Notice that in our previous examples, `addStorageAndWait(_:)` and `addStorage(_:completion:)` both accept either `InMemoryStore`, `SQLiteStore`, or `ICloudStore`. These implement the `StorageInterface` protocol.
### In-memory store
@@ -314,7 +314,7 @@ public protocol LocalStorage: StorageInterface {
If you have custom `NSIncrementalStore` or `NSAtomicStore` subclasses, you can implement this protocol and use it similarly to `SQLiteStore`.
### iCloud Store
> **Important:** The iCloud Store is currently in beta. Please use with caution. If you have any concerns please do send me a message on [Twitter](https://twitter.com/JohnEstropia) or on the [CoreStore Slack Team](http://swift-corestore-slack.herokuapp.com/)
> ⚠️**Important:** The iCloud Store is being deprecated. Please use with caution. If you have any concerns please do send me a message on [Twitter](https://twitter.com/JohnEstropia) or on the [CoreStore Slack Team](http://swift-corestore-slack.herokuapp.com/)
As a counterpart to `LocalStorage`, the `CloudStorage` protocol abstracts stores managed in the cloud. CoreStore currently provides the concrete class `ICloudStore`. Unlike `InMemoryStore` and `SQLiteStore` though, the `ICloudStore`'s initializer may return `nil` if the iCloud container could not be located or if iCloud is not available on the device:
```swift
@@ -460,6 +460,55 @@ CoreStore.defaultStack = DataStack(
)
```
**`CoreStoreSchema`-based model versions with progressive migration**
```swift
typealias Animal = V2.Animal
typealias Dog = V2.Dog
typealias Person = V2.Person
enum V2 {
class Animal: CoreStoreObject {
// ...
}
class Dog: Animal {
// ...
}
class Person: CoreStoreObject {
// ...
}
}
enum V1 {
class Animal: CoreStoreObject {
// ...
}
class Dog: Animal {
// ...
}
class Person: CoreStoreObject {
// ...
}
}
CoreStore.defaultStack = DataStack(
CoreStoreSchema(
modelVersion: "V1",
entities: [
Entity<V1.Animal>("Animal", isAbstract: true),
Entity<V1.Dog>("Dog"),
Entity<V1.Person>("Person")
]
),
CoreStoreSchema(
modelVersion: "V2",
entities: [
Entity<V2.Animal>("Animal", isAbstract: true),
Entity<V2.Dog>("Dog"),
Entity<V2.Person>("Person")
]
),
migrationChain: ["V1", "V2"]
)
```
### Starting migrations
We have seen `addStorageAndWait(...)` used to initialize our persistent store. As the method name's *~AndWait* suffix suggests though, this method blocks so it should not do long tasks such as store migrations. In fact CoreStore will only attempt a synchronous **lightweight** migration if you explicitly provide the `.allowSynchronousLightweightMigration` option:
@@ -504,14 +553,14 @@ This closure is executed on the main thread so UIKit and AppKit calls can be don
### Progressive migrations
By default, CoreStore uses Core Data's default automatic migration mechanism. In other words, CoreStore will try to migrate the existing persistent store to the *.xcdatamodeld* file's current model version. If no mapping model is found from the store's version to the data model's version, CoreStore gives up and reports an error.
By default, CoreStore uses Core Data's default automatic migration mechanism. In other words, CoreStore will try to migrate the existing persistent store until it matches the `SchemaHistory`'s `currentModelVersion`. If no mapping model path is found from the store's version to the data model's version, CoreStore gives up and reports an error.
The `DataStack` lets you specify hints on how to break a migration into several sub-migrations using a `MigrationChain`. This is typically passed to the `DataStack` initializer and will be applied to all stores added to the `DataStack` with `addSQLiteStore(...)` and its variants:
```swift
let dataStack = DataStack(migrationChain:
["MyAppModel", "MyAppModelV2", "MyAppModelV3", "MyAppModelV4"])
```
The most common usage is to pass in the *.xcdatamodeld* version names in increasing order as above.
The most common usage is to pass in the model version (*.xcdatamodeld* version names for `NSManagedObject`s, or the `modelName` for `CoreStoreSchema`s) in increasing order as above.
For more complex, non-linear migration paths, you can also pass in a version tree that maps the key-values to the source-destination versions:
```swift
@@ -536,7 +585,7 @@ The `MigrationChain` is validated when passed to the `DataStack` and unless it i
- a version appears twice as a key in a dictionary literal
- a loop is found in any of the paths
One important thing to remember is that **if a `MigrationChain` is specified, the *.xcdatamodeld*'s "Current Version" will be bypassed** and the `MigrationChain`'s leafmost version will be the `DataStack`'s base model version.
> ⚠️**Important: If a `MigrationChain` is specified, the *.xcdatamodeld*'s "Current Version" will be bypassed** and the `MigrationChain`'s leafmost version will be the `DataStack`'s base model version.
### Forecasting migrations
@@ -671,7 +720,7 @@ dataStack.perform(
}
)
```
Never use `try?` or `try!` on a `transaction.cancel()` call. Always use `try`. Using `try?` will swallow the cancellation and the transaction will proceed to save as normal. Using `try!` will crash the app as `transaction.cancel()` will *always* throw an error.
> ⚠️**Important:** Never use `try?` or `try!` on a `transaction.cancel()` call. Always use `try`. Using `try?` will swallow the cancellation and the transaction will proceed to save as normal. Using `try!` will crash the app as `transaction.cancel()` will *always* throw an error.
The examples above use `perform(asynchronous:...)`, but there are actually 3 types of transactions at your disposal: *asynchronous*, *synchronous*, and *unsafe*.
@@ -708,6 +757,9 @@ CoreStore.perform(
}
)
```
> Be careful when returning `NSManagedObject`s or `CoreStoreObject`s from the transaction closure. Those instances are for the transaction's use only. See [Passing objects safely](#passing-objects-safely).
Transactions created from `perform(asynchronous:...)` are instances of `AsynchronousDataTransaction`.
#### Synchronous transactions
@@ -724,6 +776,21 @@ let hasChanges = CoreStore.perform(
Since `perform(synchronous:...)` technically blocks two queues (the caller's queue and the transaction's background queue), it is considered less safe as it's more prone to deadlock. Take special care that the closure does not block on any other external queues.
By default, `perform(synchronous:...)` will wait for observers such as `ListMonitor`s to be notified before the method returns. This may cause deadlocks, especially if you are calling this from the main thread. To reduce this risk, you may try to set the `waitForAllObservers:` parameter to `false`. Doing so tells the `SynchronousDataTransaction` to block only until it completes saving. It will not wait for other context's to receive those changes. This reduces deadlock risk but may have surprising side-effects:
```swift
CoreStore.perform(
synchronous: { (transaction) in
let person = transaction.create(Into<Person>())
person.name = "John"
},
waitForAllObservers: false
)
let newPerson = CoreStore.fetchOne(From<Person>.where(\.name == "John"))
// newPerson may be nil!
// The DataStack may have not yet received the update notification.
```
Due to this complicated nature of synchronous transactions, if your app has very heavy transaction throughput it is highly recommended to use [asynchronous transactions](#asynchronous-transactions) instead.
#### Unsafe transactions
are special in that they do not enclose updates within a closure:
```swift
@@ -756,8 +823,8 @@ let person = transaction.create(Into<MyPersonEntity>())
While the syntax is straightforward, CoreStore does not just naively insert a new object. This single line does the following:
- Checks that the entity type exists in any of the transaction's parent persistent store
- If the entity belongs to only one persistent store, a new object is inserted into that store and returned from `create(...)`
- If the entity does not belong to any store, an assert will be triggered. **This is a programmer error and should never occur in production code.**
- If the entity belongs to multiple stores, an assert will be triggered. **This is also a programmer error and should never occur in production code.** Normally, with Core Data you can insert an object in this state but saving the `NSManagedObjectContext` will always fail. CoreStore checks this for you at creation time when it makes sense (not during save).
- If the entity does not belong to any store, an assertion failure will be raised. **This is a programmer error and should never occur in production code.**
- If the entity belongs to multiple stores, an assertion failure will be raised. **This is also a programmer error and should never occur in production code.** Normally, with Core Data you can insert an object in this state but saving the `NSManagedObjectContext` will always fail. CoreStore checks this for you at creation time when it makes sense (not during save).
If the entity exists in multiple configurations, you need to provide the configuration name for the destination persistent store:
@@ -786,9 +853,9 @@ To update an existing object, fetch the object's instance from the transaction:
```swift
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let person = transaction.fetchOne(
From<MyPersonEntity>(),
Where("name", isEqualTo: "Jane Smith")
let person = try transaction.fetchOne(
From<MyPersonEntity>()
.where(\.name == "Jane Smith")
)
person.age = person.age + 1
},
@@ -848,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 }
)
@@ -858,9 +925,9 @@ If you do not have references yet to the objects to be deleted, transactions hav
```swift
CoreStore.perform(
asynchronous: { (transaction) -> Void in
transaction.deleteAll(
From<MyPersonEntity>(),
Where("age > 30")
try transaction.deleteAll(
From<MyPersonEntity>()
.where(\.age > 30)
)
},
completion: { _ in }
@@ -906,9 +973,9 @@ var peopleIDs: [NSManagedObjectID] = // ...
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let jane = transaction.fetchOne(
From<MyPersonEntity>(),
Where("name", isEqualTo: "Jane Smith")
let jane = try transaction.fetchOne(
From<MyPersonEntity>()
.where(\.name == "Jane Smith")
)
jane.friends = NSSet(array: transaction.fetchExisting(peopleIDs)!)
// ...
@@ -953,7 +1020,7 @@ typealias ImportSource = [String: Any]
```swift
typealias ImportSource = NSData
```
You can even use external types from popular 3rd-party JSON libraries ([SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON)'s `JSON` type is a personal favorite), or just simple tuples or primitives.
You can even use external types from popular 3rd-party JSON libraries, or just simple tuples or primitives.
#### `ImportableObject`
`ImportableObject` is a very simple protocol:
@@ -1119,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.
@@ -1149,13 +1216,13 @@ 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("%K > %d", "age", 30) // string format initializer
Where<MyPersonEntity>("%K > %d", "age", 30) // string format initializer
)
people = CoreStore.fetchAll(
people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
Where(true) // boolean initializer
Where<MyPersonEntity>(true) // boolean initializer
)
```
If you do have an existing `NSPredicate` instance already, you can pass that to `Where` as well:
@@ -1163,14 +1230,21 @@ If you do have an existing `NSPredicate` instance already, you can pass that to
let predicate = NSPredicate(...)
var people = CoreStore.fetchAll(
From<MyPersonEntity>(),
Where(predicate) // predicate initializer
Where<MyPersonEntity>(predicate) // predicate initializer
)
```
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 = 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(
From<MyPersonEntity>(),
Where("age > %d", 30) && Where("gender == %@", "M")
var people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30 && \.gender == "M")
)
```
If you do not provide a `Where` clause, all objects that belong to the specified `From` will be returned.
@@ -1179,20 +1253,27 @@ 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(.descending("rating"), .ascending("surname"))
OrderBy<MyPersonEntity>(.descending("rating"), .ascending("surname"))
)
```
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 = try CoreStore.fetchAll(
From<MyPersonEntity>()
.orderBy(.descending(\.rating), .ascending(\.surname)) // Type-safe!
)
```
You can use the `+` and `+=` operator to append `OrderBy`s together. This is useful when sorting conditionally:
```swift
var orderBy = OrderBy(.descending("rating"))
var orderBy = OrderBy<MyPersonEntity>(.descending(\.rating))
if sortFromYoungest {
orderBy += OrderBy(.ascending("age"))
orderBy += OrderBy(.ascending(\.age))
}
var mostValuablePeople = CoreStore.fetchAll(
var mostValuablePeople = try CoreStore.fetchAll(
From<MyPersonEntity>(),
orderBy
)
@@ -1202,10 +1283,10 @@ 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("age > %d", 30),
OrderBy(.ascending("surname")),
Where<MyPersonEntity>("age > %d", 30),
OrderBy<MyPersonEntity>(.ascending("surname")),
Tweak { (fetchRequest) -> Void in
fetchRequest.includesPendingChanges = false
fetchRequest.returnsObjectsAsFaults = false
@@ -1213,6 +1294,19 @@ var people = CoreStore.fetchAll(
}
)
```
`Tweak` also supports **Fetch Chain builders**:
```swift
var people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
.where(\.age > 30)
.orderBy(.ascending(\.surname))
.tweak {
$0.includesPendingChanges = false
$0.returnsObjectsAsFaults = false
$0.includesSubentities = false
}
)
```
The clauses are evaluated the order they appear in the fetch/query, so you typically need to set `Tweak` as the last clause.
`Tweak`'s closure is executed only just before the fetch occurs, so make sure that any values captured by the closure is not prone to race conditions.
@@ -1233,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")
@@ -1243,11 +1337,19 @@ 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 = try CoreStore.queryValue(
From<MyPersonEntity>()
.select(\.age) // binds the result to Int
.where(\.name == "John Smith")
)
```
If you only need a value for a particular attribute, you can just specify the key name (like we did with `Select<Int>("age")`), but several aggregate functions can also be used as parameter to `Select`:
- `.average(...)`
@@ -1257,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"))
)
@@ -1265,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")
)
@@ -1285,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"))
)
@@ -1305,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"))
)
@@ -1328,12 +1430,20 @@ 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")
)
```
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 = try CoreStore.queryAttributes(
From<MyPersonEntity>()
.select(.attribute(\.age), .count(\.age, as: "count"))
.groupBy(\.age)
)
```
this returns dictionaries that shows the count for each `"age"`:
```swift
[
@@ -1382,22 +1492,43 @@ 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)
## Observing changes and notifications
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) {
// ...
}
func objectMonitor(monitor: ObjectMonitor<MyPersonEntity>, didUpdateObject object: MyPersonEntity, changedPersistentKeys: Set<KeyPath>) {
func objectMonitor(monitor: ObjectMonitor<MyPersonEntity>, didUpdateObject object: MyPersonEntity, changedPersistentKeys: Set<KeyPathString>) {
// ...
}
@@ -1457,12 +1588,10 @@ Including `ListObserver`, there are 3 observer protocols you can implement depen
We then need to create a `ListMonitor` instance and register our `ListObserver` as an observer:
```swift
self.monitor = CoreStore.monitorList(
From<MyPersonEntity>(),
Where("age > 30"),
OrderBy(.ascending("name")),
Tweak { (fetchRequest) -> Void in
fetchRequest.fetchBatchSize = 20
}
From<MyPersonEntity>()
.where(\.age > 30)
.orderBy(.ascending(\.name))
.tweak { $0.fetchBatchSize = 20 }
)
self.monitor.addObserver(self)
```
@@ -1478,13 +1607,11 @@ let firstPerson = self.monitor[0]
If the list needs to be grouped into sections, create the `ListMonitor` instance with the `monitorSectionedList(...)` method and a `SectionBy` clause:
```swift
self.monitor = CoreStore.monitorSectionedList(
From<MyPersonEntity>(),
SectionBy("age"),
Where("gender", isEqualTo: "M"),
OrderBy(.ascending("age"), .ascending("name")),
Tweak { (fetchRequest) -> Void in
fetchRequest.fetchBatchSize = 20
}
From<MyPersonEntity>()
.sectionBy(\.age)
.where(\.gender == "M")
.orderBy(.ascending(\.age), .ascending(\.name))
.tweak { $0.fetchBatchSize = 20 }
)
```
A list controller created this way will group the objects by the attribute key indicated by the `SectionBy` clause. One more thing to remember is that the `OrderBy` clause should sort the list in such a way that the `SectionBy` attribute would be sorted together (a requirement shared by `NSFetchedResultsController`.)
@@ -1492,11 +1619,11 @@ A list controller created this way will group the objects by the attribute key i
The `SectionBy` clause can also be passed a closure to transform the section name into a displayable string:
```swift
self.monitor = CoreStore.monitorSectionedList(
From<MyPersonEntity>(),
SectionBy("age") { (sectionName) -> String? in
"\(sectionName) years old"
},
OrderBy(.ascending("age"), .ascending("name"))
From<MyPersonEntity>()
.sectionBy(\.age) { (sectionName) -> String? in
"\(sectionName) years old"
}
.orderBy(.ascending(\.age), .ascending(\.name))
)
```
This is useful when implementing a `UITableViewDelegate`'s section header:
@@ -1516,9 +1643,9 @@ let person2 = self.monitor[1, 2]
```
## Objective-C support
CoreStore 2.0 was a big move to address the large number of apps starting to convert from Objective-C to Swift. The basic problem is this: The cost of converting all code base to Swift is very big, so most apps are forced to do undergo a *transitional* ObjC-Swift hybrid phase. This used to mean that these apps could not use the Swifty-est libraries out there yet, or that they may have to write their own bridging methods just to make new code usable in their old Objective-C code.
> Objective-C support is planned to be deprecated in a future CoreStore version.
With 2.0, all CoreStore types are still written in pure Swift, but they now have Objective-C "bridging classes" that are visible to Objective-C code. To show a couple of usage examples:
All CoreStore types are still written in pure Swift, but most core types have Objective-C "bridging classes" that are visible to Objective-C code. To show a couple of usage examples:
<table>
<tr><th>Swift</th><th>Objective-C</th></tr>
@@ -1566,7 +1693,7 @@ All of these `CS`-prefixed bridging classes have very similar usage to the exist
For example, you may have a new, modern Swift class that holds a `ListMonitor`:
```swift
class MyViewController: UIViewController {
let monitor = CoreStore.monitorList(From(MyEntity), ...)
let monitor = CoreStore.monitorList(From<MyEntity>(), ...)
// ...
}
```
@@ -1580,7 +1707,7 @@ Now let's say you have a legacy Objective-C class that previously uses `NSFetche
When you need to instantiate this class from Swift, you just call `bridgeToObjectiveC`:
```swift
class MyViewController: UIViewController {
let monitor = CoreStore.monitorList(From(MyEntity), ...)
let monitor = CoreStore.monitorList(From<MyEntity>(), ...)
func showOldController() {
let controller = MYOldViewController(monitor: self.monitor.bridgeToObjectiveC)
self.presentViewController(controller, animated: true, completion: nil)
@@ -1625,7 +1752,7 @@ To use these syntax sugars, include *CoreStoreBridge.h* in your Objective-C sour
Starting CoreStore 4.0, we can now create persisted objects without depending on *.xcdatamodeld* Core Data files. The new `CoreStoreObject` subclass replaces `NSManagedObject`, and specially-typed properties declared on these classes will be synthesized as Core Data attributes.
```swift
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
}
class Dog: Animal {
@@ -1634,22 +1761,22 @@ class Dog: Animal {
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
The property names to be saved to Core Data is specified as the `keyPath` argument. This lets us refactor our Swift code without affecting the underlying database. For example:
```swift
class Person: CoreStoreObject {
private let _name = Value.Required<String>("name")
// ...
private let _name = Value.Required<String>("name", initial: "")
// note property name is independent of the storage key name
}
```
Here we added an underscore to the property name and made it `private`, but the underlying key-path `"name"` was unchanged so our model will not trigger a data migration.
> **Important:** As a rule, CoreStore can only process *stored properties*. Computed, `static`, `weak`, or `lazy` properties will not be added to the store. It is also strictly advised use `let` instead of `var` to declare these properties, as any changes to the schema after declaration is not allowed.
> ⚠️**Important:** As a rule, CoreStore can only process *stored properties*. Computed, `static`, `weak`, or `lazy` properties will be ignored and will not be added to the store. It is also strictly advised use `let` instead of `var` to declare these properties, as any changes to the property value will break the schema.
Also note how `Relationship`s are linked statically with the `inverse:` argument. All relationships are required to have an "inverse" relationship. Unfortunately, due to Swift compiler limitation we can only declare the `inverse:` on one end of the relationship-pair.
Also note how `Relationship`s are linked statically with the `inverse:` argument. **All relationships are required to have an "inverse" relationship**. Unfortunately, due to Swift compiler limitation we can only declare the `inverse:` on one end of the relationship-pair.
To tell the `DataStack` about these types, add all `CoreStoreObject`s' entities to a `CoreStoreSchema`:
```swift
@@ -1672,7 +1799,7 @@ These special properties' values can be accessed or mutated using `.value`:
```swift
CoreStore.perform(
asynchronous: { (transaction) in
let dog: Dog = CoreStore.fetchOne(From<Dog>())!
let dog: Dog = transaction.fetchOne(From<Dog>())!
// ...
let nickname = dog.nickname.value // String?
let species = dog.species.value // String
@@ -1690,10 +1817,10 @@ let keyPath: String = Dog.keyPath { $0.nickname }
```
as well as `Where` and `OrderBy` clauses
```swift
let puppies = CoreStore.fetchAll(
From<Dog>(),
Dog.where { $0.age < 1 },
Dog.ascending { $0.age }
let puppies = try CoreStore.fetchAll(
From<Dog>()
.where(\.age < 1)
.orderBy(.ascending(\.age))
)
```
@@ -1703,7 +1830,7 @@ All CoreStore APIs that are usable with `NSManagedObject`s are also available fo
While it is convenient to be able to declare entities only in code, it is worrying that we might accidentally change the `CoreStoreObject`'s properties and break our users' model version history. For this, the `CoreStoreSchema` allows us to "lock" our properties to a particular configuration. Any changes to that `VersionLock` will raise an assertion failure during the `CoreStoreSchema` initialization, so you can then look for the commit which changed the `VersionLock` hash.
To use `VersionLock`s, create the `CoreStoreSchema`, run the app, and look for this particular log message that is automatically printed to the console:
To use `VersionLock`s, create the `CoreStoreSchema`, run the app, and look for a similar log message that is automatically printed to the console:
<img width="700" alt="VersionLock" src="https://cloud.githubusercontent.com/assets/3029684/26525632/757f1bd0-4398-11e7-9795-4132a2df0538.png" />
@@ -1735,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 3.1 (Xcode 8.3.2+)
- iOS 10 SDK and above
- Swift 4.2 (Xcode 10+)
- Dependencies:
- *None*
- Other notes:
@@ -1745,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', '~> 4.0'
pod 'CoreStore', '~> 6.1'
```
and run
```
@@ -1756,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" >= 4.0.0
github "JohnEstropia/CoreStore" >= 6.2.0
```
and run
```
@@ -1764,48 +1891,32 @@ 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.0"))
]
```
Declare `import CoreStore` in your swift file to use the library.
### Install as Git Submodule
```
git submodule add https://github.com/JohnEstropia/CoreStore.git <destination directory>
```
Drag and drop **CoreStore.xcodeproj** to your project.
#### To install as a framework:
Drag and drop **CoreStore.xcodeproj** to your project.
#### To include directly in your app module:
Add all *.swift* files to your project.
### Objective-C support
To use the Objective-C syntax sugars, import *CoreStoreBridge.h* in your *.m* source files.
# Changesets
### Upgrading from 3.x.x to 4.x.x
**Obsoleted**
- `LegacySQLiteStore` is now finally obsoleted in favor of `SQLiteStore`. For sqlite files that were created previously with `LegacySQLiteStore`, make sure to use the `SQLiteStore.legacy(...)` factory method to create an `SQLiteStore` that can load the file from the legacy file path.
- `SQLiteStore.init(...)`'s `mappingModelBundles` argument is now obsolete. The new initializer accepts a `migrationMappingProviders` optional argument where explicit mapping sources are declared. For reference on how to do this, read on [Custom migrations](#custom-migrations).
**Deprecated**
- `DataStack.beginAsynchronous(...)`, `DataStack.beginSynchronous(...)`, `AsynchronousDataTransaction.commit(...)`, and `SynchronousDataTransaction.commit(...)` are now deprecated in favor of `DataStack.perform(asynchronous:...)` and `DataStack.perform(synchronous:...)` family of methods. These new `perform(...)` methods are auto-commit, meaning the transaction automatically calls `commit()` internally after the transction closure completes. To roll-back and cancel a transaction, call `try transaction.cancel()`. Read [Saving and processing transactions](#saving-and-processing-transactions) for more details.
**Other Changes**
- `ListMonitor.refetch(...)` now works by recreating its internal `NSFetchedResultsController`. Previously `refetch(...)` would only apply new `FetchClause`s on top of previous fetches. Now all `FetchClauses` are required to be passed to `refetch(...)` each time it is called.
- New important concepts on "Dynamic Models", "Schema", and "Schema Histories".
- **Dynamic Models** (`DynamicObject` protocol): These are Core Data object types that any `NSManagedObject` or `CoreStoreObject`s conform to. *(See [Type-safe `CoreStoreObject`s](#type-safe-corestoreobjects))*
- **Version Schema** (`DynamicSchema` protocol): These types contain info for a single model version, as well as entities that belong to it. Currently supports `XcodeDataModelSchema` (*.xcdatamodeld* file), `CoreStoreSchema`, or `UnsafeDataModelSchema`. *(See [Migrations](#migrations))*
- **Schema History** (`SchemaHistory` class): This is now the preferred way to express all models to the `DataStack`. This class contains info to all the `DynamicSchema` across multiple model versions. *(See [Migrations](#migrations))*
### Other Releases
For the full Changelog, refer to the [Releases](https://github.com/JohnEstropia/CoreStore/releases) page.
# Contact
Questions? Suggestions?
Reach me on Twitter [@JohnEstropia](https://twitter.com/JohnEstropia)
You can reach me on Twitter [@JohnEstropia](https://twitter.com/JohnEstropia)
or join our Slack team at [swift-corestore.slack.com](http://swift-corestore-slack.herokuapp.com/)

View File

@@ -2,7 +2,7 @@
// AsynchronousDataTransaction.swift
// CoreStore
//
// Copyright © 2015 John Rommel Estropia
// 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
@@ -100,7 +100,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
*/
public override func create<T: DynamicObject>(_ into: Into<T>) -> T {
public override func create<D>(_ into: Into<D>) -> D {
CoreStore.assert(
!self.isCommitted,
@@ -116,7 +116,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be edited
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
*/
public override func edit<T: DynamicObject>(_ object: T?) -> T? {
public override func edit<D: DynamicObject>(_ object: D?) -> D? {
CoreStore.assert(
!self.isCommitted,
@@ -133,7 +133,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
- parameter objectID: the `NSManagedObjectID` for the object to be edited
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
*/
public override func edit<T: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
public override func edit<D>(_ into: Into<D>, _ objectID: NSManagedObjectID) -> D? {
CoreStore.assert(
!self.isCommitted,
@@ -148,7 +148,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be deleted
*/
public override func delete<T: DynamicObject>(_ object: T?) {
public override func delete<D: DynamicObject>(_ object: D?) {
CoreStore.assert(
!self.isCommitted,
@@ -165,14 +165,14 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
- parameter object2: another `DynamicObject` to be deleted
- parameter objects: other `DynamicObject`s to be deleted
*/
public override func delete<T: DynamicObject>(_ object1: T?, _ object2: T?, _ objects: T?...) {
public override func delete<D: DynamicObject>(_ object1: D?, _ object2: D?, _ objects: D?...) {
CoreStore.assert(
!self.isCommitted,
"Attempted to delete an entities from an already committed \(cs_typeName(self))."
)
super.delete(([object1, object2] + objects).flatMap { $0 })
super.delete(([object1, object2] + objects).compactMap { $0 })
}
/**
@@ -203,13 +203,14 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
self.isCommitted = true
let group = DispatchGroup()
group.enter()
self.context.saveAsynchronouslyWithCompletion { (result) -> Void in
self.context.saveAsynchronouslyWithCompletion { (hasChanges, error) -> Void in
completion(result.0, result.1)
self.result = result
completion(hasChanges, error)
self.result = (hasChanges, error)
group.leave()
}
group.wait()
self.context.reset()
}
@@ -226,12 +227,15 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
!self.isCommitted,
"Attempted to commit a \(cs_typeName(self)) more than once."
)
self.autoCommit { (result) in
self.autoCommit { (hasChanges, error) in
switch result {
if let error = error {
case (let hasChanges, nil): completion(SaveResult(hasChanges: hasChanges))
case (_, let error?): completion(SaveResult(error))
completion(SaveResult(error))
}
else {
completion(SaveResult(hasChanges: hasChanges))
}
}
}
@@ -266,9 +270,9 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
}
switch childTransaction.result {
case nil: return nil
case (let hasChanges, nil)?: return SaveResult(hasChanges: hasChanges)
case (_, let error?)?: return SaveResult(error)
case .none: return nil
case .some(let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
case .some(_, let error?): return SaveResult(error)
}
}
}

View File

@@ -0,0 +1,47 @@
//
// AttributeProtocol.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: - AttributeProtocol
internal protocol AttributeProtocol: class {
static var attributeType: NSAttributeType { get }
var keyPath: KeyPathString { get }
var isOptional: Bool { get }
var isTransient: Bool { get }
var allowsExternalBinaryDataStorage: Bool { get }
var versionHashModifier: () -> String? { get }
var renamingIdentifier: () -> String? { get }
var defaultValue: () -> Any? { get }
var affectedByKeyPaths: () -> Set<String> { get }
var rawObject: CoreStoreManagedObject? { get set }
var getter: CoreStoreManagedObject.CustomGetter? { get }
var setter: CoreStoreManagedObject.CustomSetter? { get }
}

View File

@@ -2,7 +2,7 @@
// BaseDataTransaction+Importing.swift
// CoreStore
//
// Copyright © 2015 John Rommel Estropia
// 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
@@ -29,7 +29,7 @@ import CoreData
// MARK: - BaseDataTransaction
public extension BaseDataTransaction {
extension BaseDataTransaction {
/**
Creates an `ImportableObject` by importing from the specified import source.
@@ -39,9 +39,9 @@ public extension BaseDataTransaction {
- throws: an `Error` thrown from any of the `ImportableObject` methods
- returns: the created `ImportableObject` instance, or `nil` if the import was ignored
*/
public func importObject<T: DynamicObject & ImportableObject>(
_ into: Into<T>,
source: T.ImportSource) throws -> T? {
public func importObject<D: ImportableObject>(
_ into: Into<D>,
source: D.ImportSource) throws -> D? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -69,9 +69,9 @@ public extension BaseDataTransaction {
- parameter source: the object to import values from
- throws: an `Error` thrown from any of the `ImportableObject` methods
*/
public func importObject<T: DynamicObject & ImportableObject>(
_ object: T,
source: T.ImportSource) throws {
public func importObject<D: ImportableObject>(
_ object: D,
source: D.ImportSource) throws {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -80,7 +80,7 @@ public extension BaseDataTransaction {
try autoreleasepool {
let entityType = type(of: object)
let entityType = cs_dynamicType(of: object)
guard entityType.shouldInsert(from: source, in: self) else {
return
@@ -97,9 +97,9 @@ public extension BaseDataTransaction {
- throws: an `Error` thrown from any of the `ImportableObject` methods
- returns: the array of created `ImportableObject` instances
*/
public func importObjects<T: DynamicObject & ImportableObject, S: Sequence>(
_ into: Into<T>,
sourceArray: S) throws -> [T] where S.Iterator.Element == T.ImportSource {
public func importObjects<D: ImportableObject, S: Sequence>(
_ into: Into<D>,
sourceArray: S) throws -> [D] where S.Iterator.Element == D.ImportSource {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -108,7 +108,7 @@ public extension BaseDataTransaction {
return try autoreleasepool {
return try sourceArray.flatMap { (source) -> T? in
return try sourceArray.compactMap { (source) -> D? in
let entityType = into.entityClass
guard entityType.shouldInsert(from: source, in: self) else {
@@ -133,9 +133,9 @@ public extension BaseDataTransaction {
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
- returns: the created/updated `ImportableUniqueObject` instance, or `nil` if the import was ignored
*/
public func importUniqueObject<T: DynamicObject & ImportableUniqueObject>(
_ into: Into<T>,
source: T.ImportSource) throws -> T? {
public func importUniqueObject<D: ImportableUniqueObject>(
_ into: Into<D>,
source: D.ImportSource) throws -> D? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -151,7 +151,7 @@ public extension BaseDataTransaction {
return nil
}
if let object = self.fetchOne(From(entityType), Where(uniqueIDKeyPath, isEqualTo: uniqueIDValue)) {
if let object = try self.fetchOne(From(entityType), Where<D>(uniqueIDKeyPath, isEqualTo: uniqueIDValue)) {
guard entityType.shouldUpdate(from: source, in: self) else {
@@ -185,10 +185,10 @@ public extension BaseDataTransaction {
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
- returns: the array of created/updated `ImportableUniqueObject` instances
*/
public func importUniqueObjects<T: DynamicObject & ImportableUniqueObject, S: Sequence>(
_ into: Into<T>,
public func importUniqueObjects<D: ImportableUniqueObject, S: Sequence>(
_ into: Into<D>,
sourceArray: S,
preProcess: @escaping (_ mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws -> [T] where S.Iterator.Element == T.ImportSource {
preProcess: @escaping (_ mapping: [D.UniqueIDType: D.ImportSource]) throws -> [D.UniqueIDType: D.ImportSource] = { $0 }) throws -> [D] where S.Iterator.Element == D.ImportSource {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -198,10 +198,10 @@ public extension BaseDataTransaction {
return try autoreleasepool {
let entityType = into.entityClass
var importSourceByID = Dictionary<T.UniqueIDType, T.ImportSource>()
var importSourceByID = Dictionary<D.UniqueIDType, D.ImportSource>()
let sortedIDs = try autoreleasepool {
return try sourceArray.flatMap { (source) -> T.UniqueIDType? in
return try sourceArray.compactMap { (source) -> D.UniqueIDType? in
guard let uniqueIDValue = try entityType.uniqueID(from: source, in: self) else {
@@ -214,12 +214,13 @@ public extension BaseDataTransaction {
importSourceByID = try autoreleasepool { try preProcess(importSourceByID) }
var existingObjectsByID = Dictionary<T.UniqueIDType, T>()
self.fetchAll(From(entityType), Where(entityType.uniqueIDKeyPath, isMemberOf: sortedIDs))?
var existingObjectsByID = Dictionary<D.UniqueIDType, D>()
try self
.fetchAll(From(entityType), Where<D>(entityType.uniqueIDKeyPath, isMemberOf: sortedIDs))
.forEach { existingObjectsByID[$0.uniqueIDValue] = $0 }
var processedObjectIDs = Set<T.UniqueIDType>()
var result = [T]()
var processedObjectIDs = Set<D.UniqueIDType>()
var result = [D]()
for objectID in sortedIDs where !processedObjectIDs.contains(objectID) {

View File

@@ -2,7 +2,7 @@
// BaseDataTransaction+Querying.swift
// CoreStore
//
// Copyright © 2015 John Rommel Estropia
// 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
@@ -39,14 +39,13 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- returns: the number of `DynamicObject`s deleted
*/
@discardableResult
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ 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)
}
/**
@@ -57,14 +56,32 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- returns: the number of `DynamicObject`s deleted
*/
@discardableResult
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ 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 try self.context.deleteAll(from, deleteClauses)
}
/**
Deletes all `DynamicObject`s that satisfy the specified conditions.
```
transaction.deleteAll(From<Person>().where(\.age > 50))
```
- parameter clauseChain: a `FetchChainableBuilderType` clause chain created from a `From` clause
- returns: the number of `DynamicObject`s deleted
*/
@discardableResult
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(from, deleteClauses)
return try self.context.deleteAll(clauseChain.from, clauseChain.fetchClauses)
}
@@ -76,7 +93,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter object: a reference to the object created/fetched outside the transaction
- returns: the `DynamicObject` instance if the object exists in the transaction, or `nil` if not found.
*/
public func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
public func fetchExisting<D: DynamicObject>(_ object: D) -> D? {
return self.context.fetchExisting(object)
}
@@ -87,7 +104,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter objectID: the `NSManagedObjectID` for the object
- returns: the `DynamicObject` instance if the object exists in the transaction, or `nil` if not found.
*/
public func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
public func fetchExisting<D: DynamicObject>(_ objectID: NSManagedObjectID) -> D? {
return self.context.fetchExisting(objectID)
}
@@ -98,7 +115,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter objects: an array of `DynamicObject`s created/fetched outside the transaction
- returns: the `DynamicObject` array for objects that exists in the transaction
*/
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
public func fetchExisting<D: DynamicObject, S: Sequence>(_ objects: S) -> [D] where S.Iterator.Element == D {
return self.context.fetchExisting(objects)
}
@@ -109,7 +126,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
- parameter objectIDs: the `NSManagedObjectID` array for the objects
- returns: the `DynamicObject` array for objects that exists in the transaction
*/
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
public func fetchExisting<D: DynamicObject, S: Sequence>(_ objectIDs: S) -> [D] where S.Iterator.Element == NSManagedObjectID {
return self.context.fetchExisting(objectIDs)
}
@@ -119,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<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
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)
}
/**
@@ -135,15 +153,38 @@ 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<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
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)
}
/**
Fetches the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
```
let youngestTeen = transaction.fetchOne(
From<MyPersonEntity>()
.where(\.age > 18)
.orderBy(.ascending(\.age))
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- 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) throws -> B.ObjectType? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return try self.context.fetchOne(clauseChain)
}
/**
@@ -151,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<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
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)
}
/**
@@ -167,15 +209,38 @@ 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<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
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)
}
/**
Fetches all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
```
let people = transaction.fetchAll(
From<MyPersonEntity>()
.where(\.age > 18)
.orderBy(.ascending(\.age))
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- 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) throws -> [B.ObjectType] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return try self.context.fetchAll(clauseChain)
}
/**
@@ -183,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<T: DynamicObject>(_ from: From<T>, _ 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)
}
/**
@@ -199,15 +265,38 @@ 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<T: DynamicObject>(_ from: From<T>, _ 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)
}
/**
Fetches the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
```
let numberOfAdults = transaction.fetchCount(
From<MyPersonEntity>()
.where(\.age > 18)
.orderBy(.ascending(\.age))
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- 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) throws -> Int {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return try self.context.fetchCount(clauseChain)
}
/**
@@ -215,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<T: DynamicObject>(_ from: From<T>, _ 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)
}
/**
@@ -231,15 +321,38 @@ 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<T: DynamicObject>(_ from: From<T>, _ 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)
}
/**
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
```
let youngestTeenID = transaction.fetchObjectID(
From<MyPersonEntity>()
.where(\.age > 18)
.orderBy(.ascending(\.age))
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- 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) throws -> NSManagedObjectID? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return try self.context.fetchObjectID(clauseChain)
}
/**
@@ -247,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<T: DynamicObject>(_ from: From<T>, _ 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)
}
/**
@@ -263,15 +377,38 @@ 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<T: DynamicObject>(_ from: From<T>, _ 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)
}
/**
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
```
let idsOfAdults = transaction.fetchObjectIDs(
From<MyPersonEntity>()
.where(\.age > 18)
.orderBy(.ascending(\.age))
)
```
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
- 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) throws -> [NSManagedObjectID] {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return try self.context.fetchObjectIDs(clauseChain)
}
@@ -285,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<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<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)
}
/**
@@ -304,15 +442,40 @@ 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<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<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)
}
/**
Queries a property value or aggregate as specified by the `QueryChainableBuilderType` built from a chain of 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.
```
let averageAdultAge = transaction.queryValue(
From<MyPersonEntity>()
.select(Int.self, .average(\.age))
.where(\.age > 18)
)
```
- 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`, 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) throws -> B.ResultType? where B.ResultType: QueryableAttributeType {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return try self.context.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
/**
@@ -324,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<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<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)
}
/**
@@ -343,14 +507,48 @@ 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<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<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)
}
/**
Queries a dictionary of attribute values or as specified by the `QueryChainableBuilderType` built from a chain of 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.
```
let results = dataStack.queryAttributes(
From<MyPersonEntity>()
.select(
NSDictionary.self,
.attribute(\.age, as: "age"),
.count(\.age, as: "numberOfPeople")
)
.groupBy(\.age)
)
for dictionary in results! {
let age = dictionary["age"] as! Int
let count = dictionary["numberOfPeople"] as! Int
print("There are \(count) people who are \(age) years old."
}
```
- 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) throws -> [[String: Any]] where B.ResultType == NSDictionary {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return try self.context.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
@@ -367,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

@@ -2,7 +2,7 @@
// BaseDataTransaction.swift
// CoreStore
//
// Copyright © 2014 John Rommel Estropia
// 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
@@ -50,7 +50,7 @@ public /*abstract*/ class BaseDataTransaction {
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
*/
public func create<T: DynamicObject>(_ into: Into<T>) -> T {
public func create<D>(_ into: Into<D>) -> D {
let entityClass = into.entityClass
CoreStore.assert(
@@ -116,12 +116,12 @@ public /*abstract*/ class BaseDataTransaction {
}
/**
Returns an editable proxy of a specified `NSManagedObject`.
Returns an editable proxy of a specified `NSManagedObject` or `CoreStoreObject`.
- parameter object: the `NSManagedObject` type to be edited
- returns: an editable proxy for the specified `NSManagedObject`.
- parameter object: the `NSManagedObject` or `CoreStoreObject` type to be edited
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
*/
public func edit<T: DynamicObject>(_ object: T?) -> T? {
public func edit<D: DynamicObject>(_ object: D?) -> D? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -139,9 +139,9 @@ public /*abstract*/ class BaseDataTransaction {
- parameter into: an `Into` clause specifying the entity type
- parameter objectID: the `NSManagedObjectID` for the object to be edited
- returns: an editable proxy for the specified `NSManagedObject`.
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
*/
public func edit<T: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
public func edit<D>(_ into: Into<D>, _ objectID: NSManagedObjectID) -> D? {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -156,11 +156,11 @@ public /*abstract*/ class BaseDataTransaction {
}
/**
Deletes a specified `NSManagedObject`.
Deletes a specified `NSManagedObject` or `CoreStoreObject`.
- parameter object: the `NSManagedObject` to be deleted
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be deleted
*/
public func delete<T: DynamicObject>(_ object: T?) {
public func delete<D: DynamicObject>(_ object: D?) {
CoreStore.assert(
self.isRunningInAllowedQueue(),
@@ -173,21 +173,21 @@ public /*abstract*/ class BaseDataTransaction {
}
/**
Deletes the specified `NSManagedObject`s.
Deletes the specified `NSManagedObject`s or `CoreStoreObject`s.
- parameter object1: the `NSManagedObject` to be deleted
- parameter object2: another `NSManagedObject` to be deleted
- parameter objects: other `NSManagedObject`s to be deleted
- parameter object1: the `NSManagedObject` or `CoreStoreObject` to be deleted
- parameter object2: another `NSManagedObject` or `CoreStoreObject` to be deleted
- parameter objects: other `NSManagedObject`s or `CoreStoreObject`s to be deleted
*/
public func delete<T: DynamicObject>(_ object1: T?, _ object2: T?, _ objects: T?...) {
public func delete<D: DynamicObject>(_ object1: D?, _ object2: D?, _ objects: D?...) {
self.delete(([object1, object2] + objects).flatMap { $0 })
self.delete(([object1, object2] + objects).compactMap { $0 })
}
/**
Deletes the specified `NSManagedObject`s.
Deletes the specified `NSManagedObject`s or `CoreStoreObject`s.
- parameter objects: the `NSManagedObject`s to be deleted
- parameter objects: the `NSManagedObject`s or `CoreStoreObject`s to be deleted
*/
public func delete<S: Sequence>(_ objects: S) where S.Iterator.Element: DynamicObject {
@@ -220,17 +220,17 @@ public /*abstract*/ class BaseDataTransaction {
- parameter entity: the `DynamicObject` subclass to filter
- returns: a `Set` of pending `DynamicObject`s of the specified type that were inserted to the transaction.
*/
public func insertedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
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(
!self.isCommitted,
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
)
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
return Set(self.context.insertedObjects.compactMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
}
/**
@@ -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(
@@ -257,17 +257,17 @@ public /*abstract*/ class BaseDataTransaction {
- parameter entity: the `DynamicObject` subclass to filter
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were inserted to the transaction.
*/
public func insertedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
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(
!self.isCommitted,
"Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))."
)
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
return Set(self.context.insertedObjects.compactMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
}
/**
@@ -276,17 +276,17 @@ public /*abstract*/ class BaseDataTransaction {
- parameter entity: the `DynamicObject` subclass to filter
- returns: a `Set` of pending `DynamicObject`s of the specified type that were updated in the transaction.
*/
public func updatedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
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(
!self.isCommitted,
"Attempted to access updated objects from an already committed \(cs_typeName(self))."
)
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
return Set(self.context.updatedObjects.compactMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
}
/**
@@ -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(
@@ -313,17 +313,17 @@ public /*abstract*/ class BaseDataTransaction {
- parameter entity: the `DynamicObject` subclass to filter
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were updated in the transaction.
*/
public func updatedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
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(
!self.isCommitted,
"Attempted to access updated object IDs from an already committed \(cs_typeName(self))."
)
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
return Set(self.context.updatedObjects.compactMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
}
/**
@@ -332,17 +332,17 @@ public /*abstract*/ class BaseDataTransaction {
- parameter entity: the `DynamicObject` subclass to filter
- returns: a `Set` of pending `DynamicObject`s of the specified type that were deleted from the transaction.
*/
public func deletedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
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(
!self.isCommitted,
"Attempted to access deleted objects from an already committed \(cs_typeName(self))."
)
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
return Set(self.context.deletedObjects.compactMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
}
/**
@@ -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(
@@ -370,17 +370,17 @@ public /*abstract*/ class BaseDataTransaction {
- parameter entity: the `DynamicObject` subclass to filter
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
*/
public func deletedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
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(
!self.isCommitted,
"Attempted to access deleted object IDs from an already committed \(cs_typeName(self))."
)
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
return Set(self.context.deletedObjects.compactMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
}
@@ -438,6 +438,11 @@ public /*abstract*/ class BaseDataTransaction {
return self.bypassesQueueing || self.transactionQueue.cs_isCurrentExecutionContext()
}
deinit {
self.context.reset()
}
// MARK: Deprecated

View File

@@ -2,7 +2,7 @@
// CSAsynchronousDataTransaction.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -35,7 +35,7 @@ import CoreData
- SeeAlso: `AsynchronousDataTransaction`
*/
@objc
public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
public final class CSAsynchronousDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType {
/**
Saves the transaction changes. This method should not be used after the `-commitWithCompletion:` method was already called once.
@@ -54,12 +54,15 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
!self.bridgeToSwift.isCommitted,
"Attempted to commit a \(cs_typeName(self)) more than once."
)
self.bridgeToSwift.autoCommit { (result) in
self.bridgeToSwift.autoCommit { (_, error) in
switch result {
if let error = error {
case (_, nil): success?()
case (_, let error?): failure?(error.bridgeToObjectiveC)
failure?(error.bridgeToObjectiveC)
}
else {
success?()
}
}
}
@@ -139,9 +142,9 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
public typealias SwiftType = AsynchronousDataTransaction
public override var bridgeToSwift: AsynchronousDataTransaction {
public var bridgeToSwift: AsynchronousDataTransaction {
return super.bridgeToSwift as! AsynchronousDataTransaction
return super.swiftTransaction as! AsynchronousDataTransaction
}
public required init(_ swiftValue: AsynchronousDataTransaction) {
@@ -149,9 +152,9 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
super.init(swiftValue as BaseDataTransaction)
}
public required init(_ swiftValue: BaseDataTransaction) {
public required override init(_ swiftValue: BaseDataTransaction) {
super.init(swiftValue as! AsynchronousDataTransaction)
super.init(swiftValue)
}

View File

@@ -2,7 +2,7 @@
// CSBaseDataTransaction+Querying.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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.
@@ -40,7 +40,7 @@ public extension CSBaseDataTransaction {
@objc
public func fetchExistingObject(_ object: NSManagedObject) -> Any? {
return self.bridgeToSwift.context.fetchExisting(object) as NSManagedObject?
return self.swiftTransaction.context.fetchExisting(object) as NSManagedObject?
}
/**
@@ -52,7 +52,7 @@ public extension CSBaseDataTransaction {
@objc
public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? {
return self.bridgeToSwift.context.fetchExisting(objectID) as NSManagedObject?
return self.swiftTransaction.context.fetchExisting(objectID) as NSManagedObject?
}
/**
@@ -64,7 +64,7 @@ public extension CSBaseDataTransaction {
@objc
public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] {
return self.bridgeToSwift.context.fetchExisting(objects) as [NSManagedObject]
return self.swiftTransaction.context.fetchExisting(objects) as [NSManagedObject]
}
/**
@@ -76,7 +76,7 @@ public extension CSBaseDataTransaction {
@objc
public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] {
return self.bridgeToSwift.context.fetchExisting(objectIDs) as [NSManagedObject]
return self.swiftTransaction.context.fetchExisting(objectIDs) as [NSManagedObject]
}
/**
@@ -90,10 +90,11 @@ public extension CSBaseDataTransaction {
public func fetchOneFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> Any? {
CoreStore.assert(
self.bridgeToSwift.isRunningInAllowedQueue(),
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.bridgeToSwift.context.fetchOne(from, fetchClauses)
return (try? self.swiftTransaction.context.fetchOne(from, fetchClauses))?
.flatMap({ $0 })
}
/**
@@ -107,10 +108,11 @@ public extension CSBaseDataTransaction {
public func fetchAllFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> [Any]? {
CoreStore.assert(
self.bridgeToSwift.isRunningInAllowedQueue(),
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.bridgeToSwift.context.fetchAll(from, fetchClauses)
return (try? self.swiftTransaction.context.fetchAll(from, fetchClauses))
.flatMap({ $0 })
}
/**
@@ -124,12 +126,11 @@ public extension CSBaseDataTransaction {
public func fetchCountFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSNumber? {
CoreStore.assert(
self.bridgeToSwift.isRunningInAllowedQueue(),
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.bridgeToSwift.context
.fetchCount(from, fetchClauses)
.flatMap { NSNumber(value: $0) }
return (try? self.swiftTransaction.context.fetchCount(from, fetchClauses))
.flatMap({ NSNumber(value: $0) })
}
/**
@@ -143,10 +144,11 @@ public extension CSBaseDataTransaction {
public func fetchObjectIDFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSManagedObjectID? {
CoreStore.assert(
self.bridgeToSwift.isRunningInAllowedQueue(),
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
)
return self.bridgeToSwift.context.fetchObjectID(from, fetchClauses)
return (try? self.swiftTransaction.context.fetchObjectID(from, fetchClauses))
.flatMap({ $0 })
}
/**
@@ -163,10 +165,11 @@ public extension CSBaseDataTransaction {
public func queryValueFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> Any? {
CoreStore.assert(
self.bridgeToSwift.isRunningInAllowedQueue(),
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.bridgeToSwift.context.queryValue(from, selectClause, queryClauses)
return (try? self.swiftTransaction.context.queryValue(from, selectClause, queryClauses))
.flatMap({ $0 })
}
/**
@@ -183,9 +186,10 @@ public extension CSBaseDataTransaction {
public func queryAttributesFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> [[String: Any]]? {
CoreStore.assert(
self.bridgeToSwift.isRunningInAllowedQueue(),
self.swiftTransaction.isRunningInAllowedQueue(),
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
)
return self.bridgeToSwift.context.queryAttributes(from, selectClause, queryClauses)
return (try? self.swiftTransaction.context.queryAttributes(from, selectClause, queryClauses))
.flatMap({ $0 })
}
}

View File

@@ -2,7 +2,7 @@
// CSBaseDataTransaction.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -35,7 +35,7 @@ import CoreData
- SeeAlso: `BaseDataTransaction`
*/
@objc
public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
public class CSBaseDataTransaction: NSObject {
// MARK: Object management
@@ -45,7 +45,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public var hasChanges: Bool {
return self.bridgeToSwift.hasChanges
return self.swiftTransaction.hasChanges
}
/**
@@ -57,7 +57,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func createInto(_ into: CSInto) -> Any {
return self.bridgeToSwift.create(into.bridgeToSwift)
return self.swiftTransaction.create(into.bridgeToSwift)
}
/**
@@ -69,7 +69,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func editObject(_ object: NSManagedObject?) -> Any? {
return self.bridgeToSwift.edit(object)
return self.swiftTransaction.edit(object)
}
/**
@@ -82,7 +82,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func editInto(_ into: CSInto, objectID: NSManagedObjectID) -> Any? {
return self.bridgeToSwift.edit(into.bridgeToSwift, objectID)
return self.swiftTransaction.edit(into.bridgeToSwift, objectID)
}
/**
@@ -93,7 +93,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func deleteObject(_ object: NSManagedObject?) {
self.bridgeToSwift.delete(object)
self.swiftTransaction.delete(object)
}
/**
@@ -104,7 +104,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func deleteObjects(_ objects: [NSManagedObject]) {
self.bridgeToSwift.delete(objects)
self.swiftTransaction.delete(objects)
}
/**
@@ -113,7 +113,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func refreshAndMergeAllObjects() {
self.bridgeToSwift.refreshAndMergeAllObjects()
self.swiftTransaction.refreshAndMergeAllObjects()
}
@@ -128,7 +128,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func insertedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
return self.bridgeToSwift.insertedObjects(entity)
return self.swiftTransaction.insertedObjects(entity)
}
/**
@@ -139,7 +139,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func insertedObjectIDs() -> Set<NSManagedObjectID> {
return self.bridgeToSwift.insertedObjectIDs()
return self.swiftTransaction.insertedObjectIDs()
}
/**
@@ -151,7 +151,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func insertedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
return self.bridgeToSwift.insertedObjectIDs(entity)
return self.swiftTransaction.insertedObjectIDs(entity)
}
/**
@@ -163,7 +163,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func updatedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
return self.bridgeToSwift.updatedObjects(entity)
return self.swiftTransaction.updatedObjects(entity)
}
/**
@@ -174,7 +174,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func updatedObjectIDs() -> Set<NSManagedObjectID> {
return self.bridgeToSwift.updatedObjectIDs()
return self.swiftTransaction.updatedObjectIDs()
}
/**
@@ -186,7 +186,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func updatedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
return self.bridgeToSwift.updatedObjectIDs(entity)
return self.swiftTransaction.updatedObjectIDs(entity)
}
/**
@@ -198,7 +198,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func deletedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
return self.bridgeToSwift.deletedObjects(entity)
return self.swiftTransaction.deletedObjects(entity)
}
/**
@@ -209,7 +209,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
return self.bridgeToSwift.deletedObjectIDs()
return self.swiftTransaction.deletedObjectIDs()
}
/**
@@ -221,7 +221,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func deletedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
return self.bridgeToSwift.deletedObjectIDs(entity)
return self.swiftTransaction.deletedObjectIDs(entity)
}
@@ -229,7 +229,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
public override var hash: Int {
return ObjectIdentifier(self.bridgeToSwift).hashValue
return ObjectIdentifier(self.swiftTransaction).hashValue
}
public override func isEqual(_ object: Any?) -> Bool {
@@ -238,28 +238,20 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
return false
}
return self.bridgeToSwift === object.bridgeToSwift
return self.swiftTransaction === object.swiftTransaction
}
// MARK: CoreStoreObjectiveCType
// MARK: Internal
public required init(_ swiftValue: BaseDataTransaction) {
internal let swiftTransaction: BaseDataTransaction
internal init(_ swiftValue: BaseDataTransaction) {
self.swiftTransaction = swiftValue
super.init()
}
public var bridgeToSwift: BaseDataTransaction {
return self.swiftTransaction
}
// MARK: Private
private let swiftTransaction: BaseDataTransaction
// MARK: Deprecated
@@ -267,20 +259,20 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
@objc
public func insertedObjects() -> Set<NSManagedObject> {
return self.bridgeToSwift.insertedObjects()
return self.swiftTransaction.insertedObjects()
}
@available(*, deprecated, message: "Use -[updatedObjectsOfType:] and pass the specific entity class")
@objc
public func updatedObjects() -> Set<NSManagedObject> {
return self.bridgeToSwift.updatedObjects()
return self.swiftTransaction.updatedObjects()
}
@available(*, deprecated, message: "Use -[deletedObjectsOfType:] and pass the specific entity class")
@objc
public func deletedObjects() -> Set<NSManagedObject> {
return self.bridgeToSwift.deletedObjects()
return self.swiftTransaction.deletedObjects()
}
}

View File

@@ -2,7 +2,7 @@
// CSClauseTypes.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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

View File

@@ -2,7 +2,7 @@
// CSCoreStore+Migrating.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// CSCoreStore+Observing.swift
// CoreStore
//
// Copyright © 2015 John Rommel Estropia
// 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
@@ -29,8 +29,8 @@ import CoreData
// MARK: - CSCoreStore
@available(OSX 10.12, *)
public extension CSCoreStore {
@available(macOS 10.12, *)
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

@@ -2,7 +2,7 @@
// CSCoreStore+Querying.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// CSCoreStore+Setup.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// CSCoreStore+Transaction.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// CSCoreStore.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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

View File

@@ -2,7 +2,7 @@
// CSDataStack+Migrating.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -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

@@ -2,7 +2,7 @@
// CSDataStack+Observing.swift
// CoreStore
//
// Copyright © 2016 John Rommel Estropia
// 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
@@ -29,8 +29,8 @@ import CoreData
// MARK: - CSDataStack
@available(OSX 10.12, *)
public extension CSDataStack {
@available(macOS 10.12, *)
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`.

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