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:
+
+
+
+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:
+
+
+
# 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")
}
}