mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-26 11:21:32 +01:00
WIP: new PartialObject to act as faster KVC wrappers when implementing custom getters and setters for CoreStoreObject
This commit is contained in:
@@ -242,6 +242,10 @@
|
|||||||
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||||
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||||
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||||
|
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||||
|
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||||
|
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||||
|
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||||
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||||
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||||
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||||
@@ -757,6 +761,7 @@
|
|||||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
|
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
|
||||||
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
||||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
|
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
|
||||||
|
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PartialObject.swift; sourceTree = "<group>"; };
|
||||||
B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = "<group>"; };
|
B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = "<group>"; };
|
||||||
B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = "<group>"; };
|
B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = "<group>"; };
|
||||||
B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = "<group>"; };
|
B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = "<group>"; };
|
||||||
@@ -1229,6 +1234,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */,
|
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */,
|
||||||
|
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */,
|
||||||
B52F74391E9B8724005F3DAC /* Dynamic Schema */,
|
B52F74391E9B8724005F3DAC /* Dynamic Schema */,
|
||||||
B5D339DC1E9489C700C880DE /* DynamicObject.swift */,
|
B5D339DC1E9489C700C880DE /* DynamicObject.swift */,
|
||||||
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */,
|
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */,
|
||||||
@@ -1826,6 +1832,7 @@
|
|||||||
B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */,
|
B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */,
|
||||||
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
|
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
|
||||||
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||||
|
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||||
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
||||||
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
||||||
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
@@ -2011,6 +2018,7 @@
|
|||||||
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
|
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
|
||||||
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
|
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
|
||||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||||
|
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||||
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
||||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||||
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
@@ -2196,6 +2204,7 @@
|
|||||||
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
|
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
|
||||||
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||||
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
||||||
|
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||||
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
||||||
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||||
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
@@ -2381,6 +2390,7 @@
|
|||||||
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
|
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
|
||||||
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||||
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
||||||
|
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||||
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||||
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||||
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||||
|
|||||||
@@ -135,3 +135,23 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - DynamicObject where Self: CoreStoreObject
|
||||||
|
|
||||||
|
public extension DynamicObject where Self: CoreStoreObject {
|
||||||
|
|
||||||
|
public func partialObject() -> PartialObject<Self> {
|
||||||
|
|
||||||
|
CoreStore.assert(
|
||||||
|
!self.isMeta,
|
||||||
|
"Attempted to create a \(cs_typeName(PartialObject<Self>.self)) from a meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||||
|
)
|
||||||
|
return PartialObject<Self>(self.rawObject!)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static var meta: Self {
|
||||||
|
|
||||||
|
return self.init(asMeta: ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -155,14 +155,3 @@ extension CoreStoreObject {
|
|||||||
return self.rawObject!
|
return self.rawObject!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Internal
|
|
||||||
|
|
||||||
internal extension DynamicObject where Self: CoreStoreObject {
|
|
||||||
|
|
||||||
internal static var meta: Self {
|
|
||||||
|
|
||||||
return self.init(asMeta: ())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
135
Sources/PartialObject.swift
Normal file
135
Sources/PartialObject.swift
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
//
|
||||||
|
// PartialObject.swift
|
||||||
|
// CoreStore
|
||||||
|
//
|
||||||
|
// Copyright © 2017 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: - PartialObject
|
||||||
|
|
||||||
|
public struct PartialObject<O: CoreStoreObject> {
|
||||||
|
|
||||||
|
public func completeObject() -> O {
|
||||||
|
|
||||||
|
return O.cs_fromRaw(object: self.rawObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func value<V: ImportableAttributeType>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
|
||||||
|
|
||||||
|
return V.cs_fromImportableNativeType(
|
||||||
|
self.rawObject.value(forKey: property(O.meta).keyPath)! as! V.ImportableNativeType
|
||||||
|
)!
|
||||||
|
}
|
||||||
|
|
||||||
|
public func value<V: ImportableAttributeType>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
|
||||||
|
|
||||||
|
return (self.rawObject.value(forKey: property(O.meta).keyPath) as! V.ImportableNativeType?)
|
||||||
|
.flatMap(V.cs_fromImportableNativeType)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func value<V: NSCoding & NSCopying>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
|
||||||
|
|
||||||
|
return self.rawObject.value(forKey: property(O.meta).keyPath)! as! V
|
||||||
|
}
|
||||||
|
|
||||||
|
public func value<V: NSCoding & NSCopying>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
|
||||||
|
|
||||||
|
return self.rawObject.value(forKey: property(O.meta).keyPath) as! V?
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setValue<V: ImportableAttributeType>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setValue(
|
||||||
|
value.cs_toImportableNativeType(),
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setValue<V: ImportableAttributeType>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setValue(
|
||||||
|
value?.cs_toImportableNativeType(),
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setValue<V: NSCoding & NSCopying>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setValue(
|
||||||
|
value,
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setValue<V: NSCoding & NSCopying>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setValue(
|
||||||
|
value,
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setPrimitiveValue<V: ImportableAttributeType>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setPrimitiveValue(
|
||||||
|
value.cs_toImportableNativeType(),
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setPrimitiveValue<V: ImportableAttributeType>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setPrimitiveValue(
|
||||||
|
value?.cs_toImportableNativeType(),
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setPrimitiveValue<V: NSCoding & NSCopying>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setPrimitiveValue(
|
||||||
|
value,
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setPrimitiveValue<V: NSCoding & NSCopying>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
|
||||||
|
|
||||||
|
self.rawObject.setPrimitiveValue(
|
||||||
|
value,
|
||||||
|
forKey: property(O.meta).keyPath
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: Internal
|
||||||
|
|
||||||
|
internal let rawObject: NSManagedObject
|
||||||
|
|
||||||
|
internal init(_ rawObject: NSManagedObject) {
|
||||||
|
|
||||||
|
self.rawObject = rawObject
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -123,8 +123,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
isTransient: Bool = false,
|
isTransient: Bool = false,
|
||||||
versionHashModifier: String? = nil,
|
versionHashModifier: String? = nil,
|
||||||
renamingIdentifier: String? = nil,
|
renamingIdentifier: String? = nil,
|
||||||
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
|
customGetter: ((_ partialObject: PartialObject<O>) -> V)? = nil,
|
||||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)? = nil,
|
||||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||||
|
|
||||||
self.keyPath = keyPath
|
self.keyPath = keyPath
|
||||||
@@ -155,16 +155,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||||
)
|
)
|
||||||
let customGetter = (self.customGetter ?? { $1() })
|
if let customGetter = self.customGetter {
|
||||||
return customGetter(
|
|
||||||
object,
|
|
||||||
{ () -> V in
|
|
||||||
|
|
||||||
return V.cs_fromImportableNativeType(
|
return customGetter(PartialObject<O>(object.rawObject!))
|
||||||
object.rawObject!.value(forKey: self.keyPath)! as! V.ImportableNativeType
|
}
|
||||||
)!
|
return V.cs_fromImportableNativeType(
|
||||||
}
|
object.rawObject!.value(forKey: self.keyPath)! as! V.ImportableNativeType
|
||||||
)
|
)!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
@@ -183,17 +180,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
object.rawObject!.isEditableInContext() == true,
|
object.rawObject!.isEditableInContext() == true,
|
||||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||||
)
|
)
|
||||||
let customSetter = (self.customSetter ?? { $1($2) })
|
if let customSetter = self.customSetter {
|
||||||
customSetter(
|
|
||||||
object,
|
|
||||||
{ (newValue: V) -> Void in
|
|
||||||
|
|
||||||
object.rawObject!.setValue(
|
return customSetter(PartialObject<O>(object.rawObject!), newValue)
|
||||||
newValue.cs_toImportableNativeType(),
|
}
|
||||||
forKey: self.keyPath
|
return object.rawObject!.setValue(
|
||||||
)
|
newValue.cs_toImportableNativeType(),
|
||||||
},
|
forKey: self.keyPath
|
||||||
newValue
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,15 +267,12 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
return { (_ id: Any) -> Any? in
|
return { (_ id: Any) -> Any? in
|
||||||
|
|
||||||
let rawObject = id as! CoreStoreManagedObject
|
let rawObject = id as! CoreStoreManagedObject
|
||||||
let value = customGetter(
|
rawObject.willAccessValue(forKey: keyPath)
|
||||||
O.cs_fromRaw(object: rawObject),
|
defer {
|
||||||
{
|
|
||||||
rawObject.getValue(
|
rawObject.didAccessValue(forKey: keyPath)
|
||||||
forKvcKey: keyPath,
|
}
|
||||||
didGetValue: { V.cs_fromImportableNativeType($0 as! V.ImportableNativeType!)! }
|
let value = customGetter(PartialObject<O>(rawObject))
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return value.cs_toImportableNativeType()
|
return value.cs_toImportableNativeType()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,16 +287,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
return { (_ id: Any, _ newValue: Any?) -> Void in
|
return { (_ id: Any, _ newValue: Any?) -> Void in
|
||||||
|
|
||||||
let rawObject = id as! CoreStoreManagedObject
|
let rawObject = id as! CoreStoreManagedObject
|
||||||
customSetter(
|
rawObject.willChangeValue(forKey: keyPath)
|
||||||
O.cs_fromRaw(object: rawObject),
|
defer {
|
||||||
{ (userValue: V) -> Void in
|
|
||||||
|
|
||||||
rawObject.setValue(
|
rawObject.didChangeValue(forKey: keyPath)
|
||||||
userValue,
|
}
|
||||||
forKvcKey: keyPath,
|
customSetter(
|
||||||
willSetValue: { $0.cs_toImportableNativeType() }
|
PartialObject<O>(rawObject),
|
||||||
)
|
|
||||||
},
|
|
||||||
V.cs_fromImportableNativeType(newValue as! V.ImportableNativeType)!
|
V.cs_fromImportableNativeType(newValue as! V.ImportableNativeType)!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -315,8 +302,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)?
|
private let customGetter: ((_ partialObject: PartialObject<O>) -> V)?
|
||||||
private let customSetter: ((_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void)?
|
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -370,8 +357,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
isTransient: Bool = false,
|
isTransient: Bool = false,
|
||||||
versionHashModifier: String? = nil,
|
versionHashModifier: String? = nil,
|
||||||
renamingIdentifier: String? = nil,
|
renamingIdentifier: String? = nil,
|
||||||
customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)? = nil,
|
customGetter: ((_ partialObject: PartialObject<O>) -> V?)? = nil,
|
||||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void)? = nil,
|
customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)? = nil,
|
||||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||||
|
|
||||||
self.keyPath = keyPath
|
self.keyPath = keyPath
|
||||||
@@ -402,15 +389,12 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
object.rawObject!.isRunningInAllowedQueue() == true,
|
object.rawObject!.isRunningInAllowedQueue() == true,
|
||||||
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
"Attempted to access \(cs_typeName(O.self))'s value outside it's designated queue."
|
||||||
)
|
)
|
||||||
let customGetter = (self.customGetter ?? { $1() })
|
if let customGetter = self.customGetter {
|
||||||
return customGetter(
|
|
||||||
object,
|
|
||||||
{ () -> V? in
|
|
||||||
|
|
||||||
return (object.rawObject!.value(forKey: self.keyPath) as! V.ImportableNativeType?)
|
return customGetter(PartialObject<O>(object.rawObject!))
|
||||||
.flatMap(V.cs_fromImportableNativeType)
|
}
|
||||||
}
|
return (object.rawObject!.value(forKey: self.keyPath) as! V.ImportableNativeType?)
|
||||||
)
|
.flatMap(V.cs_fromImportableNativeType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
@@ -429,17 +413,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
object.rawObject!.isEditableInContext() == true,
|
object.rawObject!.isEditableInContext() == true,
|
||||||
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
"Attempted to update a \(cs_typeName(O.self))'s value from outside a transaction."
|
||||||
)
|
)
|
||||||
let customSetter = (self.customSetter ?? { $1($2) })
|
if let customSetter = self.customSetter {
|
||||||
customSetter(
|
|
||||||
object,
|
|
||||||
{ (newValue: V?) -> Void in
|
|
||||||
|
|
||||||
object.rawObject!.setValue(
|
return customSetter(PartialObject<O>(object.rawObject!), newValue)
|
||||||
newValue?.cs_toImportableNativeType(),
|
}
|
||||||
forKey: self.keyPath
|
object.rawObject!.setValue(
|
||||||
)
|
newValue?.cs_toImportableNativeType(),
|
||||||
},
|
forKey: self.keyPath
|
||||||
newValue
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -518,15 +498,12 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
return { (_ id: Any) -> Any? in
|
return { (_ id: Any) -> Any? in
|
||||||
|
|
||||||
let rawObject = id as! CoreStoreManagedObject
|
let rawObject = id as! CoreStoreManagedObject
|
||||||
let value = customGetter(
|
rawObject.willAccessValue(forKey: keyPath)
|
||||||
O.cs_fromRaw(object: rawObject),
|
defer {
|
||||||
{
|
|
||||||
rawObject.getValue(
|
rawObject.didAccessValue(forKey: keyPath)
|
||||||
forKvcKey: keyPath,
|
}
|
||||||
didGetValue: { ($0 as! V.ImportableNativeType?).flatMap(V.cs_fromImportableNativeType) }
|
let value = customGetter(PartialObject<O>(rawObject))
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return value?.cs_toImportableNativeType()
|
return value?.cs_toImportableNativeType()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,16 +518,13 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
return { (_ id: Any, _ newValue: Any?) -> Void in
|
return { (_ id: Any, _ newValue: Any?) -> Void in
|
||||||
|
|
||||||
let rawObject = id as! CoreStoreManagedObject
|
let rawObject = id as! CoreStoreManagedObject
|
||||||
customSetter(
|
rawObject.willChangeValue(forKey: keyPath)
|
||||||
O.cs_fromRaw(object: rawObject),
|
defer {
|
||||||
{ (userValue: V?) -> Void in
|
|
||||||
|
|
||||||
rawObject.setValue(
|
rawObject.didChangeValue(forKey: keyPath)
|
||||||
userValue,
|
}
|
||||||
forKvcKey: keyPath,
|
customSetter(
|
||||||
willSetValue: { $0?.cs_toImportableNativeType() }
|
PartialObject<O>(rawObject),
|
||||||
)
|
|
||||||
},
|
|
||||||
(newValue as! V.ImportableNativeType?).flatMap(V.cs_fromImportableNativeType)
|
(newValue as! V.ImportableNativeType?).flatMap(V.cs_fromImportableNativeType)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -559,8 +533,8 @@ public enum ValueContainer<O: CoreStoreObject> {
|
|||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)?
|
private let customGetter: ((_ partialObject: PartialObject<O>) -> V?)?
|
||||||
private let customSetter: ((_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void)?
|
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,7 +567,7 @@ public extension ValueContainer.Required where V: EmptyableAttributeType {
|
|||||||
isTransient: Bool = false,
|
isTransient: Bool = false,
|
||||||
versionHashModifier: String? = nil,
|
versionHashModifier: String? = nil,
|
||||||
renamingIdentifier: String? = nil,
|
renamingIdentifier: String? = nil,
|
||||||
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
|
customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V) -> V)? = nil,
|
||||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
||||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||||
|
|
||||||
@@ -670,7 +644,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
isTransient: Bool = false,
|
isTransient: Bool = false,
|
||||||
versionHashModifier: String? = nil,
|
versionHashModifier: String? = nil,
|
||||||
renamingIdentifier: String? = nil,
|
renamingIdentifier: String? = nil,
|
||||||
customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)? = nil,
|
customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V) -> V)? = nil,
|
||||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V) -> Void, _ originalNewValue: V) -> Void)? = nil,
|
||||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||||
|
|
||||||
@@ -704,7 +678,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
)
|
)
|
||||||
let customGetter = (self.customGetter ?? { $1() })
|
let customGetter = (self.customGetter ?? { $1() })
|
||||||
return customGetter(
|
return customGetter(
|
||||||
object,
|
PartialObject<O>(object.rawObject!),
|
||||||
{ () -> V in
|
{ () -> V in
|
||||||
|
|
||||||
return object.rawObject!.value(forKey: self.keyPath)! as! V
|
return object.rawObject!.value(forKey: self.keyPath)! as! V
|
||||||
@@ -818,7 +792,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
|
|
||||||
let rawObject = id as! CoreStoreManagedObject
|
let rawObject = id as! CoreStoreManagedObject
|
||||||
return customGetter(
|
return customGetter(
|
||||||
O.cs_fromRaw(object: rawObject),
|
PartialObject<O>(rawObject),
|
||||||
{ rawObject.getValue(forKvcKey: keyPath) as! V }
|
{ rawObject.getValue(forKvcKey: keyPath) as! V }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -848,7 +822,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V) -> V)?
|
private let customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V) -> V)?
|
||||||
private let customSetter: ((_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void)?
|
private let customSetter: ((_ `self`: O, _ setValue: (V) -> Void, _ newValue: V) -> Void)?
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,7 +871,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
isTransient: Bool = false,
|
isTransient: Bool = false,
|
||||||
versionHashModifier: String? = nil,
|
versionHashModifier: String? = nil,
|
||||||
renamingIdentifier: String? = nil,
|
renamingIdentifier: String? = nil,
|
||||||
customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)? = nil,
|
customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V?) -> V?)? = nil,
|
||||||
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void)? = nil,
|
customSetter: ((_ `self`: O, _ setValue: (_ finalNewValue: V?) -> Void, _ originalNewValue: V?) -> Void)? = nil,
|
||||||
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
affectedByKeyPaths: @autoclosure @escaping () -> Set<String> = []) {
|
||||||
|
|
||||||
@@ -931,7 +905,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
)
|
)
|
||||||
let customGetter = (self.customGetter ?? { $1() })
|
let customGetter = (self.customGetter ?? { $1() })
|
||||||
return customGetter(
|
return customGetter(
|
||||||
object,
|
PartialObject<O>(object.rawObject!),
|
||||||
{ () -> V? in
|
{ () -> V? in
|
||||||
|
|
||||||
object.rawObject!.value(forKey: self.keyPath) as! V?
|
object.rawObject!.value(forKey: self.keyPath) as! V?
|
||||||
@@ -1045,7 +1019,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
|
|
||||||
let rawObject = id as! CoreStoreManagedObject
|
let rawObject = id as! CoreStoreManagedObject
|
||||||
return customGetter(
|
return customGetter(
|
||||||
O.cs_fromRaw(object: rawObject),
|
PartialObject<O>(rawObject),
|
||||||
{ rawObject.getValue(forKvcKey: keyPath) as! V? }
|
{ rawObject.getValue(forKvcKey: keyPath) as! V? }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1083,7 +1057,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
|||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private let customGetter: ((_ `self`: O, _ getValue: () -> V?) -> V?)?
|
private let customGetter: ((_ `self`: PartialObject<O>, _ getValue: () -> V?) -> V?)?
|
||||||
private let customSetter: ((_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void)?
|
private let customSetter: ((_ `self`: O, _ setValue: (V?) -> Void, _ newValue: V?) -> Void)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user