Implement ObjectRepresentation on ObjectMonitor, ObjectPublisher, and ObjectSnapshot for future APIs

This commit is contained in:
John Estropia
2021-01-02 09:59:15 +09:00
parent e1aed37da0
commit 2cd8101987
4 changed files with 101 additions and 43 deletions

View File

@@ -40,12 +40,7 @@ import CoreData
Observers registered via `addObserver(_:)` are not retained. `ObjectMonitor` only keeps a `weak` reference to all observers, thus keeping itself free from retain-cycles. Observers registered via `addObserver(_:)` are not retained. `ObjectMonitor` only keeps a `weak` reference to all observers, thus keeping itself free from retain-cycles.
*/ */
@available(macOS 10.12, *) @available(macOS 10.12, *)
public final class ObjectMonitor<O: DynamicObject>: Equatable { public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentation {
/**
The object type represented by this `ObjectMonitor`
*/
public typealias ObjectType = O
/** /**
Returns the `DynamicObject` instance being observed, or `nil` if the object was already deleted. Returns the `DynamicObject` instance being observed, or `nil` if the object was already deleted.
@@ -156,6 +151,51 @@ public final class ObjectMonitor<O: DynamicObject>: Equatable {
} }
// MARK: AnyObjectRepresentation
public func objectID() -> O.ObjectID {
return self.id
}
public func cs_dataStack() -> DataStack? {
return self.context.parentStack
}
// MARK: ObjectRepresentation
public typealias ObjectType = O
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
return dataStack.unsafeContext().objectPublisher(objectID: self.id)
}
public func asReadOnly(in dataStack: DataStack) -> O? {
return dataStack.unsafeContext().fetchExisting(self.id)
}
public func asEditable(in transaction: BaseDataTransaction) -> O? {
return transaction.unsafeContext().fetchExisting(self.id)
}
public func asSnapshot(in dataStack: DataStack) -> ObjectSnapshot<O>? {
let context = dataStack.unsafeContext()
return ObjectSnapshot<O>(objectID: self.id, context: context)
}
public func asSnapshot(in transaction: BaseDataTransaction) -> ObjectSnapshot<O>? {
let context = transaction.unsafeContext()
return ObjectSnapshot<O>(objectID: self.id, context: context)
}
// MARK: Internal // MARK: Internal
internal init(objectID: O.ObjectID, context: NSManagedObjectContext) { internal init(objectID: O.ObjectID, context: NSManagedObjectContext) {

View File

@@ -125,15 +125,23 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
} }
// MARK: ObjectRepresentation // MARK: AnyObjectRepresentation
public typealias ObjectType = O
public func objectID() -> O.ObjectID { public func objectID() -> O.ObjectID {
return self.id return self.id
} }
public func cs_dataStack() -> DataStack? {
return self.context.parentStack
}
// MARK: ObjectRepresentation
public typealias ObjectType = O
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> { public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
let context = dataStack.unsafeContext() let context = dataStack.unsafeContext()
@@ -173,11 +181,6 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
} }
return ObjectSnapshot<O>(objectID: self.id, context: context) return ObjectSnapshot<O>(objectID: self.id, context: context)
} }
public func cs_dataStack() -> DataStack? {
return self.context.parentStack
}
// MARK: Equatable // MARK: Equatable

View File

@@ -26,23 +26,37 @@
import CoreData import CoreData
// MARK: - AnyObjectRepresentation
/**
Used internally by CoreStore. Do not conform to directly.
*/
public protocol AnyObjectRepresentation {
/**
The internal ID for the object.
*/
func objectID() -> NSManagedObjectID
/**
Used internally by CoreStore. Do not call directly.
*/
func cs_dataStack() -> DataStack?
}
// MARK - ObjectRepresentation // MARK - ObjectRepresentation
/** /**
An object that acts as interfaces for `CoreStoreObject`s or `NSManagedObject`s An object that acts as interfaces for `CoreStoreObject`s or `NSManagedObject`s
*/ */
public protocol ObjectRepresentation { public protocol ObjectRepresentation: AnyObjectRepresentation {
/** /**
The object type represented by this protocol The object type represented by this protocol
*/ */
associatedtype ObjectType: DynamicObject associatedtype ObjectType: DynamicObject
/**
The internal ID for the object.
*/
func objectID() -> ObjectType.ObjectID
/** /**
An instance that may be observed for object changes. An instance that may be observed for object changes.
*/ */
@@ -67,11 +81,6 @@ public protocol ObjectRepresentation {
A thread-safe `struct` that is a full-copy of the object's properties A thread-safe `struct` that is a full-copy of the object's properties
*/ */
func asSnapshot(in transaction: BaseDataTransaction) -> ObjectSnapshot<ObjectType>? func asSnapshot(in transaction: BaseDataTransaction) -> ObjectSnapshot<ObjectType>?
/**
Used internally by CoreStore. Do not call directly.
*/
func cs_dataStack() -> DataStack?
} }
extension NSManagedObject: ObjectRepresentation {} extension NSManagedObject: ObjectRepresentation {}
@@ -101,14 +110,22 @@ extension DynamicObject where Self: ObjectRepresentation {
.managedObjectContext .managedObjectContext
.flatMap({ ObjectSnapshot<Self>(objectID: self.cs_id(), context: $0) }) .flatMap({ ObjectSnapshot<Self>(objectID: self.cs_id(), context: $0) })
} }
// MARK: ObjectRepresentation // MARK: AnyObjectRepresentation
public func objectID() -> Self.ObjectID { public func objectID() -> Self.ObjectID {
return self.cs_id() return self.cs_id()
} }
public func cs_dataStack() -> DataStack? {
return self.cs_toRaw().managedObjectContext?.parentStack
}
// MARK: ObjectRepresentation
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<Self> { public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<Self> {
@@ -147,9 +164,4 @@ extension DynamicObject where Self: ObjectRepresentation {
let context = transaction.unsafeContext() let context = transaction.unsafeContext()
return ObjectSnapshot<Self>(objectID: self.cs_id(), context: context) return ObjectSnapshot<Self>(objectID: self.cs_id(), context: context)
} }
public func cs_dataStack() -> DataStack? {
return self.cs_toRaw().managedObjectContext?.parentStack
}
} }

View File

@@ -48,17 +48,25 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
return self.values return self.values
} }
// MARK: ObjectRepresentation
// MARK: AnyObjectRepresentation
public typealias ObjectType = O
public func objectID() -> O.ObjectID { public func objectID() -> O.ObjectID {
return self.id return self.id
} }
public func cs_dataStack() -> DataStack? {
return self.context.parentStack
}
// MARK: ObjectRepresentation
public typealias ObjectType = O
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> { public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
let context = dataStack.unsafeContext() let context = dataStack.unsafeContext()
@@ -86,11 +94,6 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
let context = transaction.unsafeContext() let context = transaction.unsafeContext()
return ObjectSnapshot<O>(objectID: self.id, context: context) return ObjectSnapshot<O>(objectID: self.id, context: context)
} }
public func cs_dataStack() -> DataStack? {
return self.context.parentStack
}
// MARK: Equatable // MARK: Equatable