From 35885b40deaeafa608ba7631f17885b600d78222 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Wed, 24 May 2017 12:05:34 +0900 Subject: [PATCH] README done! Welcome to CoreStore 4.0! --- CoreStore.podspec | 2 +- CoreStore.xcodeproj/project.pbxproj | 40 ++-- README.md | 212 ++++++++++++++++-- Sources/CSSQliteStore.swift | 2 +- ...ma.swift => CSUnsafeDataModelSchema.swift} | 28 +-- ...reStore+CustomDebugStringConvertible.swift | 4 +- Sources/DataStack.swift | 4 +- Sources/DynamicSchema.swift | 2 +- Sources/ICloudStore.swift | 1 - Sources/SQLiteStore.swift | 4 +- ...hema.swift => UnsafeDataModelSchema.swift} | 12 +- 11 files changed, 242 insertions(+), 69 deletions(-) rename Sources/{CSLegacyXcodeDataModelSchema.swift => CSUnsafeDataModelSchema.swift} (74%) rename Sources/{LegacyXcodeDataModelSchema.swift => UnsafeDataModelSchema.swift} (79%) diff --git a/CoreStore.podspec b/CoreStore.podspec index 718a8dc..bc7fe3e 100644 --- a/CoreStore.podspec +++ b/CoreStore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "CoreStore" - s.version = "4.0.0-beta4" + s.version = "4.0.0" 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" diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 551ec82..a34b673 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -214,10 +214,10 @@ B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; }; B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; }; B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; }; - B52F74411E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; }; - B52F74421E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; }; - B52F74431E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; }; - B52F74441E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; }; + B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; }; + B52F74421E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; }; + B52F74431E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; }; + B52F74441E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; }; B52F74451E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; }; B52F74461E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; }; B52F74471E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; }; @@ -426,10 +426,10 @@ B56923FB1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; }; B56923FC1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; }; B56923FD1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; }; - B56923FF1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; }; - B56924001EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; }; - B56924011EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; }; - B56924021EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; }; + B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; }; + B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; }; + B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; }; + B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; }; B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */; }; B56965241B356B820075EE4A /* MigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965231B356B820075EE4A /* MigrationResult.swift */; }; B57D27BE1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */; }; @@ -746,7 +746,7 @@ B52DD17D1BE1F8CC00949AFE /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaHistory.swift; sourceTree = ""; }; B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicSchema.swift; sourceTree = ""; }; - B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyXcodeDataModelSchema.swift; sourceTree = ""; }; + B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeDataModelSchema.swift; sourceTree = ""; }; B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodeDataModelSchema.swift; sourceTree = ""; }; B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreSchema.swift; sourceTree = ""; }; B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Logging.swift"; sourceTree = ""; }; @@ -800,7 +800,7 @@ B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodeSchemaMappingProvider.swift; sourceTree = ""; }; B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDynamicSchema.swift; sourceTree = ""; }; B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSXcodeDataModelSchema.swift; sourceTree = ""; }; - B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSLegacyXcodeDataModelSchema.swift; sourceTree = ""; }; + B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataModelSchema.swift; sourceTree = ""; }; B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.swift; sourceTree = ""; }; B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestDataTestCase.swift; sourceTree = ""; }; @@ -1108,7 +1108,7 @@ B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */, B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */, B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */, - B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */, + B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */, ); name = "Dynamic Schema"; sourceTree = ""; @@ -1190,7 +1190,7 @@ children = ( B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */, B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */, - B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */, + B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */, ); name = "Dynamic Schema"; sourceTree = ""; @@ -1788,7 +1788,7 @@ B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */, B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, - B52F74411E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */, + B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */, B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */, B5A9921F1EA898710091A2E3 /* UserInfo.swift in Sources */, B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */, @@ -1900,7 +1900,7 @@ B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */, B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */, - B56923FF1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */, + B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */, B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */, B56923EC1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */, B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */, @@ -1972,7 +1972,7 @@ B5E1B59A1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */, B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, - B52F74421E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */, + B52F74421E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */, B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */, B5A992201EA898720091A2E3 /* UserInfo.swift in Sources */, B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */, @@ -2084,7 +2084,7 @@ B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */, B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */, B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */, - B56924001EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */, + B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */, 82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */, B56923ED1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */, 82BA18B91C4BBD4A00A0916E /* From.swift in Sources */, @@ -2156,7 +2156,7 @@ B5ECDC211CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */, B52DD1C21BE1F94600949AFE /* MigrationManager.swift in Sources */, B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, - B52F74441E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */, + B52F74441E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */, B5ECDC2D1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, B5A992221EA898720091A2E3 /* UserInfo.swift in Sources */, B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */, @@ -2268,7 +2268,7 @@ B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */, B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */, B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */, - B56924021EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */, + B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */, B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */, B56923EF1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */, B53FBA081CAB300C00F0D40A /* CSMigrationType.swift in Sources */, @@ -2340,7 +2340,7 @@ B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */, B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */, - B52F74431E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */, + B52F74431E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */, B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */, B5A992211EA898720091A2E3 /* UserInfo.swift in Sources */, B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */, @@ -2452,7 +2452,7 @@ B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */, B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */, B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */, - B56924011EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */, + B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */, B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */, B56923EE1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */, B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */, diff --git a/README.md b/README.md index c901e19..cd89ec8 100644 --- a/README.md +++ b/README.md @@ -24,20 +24,20 @@ Upgrading from CoreStore 3.x to 4.x? Check out the [new features](#features) and ## Why use CoreStore? -CoreStore is the answer to the [pain](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 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. And with Core Data and Swift continuously being improved by Apple, CoreStore will just get better and better! +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 Swift’s 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))* +- **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))* +- ⭐️ **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))* +- ⭐️ **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. @@ -58,8 +58,11 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep - [Local store](#local-store) - [iCloud store](#icloud-store) - [Migrations](#migrations) + - [Declaring model versions](#declaring-model-versions) + - [Starting migrations](#starting-migrations) - [Progressive migrations](#progressive-migrations) - [Forecasting migrations](#forecasting-migrations) + - [Custom migratoins](#custom-migrations) - [Saving and processing transactions](#saving-and-processing-transactions) - [Transaction types](#transaction-types) - [Asynchronous transactions](#asynchronous-transactions) @@ -282,7 +285,7 @@ let migrationProgress = CoreStore.addStorage( SQLiteStore( fileName: "MyStore.sqlite", configuration: "Config2", // optional. Use entities from the "Config2" configuration in the .xcdatamodeld file - mappingModelBundles: [Bundle.main], // optional. The bundles that contain required .xcmappingmodel files + migrationMappingProviders: [Bundle.main], // optional. The bundles that contain required .xcmappingmodel files localStorageOptions: .recreateStoreOnModelMismatch // optional. Provides settings that tells the DataStack how to setup the persistent store ), completion: { /* ... */ } @@ -308,7 +311,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 -> 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 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/) 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 @@ -369,7 +372,94 @@ The `ICloudStore` only keeps weak references of the registered observers. You ma ## 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: + +### Declaring model versions +Until CoreStore 4.0, model versions were always assumed to be declared in *.xcdatamodeld* files. The `DataStack` loads these for us by accepting the *.xcdatamodeld* file name and the `Bundle` where the files can be found: +```swift +CoreStore.defaultStack = DataStack( + xcodeModelName: "MyModel", + bundle: Bundle.main, + migrationChain: ["MyAppModel", "MyAppModelV2", "MyAppModelV3", "MyAppModelV4"] +) +``` + +Starting CoreStore 4.0, model versions are now expressed as a first-class protocol, `DynamicSchema`. CoreStore currently supports the following schema classes: +- **`XcodeDataModelSchema`**: a model version with entities loaded from a *.xcdatamodeld* file. +- **`CoreStoreSchema`**: a model version created with `CoreStoreObject` entities. *(See [Type-safe `CoreStoreObject`s](#type-safe-corestore-objects))* +- **`UnsafeDataModelSchema`**: a model version created with an existing `NSManagedObjectModel` instance. + +All the `DynamicSchema` for all model versions are then collected within a single `SchemaHistory` instance, which is then handed to the `DataStack`. Here are some common use cases: + +**Multiple model versions grouped in a *.xcdatamodeld* file (Core Data standard method)** +```swift +CoreStore.defaultStack = DataStack( + xcodeModelName: "MyModel", + bundle: Bundle.main, + migrationChain: ["MyAppModel", "MyAppModelV2", "MyAppModelV3", "MyAppModelV4"] +) +``` + +**`CoreStoreSchema`-based model version (No *.xcdatamodeld* file needed)** +*(For more details, see also [Type-safe `CoreStoreObject`s](#type-safe-corestore-objects))* +```swift +class Animal: CoreStoreObject { + // ... +} +class Dog: Animal { + // ... +} +class Person: CoreStoreObject { + // ... +} + +CoreStore.defaultStack = DataStack( + CoreStoreSchema( + modelVersion: "V1", + entities: [ + Entity("Animal", isAbstract: true), + Entity("Dog"), + Entity("Person") + ] + ) +) +``` + +**Models in a *.xcdatamodeld* file during past app versions, but migrated to the new `CoreStoreSchema` method** +```swift +class Animal: CoreStoreObject { + // ... +} +class Dog: Animal { + // ... +} +class Person: CoreStoreObject { + // ... +} + +let legacySchema = XcodeDataModelSchema.from( + modelName: "MyModel", // .xcdatamodeld name + bundle: bundle, + migrationChain: ["MyAppModel", "MyAppModelV2", "MyAppModelV3", "MyAppModelV4"] +) +let newSchema = CoreStoreSchema( + modelVersion: "V1", + entities: [ + Entity("Animal", isAbstract: true), + Entity("Dog"), + Entity("Person") + ] +) +CoreStore.defaultStack = DataStack( + schemaHistory: SchemaHistory( + legacySchema + [newSchema], + migrationChain: ["MyAppModel", "MyAppModelV2", "MyAppModelV3", "MyAppModelV4", "V1"] + ) +) +``` + + +### 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: ```swift try dataStack.addStorageAndWait( SQLiteStore( @@ -433,7 +523,7 @@ This allows for different migration paths depending on the starting version. The - MyAppModelV2-MyAppModelV4 - MyAppModelV3-MyAppModelV4 -Initializing with empty values (either `nil`, `[]`, or `[:]`) instructs the `DataStack` to disable progressive migrations and revert to the default migration behavior (i.e. use the .xcdatamodel's current version as the final version): +Initializing with empty values (either `nil`, `[]`, or `[:]`) instructs the `DataStack` to disable progressive migrations and revert to the default migration behavior (i.e. use the *.xcdatamodeld*'s current version as the final version): ```swift let dataStack = DataStack(migrationChain: nil) ``` @@ -471,12 +561,71 @@ catch { ``` `requiredMigrationsForStorage(_:)` returns an array of `MigrationType`s, where each item in the array may be either of the following values: ```swift -case Lightweight(sourceVersion: String, destinationVersion: String) -case Heavyweight(sourceVersion: String, destinationVersion: String) +case lightweight(sourceVersion: String, destinationVersion: String) +case heavyweight(sourceVersion: String, destinationVersion: String) ``` Each `MigrationType` indicates the migration type for each step in the `MigrationChain`. Use these information as fit for your app. +### Custom migrations + +Before CoreStore 4.0, the only way to implement custom migrations is to use Core Data's standard method: declaring entity mappings through *.xcmappingmodel* files. Starting CoreStore 4.0, new ways to declare migration mappings have been added: + +- `InferredSchemaMappingProvider`: The default mapping provider which tries to infer model migration between two `DynamicSchema` versions either by searching all *.xcmappingmodel* files from `Bundle.allBundles`, or by relying on lightweight migration if possible. +- `XcodeSchemaMappingProvider`: A mapping provider which loads entity mappings from *.xcmappingmodel* files in a specified `Bundle`. +- `CustomSchemaMappingProvider`: A mapping provider that infers mapping initially, but also accepts custom mappings for specified entities. This was added to support custom migrations with `CoreStoreObject`s as well, but may also be used with `NSManagedObject`s. + +These mapping providers conform to `SchemaMappingProvider` and can be passed to `SQLiteStore`'s initializer: +```swift +let dataStack = DataStack(migrationChain: ["MyAppModel", "MyAppModelV2", "MyAppModelV3", "MyAppModelV4"]) +_ = try dataStack.addStorage( + SQLiteStore( + fileName: "MyStore.sqlite", + migrationMappingProviders: [ + XcodeSchemaMappingProvider(from: "V1", to: "V2", mappingModelBundle: Bundle.main), + CustomSchemaMappingProvider(from: "V2", to: "V3", entityMappings: [.deleteEntity("Person") ]) + ] + ), + completion: { (result) -> Void in + // ... + } +) +``` + +For version migrations present in the `DataStack`'s `MigrationChain` but not handled by any of the `SQLiteStore`'s `migrationMappingProviders` array, CoreStore will automatically try to use `InferredSchemaMappingProvider` as fallback. Finally if the `InferredSchemaMappingProvider` could not resolve any mapping, the migration will fail and the `DataStack.addStorage(...)` method will report the failure. + +For `CustomSchemaMappingProvider`, more granular updates are supported through the dynamic objects `UnsafeSourceObject` and `UnsafeDestinationObject`. The example below allows the migration to conditionally ignore some objects: +```swift +let person_v2_to_v3_mapping = CustomSchemaMappingProvider( + from: "V2", + to: "V3", + entityMappings: [ + .transformEntity( + sourceEntity: "Person", + destinationEntity: "Person", + transformer: { (sourceObject: UnsafeSourceObject, createDestinationObject: () -> UnsafeDestinationObject) in + + if (sourceObject["isVeryOldAccount"] as! Bool?) == true { + return // this account is too old, don't migrate + } + // migrate the rest + let destinationObject = createDestinationObject() + destinationObject.enumerateAttributes { (attribute, sourceAttribute) in + + if let sourceAttribute = sourceAttribute { + destinationObject[attribute] = sourceObject[sourceAttribute] + } + } + ) + ] +) +SQLiteStore( + fileName: "MyStore.sqlite", + migrationMappingProviders: [person_v2_to_v3_mapping] +) +``` +The `UnsafeSourceObject` is a read-only proxy for an object existing in the source model version. The `UnsafeDestinationObject` is a read-write object that is inserted (optionally) to the destination model version. Both classes' properties are accessed through key-value-coding. + ## Saving and processing transactions To ensure deterministic state for objects in the read-only `NSManagedObjectContext`, CoreStore does not expose API's for updating and saving directly from the main context (or any other context for that matter.) Instead, you spawn *transactions* from `DataStack` instances: @@ -1482,10 +1631,23 @@ class Dog: Animal { } class Person: CoreStoreObject { - let name = Value.Required ("name") + let name = Value.Required("name") let pets = Relationship.ToManyUnordered("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("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. + +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 @@ -1501,12 +1663,18 @@ CoreStore.defaultStack = DataStack( ) CoreStore.addStorage(/* ... */) ``` -And that's it. These properties' values can be accessed or mutated using `.value`: +And that's all CoreStore needs to build the model; **we don't need *.xcdatamodeld* files anymore.** + +These special properties' values can be accessed or mutated using `.value`: ```swift CoreStore.perform( asynchronous: { (transaction) in let dog: Dog = CoreStore.fetchOne(From())! + // ... + let nickname = dog.nickname.value // String? + let species = dog.species.value // String let age = dog.age.value // Int + // ... dog.age.value = age + 1 }, completion: { /* ... */ } @@ -1539,8 +1707,13 @@ All CoreStore APIs that are usable with `NSManagedObject`s are also available fo - The `com.apple.CoreData.ConcurrencyDebug` debug argument should be turned off for the app. CoreStore already guarantees safety for you by making the main context read-only, and by only executing transactions serially. ### Install with CocoaPods +In your `Podfile`, add ``` -pod 'CoreStore' +pod 'CoreStore', '~> 4.0' +``` +and run +``` +pod update ``` This installs CoreStore as a framework. Declare `import CoreStore` in your swift file to use the library. @@ -1553,6 +1726,7 @@ and run ``` carthage update ``` +This installs CoreStore as a framework. Declare `import CoreStore` in your swift file to use the library. ### Install as Git Submodule ``` @@ -1575,17 +1749,17 @@ To use the Objective-C syntax sugars, import *CoreStoreBridge.h* in your *.m* so ### 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, see [Migrations](#migrations). +- `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()`. See [Saving and processing transactions](#saving-and-processing-transactions) for more details. +- `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. - - *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), `LegacyXcodeDataModelSchema`, and `CoreStoreSchema`. - - *SchemaHistory* (`SchemaHistory` class): This is now the preferred way to express all models to the `DataStack`. This class contains info of all the `DynamicSchema` across multiple model versions. + - **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 diff --git a/Sources/CSSQliteStore.swift b/Sources/CSSQliteStore.swift index c475e95..fc5ff93 100644 --- a/Sources/CSSQliteStore.swift +++ b/Sources/CSSQliteStore.swift @@ -78,7 +78,7 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT } /** - Initializes an `CSSQLiteStore` with an all-default settings: a `fileURL` pointing to a ".sqlite" file in the "Application Support/" directory (or the "Caches/" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `mappingModelBundles` set to search all `NSBundle`s, and `localStorageOptions` set to `[CSLocalStorageOptions none]`. + Initializes an `CSSQLiteStore` with an all-default settings: a `fileURL` pointing to a ".sqlite" file in the "Application Support/" directory (or the "Caches/" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, and `localStorageOptions` set to `[CSLocalStorageOptions none]`. - Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property. */ diff --git a/Sources/CSLegacyXcodeDataModelSchema.swift b/Sources/CSUnsafeDataModelSchema.swift similarity index 74% rename from Sources/CSLegacyXcodeDataModelSchema.swift rename to Sources/CSUnsafeDataModelSchema.swift index b7e5fa7..c907087 100644 --- a/Sources/CSLegacyXcodeDataModelSchema.swift +++ b/Sources/CSUnsafeDataModelSchema.swift @@ -1,5 +1,5 @@ // -// CSLegacyXcodeDataModelSchema.swift +// CSUnsafeDataModelSchema.swift // CoreStore // // Copyright © 2017 John Rommel Estropia @@ -27,18 +27,18 @@ import CoreData import Foundation -// MARK: - CSLegacyXcodeDataModelSchema +// MARK: - CSUnsafeDataModelSchema /** - The `CSLegacyXcodeDataModelSchema` serves as the Objective-C bridging type for `LegacyXcodeDataModelSchema`. + The `CSUnsafeDataModelSchema` serves as the Objective-C bridging type for `UnsafeDataModelSchema`. - - SeeAlso: `LegacyXcodeDataModelSchema` + - SeeAlso: `UnsafeDataModelSchema` */ @objc -public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType { +public final class CSUnsafeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType { /** - Initializes a `CSLegacyXcodeDataModelSchema` from an `NSManagedObjectModel`. + Initializes a `CSUnsafeDataModelSchema` from an `NSManagedObjectModel`. - parameter modelName: the model version, typically the file name of an *.xcdatamodeld file (without the file extension) - parameter model: the `NSManagedObjectModel` @@ -46,7 +46,7 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core @objc public required init(modelName: ModelVersion, model: NSManagedObjectModel) { - self.bridgeToSwift = LegacyXcodeDataModelSchema( + self.bridgeToSwift = UnsafeDataModelSchema( modelName: modelName, model: model ) @@ -62,7 +62,7 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core public override func isEqual(_ object: Any?) -> Bool { - guard let object = object as? CSLegacyXcodeDataModelSchema else { + guard let object = object as? CSUnsafeDataModelSchema else { return false } @@ -92,9 +92,9 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core // MARK: CoreStoreObjectiveCType - public let bridgeToSwift: LegacyXcodeDataModelSchema + public let bridgeToSwift: UnsafeDataModelSchema - public required init(_ swiftValue: LegacyXcodeDataModelSchema) { + public required init(_ swiftValue: UnsafeDataModelSchema) { self.bridgeToSwift = swiftValue super.init() @@ -102,14 +102,14 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core } -// MARK: - LegacyXcodeDataModelSchema +// MARK: - UnsafeDataModelSchema -extension LegacyXcodeDataModelSchema: CoreStoreSwiftType { +extension UnsafeDataModelSchema: CoreStoreSwiftType { // MARK: CoreStoreSwiftType - public var bridgeToObjectiveC: CSLegacyXcodeDataModelSchema { + public var bridgeToObjectiveC: CSUnsafeDataModelSchema { - return CSLegacyXcodeDataModelSchema(self) + return CSUnsafeDataModelSchema(self) } } diff --git a/Sources/CoreStore+CustomDebugStringConvertible.swift b/Sources/CoreStore+CustomDebugStringConvertible.swift index 6ee2776..dc197e3 100644 --- a/Sources/CoreStore+CustomDebugStringConvertible.swift +++ b/Sources/CoreStore+CustomDebugStringConvertible.swift @@ -374,9 +374,9 @@ extension Into: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { } -// MARK: - LegacyXcodeDataModelSchema +// MARK: - UnsafeDataModelSchema -extension LegacyXcodeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { +extension UnsafeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible { // MARK: CustomDebugStringConvertible diff --git a/Sources/DataStack.swift b/Sources/DataStack.swift index c2c4a08..726ffb6 100644 --- a/Sources/DataStack.swift +++ b/Sources/DataStack.swift @@ -624,14 +624,14 @@ public final class DataStack: Equatable { } - @available(*, deprecated, message: "Use the new DataStack.init(schemaHistory:) initializer passing a LegacyXcodeDataModelSchema instance as argument") + @available(*, deprecated, message: "Use the new DataStack.init(schemaHistory:) initializer passing an UnsafeDataModelSchema instance as argument") public convenience init(model: NSManagedObjectModel, migrationChain: MigrationChain = nil) { let modelVersion = migrationChain.leafVersions.first! self.init( schemaHistory: SchemaHistory( allSchema: [ - LegacyXcodeDataModelSchema( + UnsafeDataModelSchema( modelName: modelVersion, model: model ) diff --git a/Sources/DynamicSchema.swift b/Sources/DynamicSchema.swift index e01b096..bc33d8d 100644 --- a/Sources/DynamicSchema.swift +++ b/Sources/DynamicSchema.swift @@ -32,7 +32,7 @@ import Foundation /** `DynamicSchema` are types that provide `NSManagedObjectModel` instances for a single model version. CoreStore currently supports the following concrete types: - `XcodeDataModelSchema`: describes models loaded from a .xcdatamodeld file. - - `LegacyXcodeDataModelSchema`: describes models loaded directly from an existing `NSManagedObjectModel`. It is not advisable to continue using this model as its metadata are not available to CoreStore. + - `UnsafeDataModelSchema`: describes models loaded directly from an existing `NSManagedObjectModel`. It is not advisable to continue using this model as its metadata are not available to CoreStore. - `CoreStoreSchema`: describes models written for `CoreStoreObject` Swift class declarations. */ public protocol DynamicSchema { diff --git a/Sources/ICloudStore.swift b/Sources/ICloudStore.swift index ec292bc..ba96b6b 100644 --- a/Sources/ICloudStore.swift +++ b/Sources/ICloudStore.swift @@ -62,7 +62,6 @@ public final class ICloudStore: CloudStorage { - parameter ubiquitousContainerID: a container if your app has multiple ubiquity container identifiers in its entitlements - parameter ubiquitousPeerToken: a per-application salt to allow multiple apps on the same device to share a Core Data store integrated with iCloud - parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `ubiquitousContentName` explicitly for each of them. - - parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration. - parameter cloudStorageOptions: When the `ICloudStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`. */ public required init?(ubiquitousContentName: String, ubiquitousContentTransactionLogsSubdirectory: String, ubiquitousContainerID: String? = nil, ubiquitousPeerToken: String? = nil, configuration: ModelConfiguration = nil, cloudStorageOptions: CloudStorageOptions = nil) { diff --git a/Sources/SQLiteStore.swift b/Sources/SQLiteStore.swift index 4534d3e..fff62ff 100644 --- a/Sources/SQLiteStore.swift +++ b/Sources/SQLiteStore.swift @@ -70,7 +70,7 @@ public final class SQLiteStore: LocalStorage { } /** - Initializes an `SQLiteStore` with an all-default settings: a `fileURL` pointing to a ".sqlite" file in the "Application Support/" directory (or the "Caches/" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `mappingModelBundles` set to search all `NSBundle`s, and `localStorageOptions` set to `.AllowProgresiveMigration`. + Initializes an `SQLiteStore` with an all-default settings: a `fileURL` pointing to a ".sqlite" file in the "Application Support/" directory (or the "Caches/" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `migrationMappingProviders` set to empty, and `localStorageOptions` set to `.AllowProgresiveMigration`. - Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was depending on CoreStore's default directories prior to 2.0.0, make sure to use the `SQLiteStore.legacy(...)` factory methods to create the `SQLiteStore` instead of using initializers directly. */ @@ -103,7 +103,7 @@ public final class SQLiteStore: LocalStorage { } /** - Initializes an `LegacySQLiteStore` with an all-default settings: a `fileURL` pointing to a ".sqlite" file in the "Application Support" directory (or the "Caches" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `mappingModelBundles` set to search all `NSBundle`s, and `localStorageOptions` set to `.AllowProgresiveMigration`. + Initializes an `LegacySQLiteStore` with an all-default settings: a `fileURL` pointing to a ".sqlite" file in the "Application Support" directory (or the "Caches" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `migrationMappingProviders` set to empty, and `localStorageOptions` set to `.AllowProgresiveMigration`. - Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was depending on CoreStore's default directories prior to 2.0.0, make sure to use the `SQLiteStore.legacy(...)` factory methods to create the `SQLiteStore` instead of using initializers directly. */ diff --git a/Sources/LegacyXcodeDataModelSchema.swift b/Sources/UnsafeDataModelSchema.swift similarity index 79% rename from Sources/LegacyXcodeDataModelSchema.swift rename to Sources/UnsafeDataModelSchema.swift index f079c17..6230495 100644 --- a/Sources/LegacyXcodeDataModelSchema.swift +++ b/Sources/UnsafeDataModelSchema.swift @@ -1,5 +1,5 @@ // -// LegacyXcodeDataModelSchema.swift +// UnsafeDataModelSchema.swift // CoreStore // // Copyright © 2017 John Rommel Estropia @@ -27,18 +27,18 @@ import CoreData import Foundation -// MARK: - LegacyXcodeDataModelSchema +// MARK: - UnsafeDataModelSchema /** - The `LegacyXcodeDataModelSchema` describes models loaded directly from an existing `NSManagedObjectModel`. It is not advisable to continue using this model as its metadata are not available to CoreStore. + The `UnsafeDataModelSchema` describes models loaded directly from an existing `NSManagedObjectModel`. It is not advisable to continue using this model as its metadata are not available to CoreStore. */ -public final class LegacyXcodeDataModelSchema: DynamicSchema { +public final class UnsafeDataModelSchema: DynamicSchema { /** - Initializes a `LegacyXcodeDataModelSchema` from an `NSManagedObjectModel`. + Initializes a `UnsafeDataModelSchema` from an `NSManagedObjectModel`. ``` CoreStore.defaultStack = DataStack( - LegacyXcodeDataModelSchema(modelName: "MyAppV1", model: model) + UnsafeDataModelSchema(modelName: "MyAppV1", model: model) ) ``` - parameter modelName: the model version, typically the file name of an *.xcdatamodeld file (without the file extension)