Releases: JohnEstropia/CoreStore
Min Deployment = iOS 10 (Breaking changes)
Breaking changes
- Minimum Deployment Version is raised to
iOS 10
,macOS 10.12
,tvOS 10
,watchOS 3
ICloudStore
andICloudStoreObserver
s are now officially deprecated (iCloud Core Data had been deprecated quite a long time ago).- Fetching and Querying methods now
throws
an error of typeCoreStoreError.persistentStoreNotFound(DynamicObject.Type)
when the specified entity does not exist in any storage. This is to distinguish difference between non-existing objects versus non-existing stores.
// Before
if let object = CoreStore.fetchOne(...) {
// ...
}
else {
// May be nil because `addStorage()` hasn't completed yet or because nothing really matches the query
}
// After
do {
if let object = try CoreStore.fetchOne(...) {
// ...
}
else {
// `addStorage()` has completed but nothing matches the query
}
}
catch {
// method was called before `addStorage()` completed
}
If you are sure you won't encounter cases where fetches happen before a storage is added to the DataStack
, simply add try!
to your fetch*()
and query*()
method calls.
Conveniences
CoreStoreObject
s (as well as theirPartialObject
counterparts) now conform toCustomDebugStringConvertable
by default.CoreStoreObject
s now assert on property names that possibly collide with reserved names such asdescription
CoreStoreObject
properties can now be observed individually without the need forObjectMonitor
s. The API is a bit similar to the standard KVO API:
// NSManagedObject
let observer = person.observe(\.friends, options: [.new, .old]) { (person, change) in
// ...
}
// CoreStoreObject
let observer = person.friends.observe(options: [.new, .old]) { (person, change) in
// ...
}
You may still use ObjectMonitor
s especially for observing multiple changes at once.
- CoreStore now has its own Playgrounds file! You can find this at the top of the workspace (run
pod try CoreStore
if you don't have it locally). You will need to build theCoreStore iOS
schema at least once to create the framework used by the Playgrounds.
Improvements
- Fixed queue assertion for
UnsafeDataTransaction
s (#275) ListMonitor
access performance boost (#287, #288)- Added a new
CoreStoreError.asynchronousMigrationRequired(URL)
for cases whenaddStorageAndWait()
is used together with.allowSynchronousLightweightMigration
but migrations are only allowed asynchronously (#277) - CoreStore docs are now powered by jazzy
- Fixed issue with
InferredSchemaMappingProvider
not respecting renaming identifiers (#301)
Swift 4: Generic Clauses, Fetch and Query Chain Builders, Smart KeyPaths
This release builds on Swift 4.
Generic Clauses
Most fetch and query clauses such as Where
, OrderBy
, etc. are now generic types. In effect, clauses using the previous fetching/querying calls need to indicate their generic type:
var people = CoreStore.fetchAll(
From<MyPersonEntity>(),
Where<MyPersonEntity>("%K > %d", "age", 30),
OrderBy<MyPersonEntity>(.ascending("name"))
)
This is quite repetitive. To make this even more convenient, CoreStore now has fetch/query builders.
Fetch and Query Chain Builders
var people = CoreStore.fetchAll(
From<MyPersonEntity>()
.where(format: "%K > %d", "age", 30)
.orderBy(.ascending("name"))
)
This way the generic type is propagated onto subsequent clauses. But we can improve this further.
Smart KeyPaths
Using Swift 4's type-safe keypaths, we can make our fetch/query expressions even more solid.
var people = CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30)
.orderBy(.ascending(\.name))
)
All CoreStore API that accepts a string keypath now accepts these Smart Keypaths. (If I missed some, please post a github issue)
Swift 3.2 Support (Xcode 9)
typealias KeyPath = String
was changed totypealias RawKeyPath = String
4.0.0
Upgrading from 3.x.x to 4.x.x
Obsoleted
LegacySQLiteStore
is now finally obsoleted in favor ofSQLiteStore
. For sqlite files that were created previously withLegacySQLiteStore
, make sure to use theSQLiteStore.legacy(...)
factory method to create anSQLiteStore
that can load the file from the legacy file path.SQLiteStore.init(...)
'smappingModelBundles
argument is now obsolete. The new initializer accepts amigrationMappingProviders
optional argument where explicit mapping sources are declared. For reference on how to do this, read on Custom migrations.
Deprecated
DataStack.beginAsynchronous(...)
,DataStack.beginSynchronous(...)
,AsynchronousDataTransaction.commit(...)
, andSynchronousDataTransaction.commit(...)
are now deprecated in favor ofDataStack.perform(asynchronous:...)
andDataStack.perform(synchronous:...)
family of methods. These newperform(...)
methods are auto-commit, meaning the transaction automatically callscommit()
internally after the transction closure completes. To roll-back and cancel a transaction, calltry transaction.cancel()
. Read Saving and processing transactions for more details.
Other Changes
ListMonitor.refetch(...)
now works by recreating its internalNSFetchedResultsController
. Previouslyrefetch(...)
would only apply newFetchClause
s on top of previous fetches. Now allFetchClauses
are required to be passed torefetch(...)
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 anyNSManagedObject
orCoreStoreObject
s conform to. (See Type-safeCoreStoreObject
s) - Version Schema (
DynamicSchema
protocol): These types contain info for a single model version, as well as entities that belong to it. Currently supportsXcodeDataModelSchema
(.xcdatamodeld file),CoreStoreSchema
, orUnsafeDataModelSchema
. (See Migrations) - Schema History (
SchemaHistory
class): This is now the preferred way to express all models to theDataStack
. This class contains info to all theDynamicSchema
across multiple model versions. (See Migrations)
- Dynamic Models (
3.0.0
Upgrading from 2.x.x to 3.x.x
Obsoleted
UnsageDataTransaction.internalContext
was removed. Accessing the internal context (or more specifically, accessing context-level methods such as fetches) are now available through theFetchableSource
andQueryableProtocol
protocols, which are retrievable withNSManagedObject.fetchSource()
andNSManagedObject.querySource()
respectively. These protocols are implemented byDataStack
andBaseDataTransaction
.
Deprecated
Methods have been renamed to better fit the Swift 3 naming conventions.
entityDescriptionForType(_:)
→entityDescription(for:)
objectIDForURIRepresentation(_:)
→objectID(for:)
ImportableObject
andImportableUniqueObject
protocol methods (and their variants) have been renamed. The old methods are still available, but will be removed in a future update.shouldInsertFromImportSource(_:inTransaction:)
→shouldInsert(from:in:)
didInsertFromImportSource(_:inTransaction:)
→didInsert(from:in:)
shouldUpdateFromImportSource(_:inTransaction :)
→shouldUpdate(from:in:)
uniqueIDFromImportSource(_:inTransaction :)
→uniqueID(from:in:)
updateFromImportSource(_:inTransaction:)
→update(from:in:)
Miscellaneous
- APIs obsoleted from 2.0.0 have been removed.
- CoreStore does not depend on GCDKit anymore, thanks to Swift 3's better Grand Central Dispatch API.
- All enum cases are now lowercased
CoreStoreError
now implements the new SwiftCustomNSError
protocol for better Objective-C
bridging.- Some methods may emit warnings for unused return values.
@discardableResult
annotations have been set to better reflect the responsibility of API users to use/inspect return values.
2.0.0
Upgrading from 1.x.x to 2.x.x
Obsoleted
AsynchronousDataTransaction.rollback()
was removed. Undo and rollback functionality are now only allowed onUnsafeDataTransaction
sDetachedDataTransaction
was renamed toUnsafeDataTransaction
beginDetached()
was renamed tobeginUnsafe()
PersistentStoreResult
was removed in favor ofSetupResult<T>
SynchronousDataTransaction.commit()
was renamed toSynchronousDataTransaction.commitAndWait()
From
initializers that acceptedNSURL
s andNSPersistentStore
were removed.
Deprecated
The following methods are still available, but will be removed in a future update.
add*Store(...)
method variants. It is strongly recommended to convert to the new API. Refer to Local store) usage then useLegacySQLiteStore
instead ofSQLiteStore
to maintain the old default file names and directory valuesaddInMemoryStoreAndWait(...)
→addStorageAndWait(InMemoryStore(...))
addSQLiteStoreAndWait(...)
→addStorageAndWait(LegacySQLiteStore(...))
addInMemoryStore(...)
→addStorage(InMemoryStore(...), ...)
addSQLiteStore(...)
→addStorage(LegacySQLiteStore(...), ...)
requiredMigrationsForSQLiteStore(...)
→requiredMigrationsForStorage(...)
upgradeSQLiteStoreIfNeeded(...)
→upgradeStorageIfNeeded(...)
- The
resetStoreOnModelMismatch: Bool
argument for the methods above are now provided to theLegacySQLiteStore
andSQLiteStore
initializers as aLocalStorageOptions
option set
NSError
used to have acoreStoreErrorCode
property that returnsCoreStoreErrorCode
enum, but all CoreStore errors are now guaranteed to beCoreStoreError
enum type in swift, andCSError
type on Objective-C.CoreStoreLogger.handleError(...)
was deprecated in favor ofCoreStoreLogger.log(error:...)
.CoreStoreLogger
may also implementCoreStoreLogger.abort(...)
, which is called just before CoreStore executesfatalError()
due to critical runtime errors.