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

-Build Status +Build Status Last Commit Platform License 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