diff --git a/.gitignore b/.gitignore
index edbb461..a486161 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@ DerivedData
*.orig
build
Playground_macOS.playground/playground.xcworkspace/xcuserdata
+.swiftpm/xcode/package.xcworkspace/xcuserdata
+.swiftpm/xcode/xcuserdata
+Playground_iOS.playground/playground.xcworkspace/xcuserdata
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj
index c28d06d..81f93e3 100644
--- a/CoreStore.xcodeproj/project.pbxproj
+++ b/CoreStore.xcodeproj/project.pbxproj
@@ -617,6 +617,10 @@
B5E41EC11EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */; };
B5E41EC21EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */; };
B5E41EC31EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */; };
+ B5E5FA4E22D162F400330931 /* ObjectSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E5FA4D22D162F400330931 /* ObjectSnapshot.swift */; };
+ B5E5FA4F22D162F400330931 /* ObjectSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E5FA4D22D162F400330931 /* ObjectSnapshot.swift */; };
+ B5E5FA5022D162F400330931 /* ObjectSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E5FA4D22D162F400330931 /* ObjectSnapshot.swift */; };
+ B5E5FA5122D162F400330931 /* ObjectSnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E5FA4D22D162F400330931 /* ObjectSnapshot.swift */; };
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */; };
B5E834BB1B7691F3001D3D50 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E834BA1B7691F3001D3D50 /* Functions.swift */; };
B5E84EDF1AFF84500064E85B /* DataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDB1AFF84500064E85B /* DataStack.swift */; };
@@ -763,6 +767,7 @@
82BA18921C4BBCBA00A0916E /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
82BA18DE1C4BBE2600A0916E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
82BA18E01C4BBE2C00A0916E /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.1.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
+ B500810F2290CDF800F4CEA5 /* bitrise.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = bitrise.yml; sourceTree = SOURCE_ROOT; };
B501FDDC1CA8D05000BE22EF /* CSSectionBy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSectionBy.swift; sourceTree = ""; };
B501FDE11CA8D1F500BE22EF /* CSListMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSListMonitor.swift; sourceTree = ""; };
B501FDE61CA8D20500BE22EF /* CSListObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSListObserver.swift; sourceTree = ""; };
@@ -876,7 +881,6 @@
B5A9921E1EA898710091A2E3 /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = ""; };
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreBridge.swift; sourceTree = ""; };
- B5BDC91A1C202269008147CD /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cartfile; path = ../Cartfile; sourceTree = ""; };
B5BDC9271C2024F2008147CD /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = SOURCE_ROOT; };
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = ""; };
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = ""; };
@@ -913,6 +917,7 @@
B5E222221CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSynchronousDataTransaction.swift; sourceTree = ""; };
B5E222291CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataTransaction.swift; sourceTree = ""; };
B5E41EBF1EA9BB37006240F0 /* DynamicSchema+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DynamicSchema+Convenience.swift"; sourceTree = ""; };
+ B5E5FA4D22D162F400330931 /* ObjectSnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectSnapshot.swift; sourceTree = ""; };
B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseDataTransaction+Importing.swift"; sourceTree = ""; };
B5E834BA1B7691F3001D3D50 /* Functions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = ""; };
B5E84ED81AFF82360064E85B /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
@@ -1080,9 +1085,9 @@
children = (
2F03A53419C5C6DA005002A5 /* Info.plist */,
B5E84ED81AFF82360064E85B /* README.md */,
+ B500810F2290CDF800F4CEA5 /* bitrise.yml */,
B5E84ED91AFF82360064E85B /* LICENSE */,
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */,
- B5BDC91A1C202269008147CD /* Cartfile */,
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */,
B5BDC9271C2024F2008147CD /* .travis.yml */,
B524E78721CA20AC00BEB794 /* .jazzy.yaml */,
@@ -1357,6 +1362,7 @@
B5E84EFD1AFF847B0064E85B /* Fetching and Querying */,
B5E84F191AFF84860064E85B /* Observing */,
B56964D11B22FF700075EE4A /* Migrating */,
+ B5E5FA4C22D15D3C00330931 /* DataSources */,
B5E84F261AFF84920064E85B /* Convenience */,
B5E84F291AFF849C0064E85B /* Internal */,
);
@@ -1414,6 +1420,14 @@
name = "Fetching and Querying";
sourceTree = "";
};
+ B5E5FA4C22D15D3C00330931 /* DataSources */ = {
+ isa = PBXGroup;
+ children = (
+ B5E5FA4D22D162F400330931 /* ObjectSnapshot.swift */,
+ );
+ name = DataSources;
+ sourceTree = "";
+ };
B5E834B61B7630BD001D3D50 /* Importing */ = {
isa = PBXGroup;
children = (
@@ -1801,10 +1815,9 @@
};
buildConfigurationList = 2F03A52A19C5C6DA005002A5 /* Build configuration list for PBXProject "CoreStore" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
- English,
en,
Base,
);
@@ -1917,6 +1930,7 @@
B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
B51B5C2D22D43E38009FA3BA /* KeyPath+KeyPaths.swift in Sources */,
+ B5E5FA4E22D162F400330931 /* ObjectSnapshot.swift in Sources */,
B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
@@ -2113,6 +2127,7 @@
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
B53FBA141CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
+ B5E5FA4F22D162F400330931 /* ObjectSnapshot.swift in Sources */,
B5E1B5AA1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
B5D339F21E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B5E1B59F1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
@@ -2308,6 +2323,7 @@
B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */,
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */,
+ B5E5FA5122D162F400330931 /* ObjectSnapshot.swift in Sources */,
B5D339F41E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B5220E241D13085E009BC71E /* NSFetchedResultsController+Convenience.swift in Sources */,
B559CD471CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
@@ -2503,6 +2519,7 @@
B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
+ B5E5FA5022D162F400330931 /* ObjectSnapshot.swift in Sources */,
B5D339F31E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B5E1B5A01CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
B5ECDC261CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */,
diff --git a/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/ListObserverDemoViewController.swift b/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/ListObserverDemoViewController.swift
index 6838694..1322f26 100644
--- a/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/ListObserverDemoViewController.swift
+++ b/CoreStoreDemo/CoreStoreDemo/List and Object Observers Demo/ListObserverDemoViewController.swift
@@ -252,7 +252,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
func listMonitor(_ monitor: ListMonitor, didUpdateObject object: Palette, atIndexPath indexPath: IndexPath) {
if let cell = self.tableView.cellForRow(at: indexPath) as? PaletteTableViewCell {
-
+
let palette = ColorsDemo.palettes[indexPath]
cell.colorView?.backgroundColor = palette.color
cell.label?.text = palette.colorText
@@ -261,8 +261,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
func listMonitor(_ monitor: ListMonitor, didMoveObject object: Palette, fromIndexPath: IndexPath, toIndexPath: IndexPath) {
- self.tableView.deleteRows(at: [fromIndexPath], with: .automatic)
- self.tableView.insertRows(at: [toIndexPath], with: .automatic)
+ self.tableView.moveRow(at: fromIndexPath, to: toIndexPath)
}
diff --git a/CoreStoreTests/BaseTests/BaseTestCase.swift b/CoreStoreTests/BaseTests/BaseTestCase.swift
index b7be0a5..d85661e 100644
--- a/CoreStoreTests/BaseTests/BaseTestCase.swift
+++ b/CoreStoreTests/BaseTests/BaseTestCase.swift
@@ -40,7 +40,7 @@ class BaseTestCase: XCTestCase {
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
do {
@@ -50,7 +50,7 @@ class BaseTestCase: XCTestCase {
SQLiteStore(
fileURL: SQLiteStore.defaultRootDirectory
.appendingPathComponent(UUID().uuidString)
- .appendingPathComponent("\(type(of: self))_\(($0 ?? "-null-")).sqlite"),
+ .appendingPathComponent("\(Self.self)_\(($0 ?? "-null-")).sqlite"),
configuration: $0,
localStorageOptions: .recreateStoreOnModelMismatch
)
diff --git a/CoreStoreTests/DynamicModelTests.swift b/CoreStoreTests/DynamicModelTests.swift
index 8eb798d..8e3175d 100644
--- a/CoreStoreTests/DynamicModelTests.swift
+++ b/CoreStoreTests/DynamicModelTests.swift
@@ -213,7 +213,9 @@ class DynamicModelTests: BaseTestDataTestCase {
XCTAssertTrue(person.pets.value.isEmpty)
XCTAssertEqual(
- cs_dynamicType(of: person.rawObject!).keyPathsForValuesAffectingValue(forKey: "displayName"),
+ person.rawObject!
+ .runtimeType()
+ .keyPathsForValuesAffectingValue(forKey: "displayName"),
["title", "name"]
)
@@ -229,9 +231,23 @@ class DynamicModelTests: BaseTestDataTestCase {
XCTAssertEqual(person.name.value, "John")
XCTAssertEqual(person.displayName.value, "Mr. John") // Custom getter
+ let personSnapshot1 = person.createSnapshot()
+ XCTAssertEqual(person.name.value, personSnapshot1.name)
+ XCTAssertEqual(person.title.value, personSnapshot1.title)
+ XCTAssertEqual(person.displayName.value, personSnapshot1.displayName)
+
person.title .= "Sir"
XCTAssertEqual(person.displayName.value, "Sir John")
+ XCTAssertEqual(personSnapshot1.name, "John")
+ XCTAssertEqual(personSnapshot1.title, "Mr.")
+ XCTAssertEqual(personSnapshot1.displayName, "Mr. John")
+
+ let personSnapshot2 = person.createSnapshot()
+ XCTAssertEqual(person.name.value, personSnapshot2.name)
+ XCTAssertEqual(person.title.value, personSnapshot2.title)
+ XCTAssertEqual(person.displayName.value, personSnapshot2.displayName)
+
person.pets.value.insert(dog)
XCTAssertEqual(person.pets.count, 1)
XCTAssertEqual(person.pets.value.first, dog)
@@ -337,7 +353,7 @@ class DynamicModelTests: BaseTestDataTestCase {
SQLiteStore(
fileURL: SQLiteStore.defaultRootDirectory
.appendingPathComponent(UUID().uuidString)
- .appendingPathComponent("\(type(of: self))_\((configuration ?? "-null-")).sqlite"),
+ .appendingPathComponent("\(Self.self)_\((configuration ?? "-null-")).sqlite"),
configuration: configuration,
localStorageOptions: .recreateStoreOnModelMismatch
)
diff --git a/CoreStoreTests/ErrorTests.swift b/CoreStoreTests/ErrorTests.swift
index 46f1747..14870b7 100644
--- a/CoreStoreTests/ErrorTests.swift
+++ b/CoreStoreTests/ErrorTests.swift
@@ -88,7 +88,7 @@ final class ErrorTests: XCTestCase {
let schemaHistory = SchemaHistory(
XcodeDataModelSchema.from(
modelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
)
let version = "1.0.0"
diff --git a/CoreStoreTests/SetupTests.swift b/CoreStoreTests/SetupTests.swift
index b053c00..e81110b 100644
--- a/CoreStoreTests/SetupTests.swift
+++ b/CoreStoreTests/SetupTests.swift
@@ -39,7 +39,7 @@ class SetupTests: BaseTestDataTestCase {
let schemaHistory = SchemaHistory(
XcodeDataModelSchema.from(
modelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
)
let stack = DataStack(schemaHistory: schemaHistory)
@@ -68,7 +68,7 @@ class SetupTests: BaseTestDataTestCase {
DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self)),
+ bundle: Bundle(for: Self.self),
migrationChain: migrationChain
)
}
@@ -85,7 +85,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
do {
@@ -140,7 +140,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
do {
@@ -208,7 +208,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
try! stack.addStorageAndWait(sqliteStore)
self.prepareTestDataForStack(stack)
@@ -227,7 +227,7 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore()
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata,
@@ -260,7 +260,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
do {
@@ -328,7 +328,7 @@ class SetupTests: BaseTestDataTestCase {
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
try! stack.addStorageAndWait(
SQLiteStore.legacy(
@@ -354,7 +354,7 @@ class SetupTests: BaseTestDataTestCase {
let metadata = try createStore()
let stack = DataStack(
xcodeModelName: "Model",
- bundle: Bundle(for: type(of: self))
+ bundle: Bundle(for: Self.self)
)
try sqliteStore.cs_eraseStorageAndWait(
metadata: metadata,
diff --git a/CoreStoreTests/StorageInterfaceTests.swift b/CoreStoreTests/StorageInterfaceTests.swift
index fbccad7..ef94b85 100644
--- a/CoreStoreTests/StorageInterfaceTests.swift
+++ b/CoreStoreTests/StorageInterfaceTests.swift
@@ -112,7 +112,7 @@ final class StorageInterfaceTests: XCTestCase {
.appendingPathExtension("db")
let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2",
- mappingModelBundle: Bundle(for: type(of: self))
+ mappingModelBundle: Bundle(for: Self.self)
)
let store = SQLiteStore(
@@ -150,7 +150,7 @@ final class StorageInterfaceTests: XCTestCase {
let fileName = UUID().uuidString + ".db"
let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2",
- mappingModelBundle: Bundle(for: type(of: self))
+ mappingModelBundle: Bundle(for: Self.self)
)
let store = SQLiteStore(
fileName: fileName,
@@ -236,7 +236,7 @@ final class StorageInterfaceTests: XCTestCase {
let fileName = UUID().uuidString + ".db"
let mappingProvider = XcodeSchemaMappingProvider(
from: "V1", to: "V2",
- mappingModelBundle: Bundle(for: type(of: self))
+ mappingModelBundle: Bundle(for: Self.self)
)
let store = SQLiteStore.legacy(
fileName: fileName,
diff --git a/Playground_iOS.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Playground_iOS.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Playground_iOS.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/README.md b/README.md
index 327dff0..c355c14 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
Unleashing the real power of Core Data with the elegance and safety of Swift
-
+
diff --git a/Sources/AttributeProtocol.swift b/Sources/AttributeProtocol.swift
index 9223daa..0890817 100644
--- a/Sources/AttributeProtocol.swift
+++ b/Sources/AttributeProtocol.swift
@@ -44,4 +44,5 @@ internal protocol AttributeProtocol: AnyObject {
var rawObject: CoreStoreManagedObject? { get set }
var getter: CoreStoreManagedObject.CustomGetter? { get }
var setter: CoreStoreManagedObject.CustomSetter? { get }
+ var valueForSnapshot: Any { get }
}
diff --git a/Sources/BaseDataTransaction+Importing.swift b/Sources/BaseDataTransaction+Importing.swift
index 37b8655..6bd3f47 100644
--- a/Sources/BaseDataTransaction+Importing.swift
+++ b/Sources/BaseDataTransaction+Importing.swift
@@ -80,7 +80,7 @@ extension BaseDataTransaction {
try autoreleasepool {
- let entityType = cs_dynamicType(of: object)
+ let entityType = object.runtimeType()
guard entityType.shouldInsert(from: source, in: self) else {
return
diff --git a/Sources/CSAsynchronousDataTransaction.swift b/Sources/CSAsynchronousDataTransaction.swift
index 80ad0fc..ab58ab4 100644
--- a/Sources/CSAsynchronousDataTransaction.swift
+++ b/Sources/CSAsynchronousDataTransaction.swift
@@ -72,7 +72,7 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction, CoreSto
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSDataStack.swift b/Sources/CSDataStack.swift
index 55d8344..dd659fd 100644
--- a/Sources/CSDataStack.swift
+++ b/Sources/CSDataStack.swift
@@ -191,7 +191,7 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSError.swift b/Sources/CSError.swift
index 1420729..8ee149b 100644
--- a/Sources/CSError.swift
+++ b/Sources/CSError.swift
@@ -64,7 +64,7 @@ public final class CSError: NSError, CoreStoreObjectiveCType {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
@@ -274,7 +274,7 @@ extension Error {
case let error as CSError:
return error.bridgeToSwift
- case let error as NSError where type(of: self) is NSError.Type:
+ case let error as NSError where Self.self is NSError.Type:
return .internalError(NSError: error)
default:
diff --git a/Sources/CSFrom.swift b/Sources/CSFrom.swift
index 155b6cb..c9238fb 100644
--- a/Sources/CSFrom.swift
+++ b/Sources/CSFrom.swift
@@ -137,7 +137,7 @@ public final class CSFrom: NSObject {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSGroupBy.swift b/Sources/CSGroupBy.swift
index 54e9add..73c19dc 100644
--- a/Sources/CSGroupBy.swift
+++ b/Sources/CSGroupBy.swift
@@ -87,7 +87,7 @@ public final class CSGroupBy: NSObject, CSQueryClause {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSInMemoryStore.swift b/Sources/CSInMemoryStore.swift
index 72a1b9b..341dc45 100644
--- a/Sources/CSInMemoryStore.swift
+++ b/Sources/CSInMemoryStore.swift
@@ -103,7 +103,7 @@ public final class CSInMemoryStore: NSObject, CSStorageInterface, CoreStoreObjec
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSInto.swift b/Sources/CSInto.swift
index 420d4a6..9c0203b 100644
--- a/Sources/CSInto.swift
+++ b/Sources/CSInto.swift
@@ -104,7 +104,7 @@ public final class CSInto: NSObject {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSListMonitor.swift b/Sources/CSListMonitor.swift
index f84e907..a5b3fae 100644
--- a/Sources/CSListMonitor.swift
+++ b/Sources/CSListMonitor.swift
@@ -526,7 +526,7 @@ public final class CSListMonitor: NSObject {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSMigrationResult.swift b/Sources/CSMigrationResult.swift
index 8baca2b..c3e1cb0 100644
--- a/Sources/CSMigrationResult.swift
+++ b/Sources/CSMigrationResult.swift
@@ -155,7 +155,7 @@ public final class CSMigrationResult: NSObject, CoreStoreObjectiveCType {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSMigrationType.swift b/Sources/CSMigrationType.swift
index 61d5986..c643856 100644
--- a/Sources/CSMigrationType.swift
+++ b/Sources/CSMigrationType.swift
@@ -101,7 +101,7 @@ public final class CSMigrationType: NSObject, CoreStoreObjectiveCType {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSObjectMonitor.swift b/Sources/CSObjectMonitor.swift
index 6776513..a0e7561 100644
--- a/Sources/CSObjectMonitor.swift
+++ b/Sources/CSObjectMonitor.swift
@@ -119,7 +119,7 @@ public final class CSObjectMonitor: NSObject {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSOrderBy.swift b/Sources/CSOrderBy.swift
index 2c97a89..cb094f8 100644
--- a/Sources/CSOrderBy.swift
+++ b/Sources/CSOrderBy.swift
@@ -95,7 +95,7 @@ public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteCl
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSSQliteStore.swift b/Sources/CSSQliteStore.swift
index e84e29b..4611b6b 100644
--- a/Sources/CSSQliteStore.swift
+++ b/Sources/CSSQliteStore.swift
@@ -178,7 +178,7 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSSectionBy.swift b/Sources/CSSectionBy.swift
index a96a871..c94cd2a 100644
--- a/Sources/CSSectionBy.swift
+++ b/Sources/CSSectionBy.swift
@@ -68,7 +68,7 @@ public final class CSSectionBy: NSObject {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSSelect.swift b/Sources/CSSelect.swift
index 2a8c105..fd910a4 100644
--- a/Sources/CSSelect.swift
+++ b/Sources/CSSelect.swift
@@ -377,7 +377,7 @@ public final class CSSelect: NSObject {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSSetupResult.swift b/Sources/CSSetupResult.swift
index f4a32a9..1e66b13 100644
--- a/Sources/CSSetupResult.swift
+++ b/Sources/CSSetupResult.swift
@@ -146,7 +146,7 @@ public final class CSSetupResult: NSObject {
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSSynchronousDataTransaction.swift b/Sources/CSSynchronousDataTransaction.swift
index 4ef6205..4874226 100644
--- a/Sources/CSSynchronousDataTransaction.swift
+++ b/Sources/CSSynchronousDataTransaction.swift
@@ -60,7 +60,7 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction, CoreStor
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSTweak.swift b/Sources/CSTweak.swift
index 11cbf83..39324c7 100644
--- a/Sources/CSTweak.swift
+++ b/Sources/CSTweak.swift
@@ -63,7 +63,7 @@ public final class CSTweak: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSUnsafeDataModelSchema.swift b/Sources/CSUnsafeDataModelSchema.swift
index 660782d..08552d6 100644
--- a/Sources/CSUnsafeDataModelSchema.swift
+++ b/Sources/CSUnsafeDataModelSchema.swift
@@ -71,7 +71,7 @@ public final class CSUnsafeDataModelSchema: NSObject, CSDynamicSchema, CoreStore
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSUnsafeDataTransaction.swift b/Sources/CSUnsafeDataTransaction.swift
index b2a7e9d..10b610c 100644
--- a/Sources/CSUnsafeDataTransaction.swift
+++ b/Sources/CSUnsafeDataTransaction.swift
@@ -181,7 +181,7 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction, CoreStoreObje
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSWhere.swift b/Sources/CSWhere.swift
index e631c70..7cb0f7c 100644
--- a/Sources/CSWhere.swift
+++ b/Sources/CSWhere.swift
@@ -134,7 +134,7 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CSXcodeDataModelSchema.swift b/Sources/CSXcodeDataModelSchema.swift
index ce8431c..d630ae2 100644
--- a/Sources/CSXcodeDataModelSchema.swift
+++ b/Sources/CSXcodeDataModelSchema.swift
@@ -71,7 +71,7 @@ public final class CSXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreO
public override var description: String {
- return "(\(String(reflecting: type(of: self)))) \(self.bridgeToSwift.coreStoreDumpString)"
+ return "(\(String(reflecting: Self.self))) \(self.bridgeToSwift.coreStoreDumpString)"
}
diff --git a/Sources/CoreStore+CustomDebugStringConvertible.swift b/Sources/CoreStore+CustomDebugStringConvertible.swift
index 894932a..4502f4b 100644
--- a/Sources/CoreStore+CustomDebugStringConvertible.swift
+++ b/Sources/CoreStore+CustomDebugStringConvertible.swift
@@ -116,7 +116,7 @@ extension CoreStoreError: CustomDebugStringConvertible, CoreStoreDebugStringConv
let firstLine: String
var info: DumpInfo = [
- ("errorDomain", type(of: self).errorDomain),
+ ("errorDomain", Self.errorDomain),
("errorCode", self.errorCode),
]
switch self {
diff --git a/Sources/CoreStoreObject.swift b/Sources/CoreStoreObject.swift
index 228ee58..560198e 100644
--- a/Sources/CoreStoreObject.swift
+++ b/Sources/CoreStoreObject.swift
@@ -69,7 +69,10 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
self.isMeta = false
self.rawObject = (rawObject as! CoreStoreManagedObject)
- self.initializeAttributes(Mirror(reflecting: self), self)
+ self.registerReceiver(
+ mirror: Mirror(reflecting: self),
+ object: self
+ )
}
/**
@@ -93,7 +96,7 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
}
if lhs.isMeta {
- return cs_dynamicType(of: lhs) == cs_dynamicType(of: rhs)
+ return lhs.runtimeType() == rhs.runtimeType()
}
return lhs.rawObject!.isEqual(rhs.rawObject!)
}
@@ -117,18 +120,24 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
// MARK: Private
- private func initializeAttributes(_ mirror: Mirror, _ parentObject: CoreStoreObject) {
+ private func registerReceiver(mirror: Mirror, object: CoreStoreObject) {
- _ = mirror.superclassMirror.flatMap({ self.initializeAttributes($0, parentObject) })
+ if let superclassMirror = mirror.superclassMirror {
+
+ self.registerReceiver(
+ mirror: superclassMirror,
+ object: object
+ )
+ }
for child in mirror.children {
switch child.value {
case let property as AttributeProtocol:
- property.rawObject = parentObject.rawObject
+ property.rawObject = object.rawObject
case let property as RelationshipProtocol:
- property.rawObject = parentObject.rawObject
+ property.rawObject = object.rawObject
default:
continue
@@ -158,14 +167,14 @@ extension DynamicObject where Self: CoreStoreObject {
// MARK: Internal
internal static var meta: Self {
-
- let key = ObjectIdentifier(self)
- if case let meta as Self = Static.metaCache[key] {
-
+
+ let cacheKey = ObjectIdentifier(self)
+ if case let meta as Self = Static.metaCache[cacheKey] {
+
return meta
}
let meta = self.init(asMeta: ())
- Static.metaCache[key] = meta
+ Static.metaCache[cacheKey] = meta
return meta
}
}
@@ -174,6 +183,8 @@ extension DynamicObject where Self: CoreStoreObject {
// MARK: - Static
fileprivate enum Static {
-
+
+ // MARK: FilePrivate
+
fileprivate static var metaCache: [ObjectIdentifier: Any] = [:]
}
diff --git a/Sources/CustomSchemaMappingProvider.swift b/Sources/CustomSchemaMappingProvider.swift
index 9dc5a9b..5875209 100644
--- a/Sources/CustomSchemaMappingProvider.swift
+++ b/Sources/CustomSchemaMappingProvider.swift
@@ -328,7 +328,6 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
return lhs.sourceVersion == rhs.sourceVersion
&& lhs.destinationVersion == rhs.destinationVersion
- && cs_dynamicType(of: lhs) == cs_dynamicType(of: rhs)
}
@@ -338,7 +337,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
hasher.combine(self.sourceVersion)
hasher.combine(self.destinationVersion)
- hasher.combine(ObjectIdentifier(cs_dynamicType(of: self)))
+ hasher.combine(ObjectIdentifier(Self.self))
}
diff --git a/Sources/DynamicObject.swift b/Sources/DynamicObject.swift
index 923ea43..2cc3e5b 100644
--- a/Sources/DynamicObject.swift
+++ b/Sources/DynamicObject.swift
@@ -60,6 +60,17 @@ public protocol DynamicObject: AnyObject {
func cs_toRaw() -> NSManagedObject
}
+extension DynamicObject {
+
+ // MARK: Internal
+
+ internal func runtimeType() -> Self.Type {
+
+ // Self.self does not return runtime-created types
+ return object_getClass(self)! as! Self.Type
+ }
+}
+
// MARK: - NSManagedObject
@@ -98,6 +109,16 @@ extension NSManagedObject: DynamicObject {
}
}
+extension DynamicObject where Self: NSManagedObject {
+
+ // MARK: Public
+
+ public func createSnapshot() -> ObjectSnapshot {
+
+ return ObjectSnapshot(from: self)
+ }
+}
+
// MARK: - CoreStoreObject
@@ -150,3 +171,13 @@ extension CoreStoreObject {
return self.rawObject!
}
}
+
+extension DynamicObject where Self: CoreStoreObject {
+
+ // MARK: Public
+
+ public func createSnapshot() -> ObjectSnapshot {
+
+ return ObjectSnapshot(from: self)
+ }
+}
diff --git a/Sources/Functions.swift b/Sources/Functions.swift
index 7cc83dc..0bfc8cd 100644
--- a/Sources/Functions.swift
+++ b/Sources/Functions.swift
@@ -27,15 +27,6 @@ import Foundation
// MARK: Associated Objects
-@inline(__always)
-/// type(of:) doesn't return the dynamic type anymore, use this to guarantee correct dispatch of class methods
-internal func cs_dynamicType(of instance: T) -> T.Type {
-
- return object_getClass(instance) as! T.Type
-}
-
-// MARK: Associated Objects
-
@inline(__always)
internal func cs_getAssociatedObjectForKey(_ key: UnsafeRawPointer, inObject object: Any) -> T? {
diff --git a/Sources/ImportableUniqueObject.swift b/Sources/ImportableUniqueObject.swift
index db8b915..0bdb246 100644
--- a/Sources/ImportableUniqueObject.swift
+++ b/Sources/ImportableUniqueObject.swift
@@ -125,7 +125,7 @@ extension ImportableUniqueObject where UniqueIDType.QueryableNativeType: CoreDat
get {
return self.cs_toRaw().getValue(
- forKvcKey: cs_dynamicType(of: self).uniqueIDKeyPath,
+ forKvcKey: Self.uniqueIDKeyPath,
didGetValue: { UniqueIDType.cs_fromQueryableNativeType($0 as! UniqueIDType.QueryableNativeType)! }
)
}
@@ -134,7 +134,7 @@ extension ImportableUniqueObject where UniqueIDType.QueryableNativeType: CoreDat
self.cs_toRaw()
.setValue(
newValue,
- forKvcKey: cs_dynamicType(of: self).uniqueIDKeyPath,
+ forKvcKey: Self.uniqueIDKeyPath,
willSetValue: { ($0.cs_toQueryableNativeType() as CoreDataNativeType) }
)
}
diff --git a/Sources/InferredSchemaMappingProvider.swift b/Sources/InferredSchemaMappingProvider.swift
index db14b59..3f10a8a 100644
--- a/Sources/InferredSchemaMappingProvider.swift
+++ b/Sources/InferredSchemaMappingProvider.swift
@@ -47,7 +47,7 @@ public final class InferredSchemaMappingProvider: Hashable, SchemaMappingProvide
public func hash(into hasher: inout Hasher) {
- hasher.combine(ObjectIdentifier(type(of: self)))
+ hasher.combine(ObjectIdentifier(Self.self))
}
diff --git a/Sources/NSManagedObjectContext+Querying.swift b/Sources/NSManagedObjectContext+Querying.swift
index b7d655c..0d444b8 100644
--- a/Sources/NSManagedObjectContext+Querying.swift
+++ b/Sources/NSManagedObjectContext+Querying.swift
@@ -62,7 +62,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
return object
}
- return cs_dynamicType(of: object).cs_fromRaw(object: existingRawObject)
+ return object.runtimeType().cs_fromRaw(object: existingRawObject)
}
catch {
diff --git a/Sources/ObjectSnapshot.swift b/Sources/ObjectSnapshot.swift
new file mode 100644
index 0000000..4f60e45
--- /dev/null
+++ b/Sources/ObjectSnapshot.swift
@@ -0,0 +1,143 @@
+//
+// ObjectSnapshot.swift
+// CoreStore
+//
+// Copyright © 2018 John Rommel Estropia
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+//
+
+import CoreData
+import Foundation
+
+
+// MARK: - ObjectSnapshot
+
+/**
+ An `ObjectSnapshot` contains "snapshot" values from a `DynamicObject` instance copied at a specific point in time.
+ */
+@dynamicMemberLookup
+public struct ObjectSnapshot {
+
+ // MARK: FilePrivate
+
+ fileprivate var attributes: [KeyPathString: Any]
+
+ // MARK: Private
+
+ private init() {
+
+ self.attributes = [:]
+ }
+}
+
+// MARK: - ObjectSnapshot where O: NSManagedObject
+
+extension ObjectSnapshot where O: NSManagedObject {
+
+ /**
+ Initializes an `ObjectSnapshot` instance by copying all attribute values from the given `NSManagedObject`.
+ */
+ public init(from object: O) {
+
+ self.attributes = object.dictionaryWithValues(
+ forKeys: Array(object.entity.attributesByName.keys)
+ )
+ }
+
+ /**
+ Returns the value for the property identified by a given key.
+ */
+ public subscript(dynamicMember member: KeyPath) -> V {
+
+ get {
+
+ let key = String(keyPath: member)
+ return self.attributes[key]! as! V
+ }
+ set {
+
+ let key = String(keyPath: member)
+ self.attributes[key] = newValue
+ }
+ }
+}
+
+
+// MARK: - ObjectSnapshot where O: CoreStoreObject
+
+extension ObjectSnapshot where O: CoreStoreObject {
+
+ /**
+ Initializes an `ObjectSnapshot` instance by copying all attribute values from the given `CoreStoreObject`.
+ */
+ public init(from object: O) {
+
+ var attributes: [KeyPathString: Any] = [:]
+ Self.initializeAttributes(
+ mirror: Mirror(reflecting: object),
+ object: object,
+ into: &attributes
+ )
+ self.attributes = attributes
+ }
+
+ /**
+ Returns the value for the property identified by a given key.
+ */
+ public subscript(dynamicMember member: KeyPath) -> K.ReturnValueType {
+
+ get {
+
+ let key = String(keyPath: member)
+ return self.attributes[key]! as! K.ReturnValueType
+ }
+ set {
+
+ let key = String(keyPath: member)
+ self.attributes[key] = newValue
+ }
+ }
+
+
+ // MARK: Private
+
+ private static func initializeAttributes(mirror: Mirror, object: CoreStoreObject, into attributes: inout [KeyPathString: Any]) {
+
+ if let superClassMirror = mirror.superclassMirror {
+
+ self.initializeAttributes(
+ mirror: superClassMirror,
+ object: object,
+ into: &attributes
+ )
+ }
+ for child in mirror.children {
+
+ switch child.value {
+
+ case let property as AttributeProtocol:
+ attributes[property.keyPath] = property.valueForSnapshot
+
+ default:
+ continue
+ }
+ }
+ }
+}
diff --git a/Sources/SQLiteStore.swift b/Sources/SQLiteStore.swift
index 867a7f8..fc43f8b 100644
--- a/Sources/SQLiteStore.swift
+++ b/Sources/SQLiteStore.swift
@@ -223,7 +223,7 @@ public final class SQLiteStore: LocalStorage {
var storeOptions = self.storeOptions ?? [:]
storeOptions[NSSQLitePragmasOption] = ["journal_mode": "DELETE"]
try coordinator.addPersistentStore(
- ofType: type(of: self).storeType,
+ ofType: Self.storeType,
configurationName: self.configuration,
at: fileURL,
options: storeOptions
@@ -289,7 +289,7 @@ public final class SQLiteStore: LocalStorage {
var storeOptions = self.storeOptions ?? [:]
storeOptions[NSSQLitePragmasOption] = ["journal_mode": "DELETE"]
let store = try journalUpdatingCoordinator.addPersistentStore(
- ofType: type(of: self).storeType,
+ ofType: Self.storeType,
configurationName: self.configuration,
at: fileURL,
options: storeOptions
diff --git a/Sources/StorageInterface.swift b/Sources/StorageInterface.swift
index 441e47d..14787c8 100644
--- a/Sources/StorageInterface.swift
+++ b/Sources/StorageInterface.swift
@@ -156,7 +156,7 @@ extension LocalStorage {
internal func matchesPersistentStore(_ persistentStore: NSPersistentStore) -> Bool {
- return persistentStore.type == type(of: self).storeType
+ return persistentStore.type == Self.storeType
&& persistentStore.configurationName == (self.configuration ?? DataStack.defaultConfigurationName)
&& persistentStore.url == self.fileURL
}
@@ -243,7 +243,7 @@ extension CloudStorage {
internal func matchesPersistentStore(_ persistentStore: NSPersistentStore) -> Bool {
- guard persistentStore.type == type(of: self).storeType
+ guard persistentStore.type == Self.storeType
&& persistentStore.configurationName == (self.configuration ?? DataStack.defaultConfigurationName) else {
return false
diff --git a/Sources/Transformable.swift b/Sources/Transformable.swift
index 3f27575..267d6c4 100644
--- a/Sources/Transformable.swift
+++ b/Sources/Transformable.swift
@@ -267,6 +267,10 @@ public enum TransformableContainer {
)
}
}
+
+ internal var valueForSnapshot: Any {
+ return self.value
+ }
// MARK: Private
@@ -480,6 +484,10 @@ public enum TransformableContainer {
)
}
}
+
+ internal var valueForSnapshot: Any {
+ return self.value as Any
+ }
// MARK: Private
diff --git a/Sources/Value.swift b/Sources/Value.swift
index 6945299..348cb2c 100644
--- a/Sources/Value.swift
+++ b/Sources/Value.swift
@@ -263,6 +263,10 @@ public enum ValueContainer {
}
}
+ internal var valueForSnapshot: Any {
+ return self.value
+ }
+
// MARK: Private
@@ -476,6 +480,10 @@ public enum ValueContainer {
}
}
+ internal var valueForSnapshot: Any {
+ return self.value as Any
+ }
+
// MARK: Private
diff --git a/bitrise.yml b/bitrise.yml
new file mode 100644
index 0000000..99ac7f5
--- /dev/null
+++ b/bitrise.yml
@@ -0,0 +1,103 @@
+---
+format_version: '7'
+default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
+project_type: ios
+trigger_map:
+- push_branch: "*"
+ workflow: ci
+- pull_request_source_branch: "*"
+ workflow: ci
+workflows:
+ ci:
+ steps:
+ - activate-ssh-key:
+ run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
+ - git-clone: {}
+ - cache-pull: {}
+ - certificate-and-profile-installer: {}
+ ################ PLATFORM = tvOS
+ - xcode-test:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore tvOS"
+ - is_clean_build: "yes"
+ - xcodebuild_test_options: "-configuration Debug"
+ - simulator_platform: "tvOS Simulator"
+ - simulator_device: "Apple TV"
+ - should_retry_test_on_fail: "yes"
+ - xcode-test:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore tvOS"
+ - is_clean_build: "yes"
+ - xcodebuild_test_options: "-configuration Release"
+ - simulator_platform: "tvOS Simulator"
+ - simulator_device: "Apple TV"
+ - should_retry_test_on_fail: "yes"
+ - xcode-test:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore tvOS"
+ - is_clean_build: "yes"
+ - simulator_platform: "tvOS Simulator"
+ - simulator_device: "Apple TV 4K"
+ - should_retry_test_on_fail: "yes"
+ - xcode-test:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore tvOS"
+ - is_clean_build: "yes"
+ - simulator_platform: "tvOS Simulator"
+ - simulator_device: "Apple TV 4K (at 1080p)"
+ - should_retry_test_on_fail: "yes"
+ ################ PLATFORM = iOS
+ - xcode-test:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore iOS"
+ - is_clean_build: "yes"
+ - simulator_platform: "iOS Simulator"
+ - simulator_device: "iPhone XS"
+ - simulator_os_version: "12.0"
+ - should_retry_test_on_fail: "yes"
+ - xcode-test:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore iOS"
+ - is_clean_build: "yes"
+ - simulator_platform: "iOS Simulator"
+ - simulator_device: "iPhone 8"
+ - simulator_os_version: "11.4"
+ - should_retry_test_on_fail: "yes"
+ - xcode-test:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore iOS"
+ - is_clean_build: "yes"
+ - simulator_platform: "iOS Simulator"
+ - simulator_device: "iPhone 7"
+ - simulator_os_version: "10.3.1"
+ - should_retry_test_on_fail: "yes"
+ ################ PLATFORM = macOS
+ - xcode-test-mac:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore OSX"
+ - is_clean_build: "yes"
+ - xcodebuild_test_options: "-configuration Debug"
+ - destination: "platform=macos,arch=x86_64"
+ - should_retry_test_on_fail: "yes"
+ - xcode-test-mac:
+ inputs:
+ - project_path: "$BITRISE_PROJECT_PATH"
+ - scheme: "CoreStore OSX"
+ - is_clean_build: "yes"
+ - xcodebuild_test_options: "-configuration Release"
+ - destination: "platform=macos,arch=x86_64"
+ - should_retry_test_on_fail: "yes"
+ - cache-push: {}
+app:
+ envs:
+ - opts:
+ is_expand: false
+ BITRISE_PROJECT_PATH: CoreStore.xcworkspace