From 1ddbe20c86ec2c22d4d86868303d7e7e0569b0f4 Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Sun, 28 May 2017 11:37:40 +0900 Subject: [PATCH] Updated README, fixed demo app, and bumped to 4.0.1 --- CoreStore.podspec | 2 +- CoreStoreDemo/CoreStoreDemo/AppDelegate.swift | 1 - CoreStoreDemo/CoreStoreDemo/Info.plist | 4 +-- .../MigrationsDemoViewController.swift | 23 ++++++++++-- README.md | 36 +++++++++++++++++++ Sources/DynamicSchema+Convenience.swift | 12 ++++--- 6 files changed, 67 insertions(+), 11 deletions(-) diff --git a/CoreStore.podspec b/CoreStore.podspec index bc7fe3e..81734ac 100644 --- a/CoreStore.podspec +++ b/CoreStore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "CoreStore" - s.version = "4.0.0" + s.version = "4.0.1" 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/CoreStoreDemo/CoreStoreDemo/AppDelegate.swift b/CoreStoreDemo/CoreStoreDemo/AppDelegate.swift index 3b8a8c4..6e433b7 100644 --- a/CoreStoreDemo/CoreStoreDemo/AppDelegate.swift +++ b/CoreStoreDemo/CoreStoreDemo/AppDelegate.swift @@ -8,7 +8,6 @@ import UIKit -import CoreStore // MARK: - AppDelegate diff --git a/CoreStoreDemo/CoreStoreDemo/Info.plist b/CoreStoreDemo/CoreStoreDemo/Info.plist index 2febe10..82edb50 100644 --- a/CoreStoreDemo/CoreStoreDemo/Info.plist +++ b/CoreStoreDemo/CoreStoreDemo/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.1 + 4.0.1 CFBundleSignature ???? CFBundleVersion - 1 + 4 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift b/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift index 980dfb3..ee959d0 100644 --- a/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift +++ b/CoreStoreDemo/CoreStoreDemo/MIgrations Demo/MigrationsDemoViewController.swift @@ -91,6 +91,11 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD } } + func listMonitorDidRefetch(_ monitor: ListMonitor) { + + self.listMonitorDidChange(monitor) + } + // MARK: UITableViewDataSource @objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -148,7 +153,10 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD label: "Model V1", entityType: OrganismV1.self, schemaHistory: SchemaHistory( - modelName: "MigrationDemo", + XcodeDataModelSchema.from( + modelName: "MigrationDemo", + migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"] + ), migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"] ) ), @@ -156,7 +164,13 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD label: "Model V2", entityType: OrganismV2.self, schemaHistory: SchemaHistory( - modelName: "MigrationDemo", + XcodeDataModelSchema.from( + modelName: "MigrationDemo", + migrationChain: [ + "MigrationDemo": "MigrationDemoV2", + "MigrationDemoV3": "MigrationDemoV2" + ] + ), migrationChain: [ "MigrationDemo": "MigrationDemoV2", "MigrationDemoV3": "MigrationDemoV2" @@ -167,7 +181,10 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD label: "Model V3", entityType: OrganismV3.self, schemaHistory: SchemaHistory( - modelName: "MigrationDemo", + XcodeDataModelSchema.from( + modelName: "MigrationDemo", + migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"] + ), migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"] ) ) diff --git a/README.md b/README.md index cd89ec8..e87be33 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ Unleashing the real power of Core Data with the elegance and safety of Swift 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). +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). @@ -88,6 +90,7 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep - [Observe a list of objects](#observe-a-list-of-objects) - [Objective-C support](#objective-c-support) - [Type-safe `CoreStoreObject`s](#type-safe-corestoreobjects) + - [`VersionLock`s](#versionlocks) - [Roadmap](#roadmap) - [Installation](#installation) - [Changesets](#changesets) @@ -1696,6 +1699,39 @@ let puppies = CoreStore.fetchAll( All CoreStore APIs that are usable with `NSManagedObject`s are also available for `CoreStoreObject`s. These include `ListMonitor`s, `ImportableObject`s, fetching, etc. +### `VersionLock`s + +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: + +VersionLock + +Copy this dictionary value and use it as the `versionLock:` argument of the `CoreStoreSchema` initializer: +```swift +CoreStoreSchema( + modelVersion: "V1", + entities: [ + Entity("Animal", isAbstract: true), + Entity("Dog"), + Entity("Person"), + ], + versionLock: [ + "Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a], + "Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7], + "Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b] + ] +) +``` +You can also get this hash after the `DataStack` has been fully set up by printing to the console: +```swift +print(CoreStore.defaultStack.modelSchema.printCoreStoreSchema()) +``` + +Once the version lock is set, any changes in the properties or to the model will trigger an assertion failure similar to this: + +VersionLock failure + # Installation - Requires: diff --git a/Sources/DynamicSchema+Convenience.swift b/Sources/DynamicSchema+Convenience.swift index 45ad08b..45b2fbb 100644 --- a/Sources/DynamicSchema+Convenience.swift +++ b/Sources/DynamicSchema+Convenience.swift @@ -193,9 +193,11 @@ public extension DynamicSchema { let indexedString = attribute.isIndexed ? ", isIndexed: true" : "" let transientString = attribute.isTransient ? ", isTransient: true" : "" // TODO: escape strings - let versionHashModifierString = attribute.versionHashModifier.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? "" + let versionHashModifierString = attribute.versionHashModifier + .flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? "" // TODO: escape strings - let renamingIdentifierString = attribute.renamingIdentifier.flatMap({ ", renamingIdentifier: \"\($0)\"" }) ?? "" + let renamingIdentifierString = attribute.renamingIdentifier + .flatMap({ ($0 == attributeName ? "" : ", renamingIdentifier: \"\($0)\"") as String }) ?? "" output.append(" let \(attributeName) = \(containerType)<\(String(describing: valueType))>(\"\(attributeName)\"\(indexedString)\(defaultString)\(transientString)\(versionHashModifierString)\(renamingIdentifierString))\n") } } @@ -260,8 +262,10 @@ public extension DynamicSchema { fatalError("Unsupported delete rule \((relationship.deleteRule)) for relationship \"\(relationshipQualifier)\"") } } - let versionHashModifierString = relationship.versionHashModifier.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? "" - let renamingIdentifierString = relationship.renamingIdentifier.flatMap({ ", renamingIdentifier: \"\($0)\"" }) ?? "" + let versionHashModifierString = relationship.versionHashModifier + .flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? "" + let renamingIdentifierString = relationship.renamingIdentifier + .flatMap({ ($0 == relationshipName ? "" : ", renamingIdentifier: \"\($0)\"") as String }) ?? "" output.append(" let \(relationshipName) = \(containerType)<\(relationship.destinationEntity!.name!)>(\"\(relationshipName)\"\(inverseString)\(deleteRuleString)\(minCountString)\(maxCountString)\(versionHashModifierString)\(renamingIdentifierString))\n") } }