Skip to content

Releases: JohnEstropia/CoreStore

Min Deployment = iOS 10 (Breaking changes)

23 Jan 08:40
Compare
Choose a tag to compare

⚠️This update will break current code. Make sure to read the changes below:

Breaking changes

  • Minimum Deployment Version is raised to iOS 10, macOS 10.12, tvOS 10, watchOS 3
  • ICloudStore and ICloudStoreObservers are now officially deprecated (iCloud Core Data had been deprecated quite a long time ago).
  • Fetching and Querying methods now throws an error of type CoreStoreError.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

  • CoreStoreObjects (as well as their PartialObject counterparts) now conform to CustomDebugStringConvertable by default.
  • CoreStoreObjects now assert on property names that possibly collide with reserved names such as description
  • CoreStoreObject properties can now be observed individually without the need for ObjectMonitors. 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 ObjectMonitors 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 the CoreStore iOS schema at least once to create the framework used by the Playgrounds.

Improvements

  • Fixed queue assertion for UnsafeDataTransactions (#275)
  • ListMonitor access performance boost (#287, #288)
  • Added a new CoreStoreError.asynchronousMigrationRequired(URL) for cases when addStorageAndWait() 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

28 Dec 16:10
Compare
Choose a tag to compare

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)

12 Oct 23:07
Compare
Choose a tag to compare
  • typealias KeyPath = String was changed to typealias RawKeyPath = String

4.0.0

24 May 06:40
Compare
Choose a tag to compare

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.

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 for more details.

Other Changes

  • ListMonitor.refetch(...) now works by recreating its internal NSFetchedResultsController. Previously refetch(...) would only apply new FetchClauses 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 CoreStoreObjects conform to. (See 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)
    • 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)

3.0.0

21 May 14:06
Compare
Choose a tag to compare

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 the FetchableSource and QueryableProtocol protocols, which are retrievable with NSManagedObject.fetchSource() and NSManagedObject.querySource() respectively. These protocols are implemented by DataStack and BaseDataTransaction.

Deprecated
Methods have been renamed to better fit the Swift 3 naming conventions.

  • entityDescriptionForType(_:)entityDescription(for:)
  • objectIDForURIRepresentation(_:)objectID(for:)
  • ImportableObject and ImportableUniqueObject 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 Swift CustomNSError 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

21 May 14:09
Compare
Choose a tag to compare

Upgrading from 1.x.x to 2.x.x

Obsoleted

  • AsynchronousDataTransaction.rollback() was removed. Undo and rollback functionality are now only allowed on UnsafeDataTransactions
  • DetachedDataTransaction was renamed to UnsafeDataTransaction
  • beginDetached() was renamed to beginUnsafe()
  • PersistentStoreResult was removed in favor of SetupResult<T>
  • SynchronousDataTransaction.commit() was renamed to SynchronousDataTransaction.commitAndWait()
  • From initializers that accepted NSURLs and NSPersistentStore 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 use LegacySQLiteStore instead of SQLiteStore to maintain the old default file names and directory values
    • addInMemoryStoreAndWait(...)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 the LegacySQLiteStore and SQLiteStore initializers as a LocalStorageOptions option set
  • NSError used to have a coreStoreErrorCode property that returns CoreStoreErrorCode enum, but all CoreStore errors are now guaranteed to be CoreStoreError enum type in swift, and CSError type on Objective-C.
  • CoreStoreLogger.handleError(...) was deprecated in favor of CoreStoreLogger.log(error:...). CoreStoreLogger may also implement CoreStoreLogger.abort(...), which is called just before CoreStore executes fatalError() due to critical runtime errors.