Merge branch 'develop' into prototype/propertyWrapper

This commit is contained in:
John Estropia
2019-11-09 00:00:40 +09:00
16 changed files with 227 additions and 106 deletions

View File

@@ -43,5 +43,5 @@ internal protocol AttributeProtocol: PropertyProtocol {
var rawObject: CoreStoreManagedObject? { get set }
var getter: CoreStoreManagedObject.CustomGetter? { get }
var setter: CoreStoreManagedObject.CustomSetter? { get }
var valueForSnapshot: Any { get }
var valueForSnapshot: Any? { get }
}

View File

@@ -374,15 +374,34 @@ fileprivate struct CoreStoreFetchedSectionInfoWrapper: CoreStoreDebugStringConve
var coreStoreDumpString: String {
return createFormattedString(
"\"\(self.sectionInfo.name)\" (", ")",
("numberOfObjects", self.sectionInfo.numberOfObjects),
("indexTitle", self.sectionInfo.indexTitle as Any)
"\"\(self.sectionName)\" (", ")",
("numberOfObjects", self.numberOfObjects),
("indexTitle", self.sectionIndexTitle as Any)
)
}
// MARK: FilePrivate
let sectionInfo: NSFetchedResultsSectionInfo
fileprivate init(_ sectionInfo: NSFetchedResultsSectionInfo) {
self.sectionName = sectionInfo.name
self.numberOfObjects = sectionInfo.numberOfObjects
self.sectionIndexTitle = sectionInfo.indexTitle
}
fileprivate init(_ section: Internals.DiffableDataSourceSnapshot.Section) {
self.sectionName = section.differenceIdentifier
self.numberOfObjects = section.elements.count
self.sectionIndexTitle = nil
}
// MARK: Private
private let sectionName: String
private let sectionIndexTitle: String?
private let numberOfObjects: Int
}
@available(macOS 10.12, *)
@@ -410,6 +429,56 @@ extension ListMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConvert
}
// MARK: - ListPublisher
@available(macOS 10.12, *)
extension ListPublisher: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return formattedDebugDescription(self)
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
return createFormattedString(
"(", ")",
("snapshot", self.snapshot)
)
}
}
// MARK: - ListSnapshot
extension ListSnapshot: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return formattedDebugDescription(self)
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
return createFormattedString(
"(", ")",
("numberOfObjects", self.numberOfItems),
("sections", self.diffableSnapshot.sections.map(CoreStoreFetchedSectionInfoWrapper.init))
)
}
}
// MARK: - LocalStorageOptions
extension LocalStorageOptions: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
@@ -569,6 +638,56 @@ extension ObjectMonitor: CustomDebugStringConvertible, CoreStoreDebugStringConve
}
// MARK: - ObjectPublisher
extension ObjectPublisher: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return formattedDebugDescription(self)
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
return createFormattedString(
"(", ")",
("objectID", self.objectID()),
("object", self.object as Any)
)
}
}
// MARK: - ObjectSnapshot
extension ObjectSnapshot: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return formattedDebugDescription(self)
}
// MARK: CoreStoreDebugStringConvertible
public var coreStoreDumpString: String {
return createFormattedString(
"(", ")",
("objectID", self.objectID()),
("dictionaryForValues", self.dictionaryForValues())
)
}
}
// MARK: - OrderBy
extension OrderBy: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {

View File

@@ -41,7 +41,18 @@ extension DataStack {
*/
public func publishObject<O: DynamicObject>(_ object: O) -> ObjectPublisher<O> {
return ObjectPublisher<O>(objectID: object.cs_id(), context: self.unsafeContext())
return self.publishObject(object.cs_id())
}
/**
Creates an `ObjectPublisher` for a `DynamicObject` with the specified `ObjectID`. Multiple objects may then register themselves to be notified when changes are made to the `DynamicObject`.
- parameter objectID: the `ObjectID` of the object to observe changes from
- returns: an `ObjectPublisher` that broadcasts changes to `object`
*/
public func publishObject<O: DynamicObject>(_ objectID: O.ObjectID) -> ObjectPublisher<O> {
return ObjectPublisher<O>(objectID: objectID, context: self.unsafeContext())
}
/**

View File

@@ -120,7 +120,7 @@ extension DiffableDataSource {
let diffableSnapshot = snapshot.diffableSnapshot
self.dispatcher.apply(
diffableSnapshot as! Internals.DiffableDataSourceSnapshot,
diffableSnapshot,
view: self.collectionView,
animatingDifferences: animatingDifferences,
performUpdates: { collectionView, changeset, setSections in

View File

@@ -127,31 +127,19 @@ extension DiffableDataSource {
@nonobjc
public func apply(_ snapshot: ListSnapshot<O>, animatingDifferences: Bool = true) {
let diffableSnapshot = snapshot.diffableSnapshot
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
//
// self.modernDataSource.apply(
// diffableSnapshot as! NSDiffableDataSourceSnapshot<String, NSManagedObjectID>,
// animatingDifferences: animatingDifferences,
// completion: nil
// )
// }
// else {
self.dispatcher.apply(
diffableSnapshot as! Internals.DiffableDataSourceSnapshot,
view: self.tableView,
animatingDifferences: animatingDifferences,
performUpdates: { tableView, changeset, setSections in
tableView.reload(
using: changeset,
with: self.defaultRowAnimation,
setData: setSections
)
}
)
// }
self.dispatcher.apply(
snapshot.diffableSnapshot,
view: self.tableView,
animatingDifferences: animatingDifferences,
performUpdates: { tableView, changeset, setSections in
tableView.reload(
using: changeset,
with: self.defaultRowAnimation,
setData: setSections
)
}
)
}
/**

View File

@@ -41,9 +41,6 @@ import AppKit
internal protocol FetchedDiffableDataSourceSnapshotHandler: AnyObject {
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
// func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshot<String, NSManagedObjectID>)
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: Internals.DiffableDataSourceSnapshot)
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, sectionIndexTitleForSectionName sectionName: String?) -> String?
@@ -80,15 +77,6 @@ extension Internals {
internal func initialFetch() {
// #if canImport(UIKit) || canImport(AppKit)
//
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
//
// return
// }
//
// #endif
guard let fetchedResultsController = self.fetchedResultsController else {
return
@@ -98,20 +86,6 @@ extension Internals {
// MARK: NSFetchedResultsControllerDelegate
// #if canImport(UIKit) || canImport(AppKit)
//
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
// @objc
// dynamic func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
//
// self.handler?.controller(
// controller,
// didChangeContentWith: snapshot as NSDiffableDataSourceSnapshot<String, NSManagedObjectID>
// )
// }
//
// #endif
@objc
dynamic func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {

View File

@@ -397,15 +397,6 @@ public final class ListPublisher<O: DynamicObject>: Hashable {
extension ListPublisher: FetchedDiffableDataSourceSnapshotHandler {
// MARK: FetchedDiffableDataSourceSnapshotHandler
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
// internal func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshot<String, NSManagedObjectID>) {
//
// self.snapshot = .init(
// diffableSnapshot: snapshot,
// context: controller.managedObjectContext
// )
// }
internal func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: Internals.DiffableDataSourceSnapshot) {

View File

@@ -629,28 +629,14 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
// MARK: Internal
internal private(set) var diffableSnapshot: DiffableDataSourceSnapshotProtocol
internal private(set) var diffableSnapshot: Internals.DiffableDataSourceSnapshot
internal init() {
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
//
// self.diffableSnapshot = NSDiffableDataSourceSnapshot<String, NSManagedObjectID>()
// }
// else {
self.diffableSnapshot = Internals.DiffableDataSourceSnapshot()
// }
self.diffableSnapshot = Internals.DiffableDataSourceSnapshot()
self.context = nil
}
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
// internal init(diffableSnapshot: NSDiffableDataSourceSnapshot<String, NSManagedObjectID>, context: NSManagedObjectContext) {
//
// self.diffableSnapshot = diffableSnapshot
// self.context = context
// }
internal init(diffableSnapshot: Internals.DiffableDataSourceSnapshot, context: NSManagedObjectContext) {
self.diffableSnapshot = diffableSnapshot

View File

@@ -178,9 +178,9 @@ extension NSManagedObjectContext {
private func userInfo<T>(for key: UserInfoKeys, initialize: @escaping () -> T) -> T {
let keyString = key.keyString
if let value = self.userInfo[keyString] {
if let value = self.userInfo[keyString] as? T {
return value as! T
return value
}
let value = initialize()
self.userInfo[keyString] = value

View File

@@ -336,7 +336,6 @@ extension ObjectPublisher {
// MARK: - ObjectPublisher where O: NSManagedObject
@available(*, unavailable, message: "KeyPaths accessed from @dynamicMemberLookup types can't generate KVC keys yet (https://bugs.swift.org/browse/SR-11351)")
extension ObjectPublisher where O: NSManagedObject {
// MARK: Public
@@ -344,11 +343,21 @@ extension ObjectPublisher where O: NSManagedObject {
/**
Returns the value for the property identified by a given key.
*/
@available(*, unavailable, message: "KeyPaths accessed from @dynamicMemberLookup types can't generate KVC keys yet (https://bugs.swift.org/browse/SR-11351)")
public subscript<V: AllowedObjectiveCKeyPathValue>(dynamicMember member: KeyPath<O, V>) -> V {
fatalError()
// return self.snapshot[dynamicMember: member]
}
/**
Returns the value for the property identified by a given key.
*/
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
let key = String(keyPath: keyPath)
return self.snapshot?.dictionaryForValues()[key] as! V?
}
}

View File

@@ -75,6 +75,19 @@ extension CoreStoreObject: ObjectRepresentation {}
extension DynamicObject where Self: ObjectRepresentation {
// MARK: Public
/**
A thread-safe `struct` that is a full-copy of the object's properties
*/
public func asSnapshot() -> ObjectSnapshot<Self>? {
return self.cs_toRaw()
.managedObjectContext
.flatMap({ ObjectSnapshot<Self>(objectID: self.cs_id(), context: $0) })
}
// MARK: ObjectRepresentation
public func objectID() -> Self.ObjectID {

View File

@@ -41,6 +41,14 @@ import AppKit
*/
@dynamicMemberLookup
public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
// MARK: Public
public func dictionaryForValues() -> [String: Any] {
return self.values
}
// MARK: ObjectRepresentation
@@ -112,11 +120,15 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
}
// MARK: FilePrivate
fileprivate var values: [String: Any]
// MARK: Private
private let id: O.ObjectID
private let context: NSManagedObjectContext
private var values: [String: Any]
private var valuesRef: NSDictionary {
@@ -127,17 +139,35 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
// MARK: - ObjectSnapshot where O: NSManagedObject
@available(*, unavailable, message: "KeyPaths accessed from @dynamicMemberLookup types can't generate KVC keys yet (https://bugs.swift.org/browse/SR-11351)")
extension ObjectSnapshot where O: NSManagedObject {
/**
Returns the value for the property identified by a given key.
*/
@available(*, unavailable, message: "KeyPaths accessed from @dynamicMemberLookup types can't generate KVC keys yet (https://bugs.swift.org/browse/SR-11351)")
public subscript<V: AllowedObjectiveCKeyPathValue>(dynamicMember member: KeyPath<O, V>) -> V {
let key = String(keyPath: member)
return self.values[key] as! V
}
/**
Returns the value for the property identified by a given key.
*/
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
let key = String(keyPath: keyPath)
return self.values[key] as! V?
}
/**
Mutates the value for the property identified by a given key.
*/
public mutating func setValue<V: AllowedObjectiveCKeyPathValue>(_ value: V!, forKeyPath keyPath: KeyPath<O, V>) {
let key = String(keyPath: keyPath)
self.values[key] = value
}
}
@@ -170,7 +200,7 @@ extension ObjectSnapshot where O: CoreStoreObject {
get {
let key = String(keyPath: member)
return self.values[key] as! V?
return self.values[key] as? V
}
set {
@@ -204,7 +234,7 @@ extension ObjectSnapshot where O: CoreStoreObject {
get {
let key = String(keyPath: member)
return self.values[key] as! V?
return self.values[key] as? V
}
set {
@@ -221,7 +251,7 @@ extension ObjectSnapshot where O: CoreStoreObject {
get {
let key = String(keyPath: member)
guard let id = self.values[key] as! D.ObjectID? else {
guard let id = self.values[key] as? D.ObjectID else {
return nil
}

View File

@@ -313,9 +313,9 @@ public enum RelationshipContainer<O: CoreStoreObject> {
}
}
internal var valueForSnapshot: Any {
internal var valueForSnapshot: Any? {
return self.value?.objectID() as Any
return self.value?.objectID()
}
@@ -609,9 +609,9 @@ public enum RelationshipContainer<O: CoreStoreObject> {
}
}
internal var valueForSnapshot: Any {
internal var valueForSnapshot: Any? {
return self.value.map({ $0.objectID() }) as Any
return self.value.map({ $0.objectID() })
}
@@ -910,9 +910,9 @@ public enum RelationshipContainer<O: CoreStoreObject> {
}
}
internal var valueForSnapshot: Any {
internal var valueForSnapshot: Any? {
return Set(self.value.map({ $0.objectID() })) as Any
return Set(self.value.map({ $0.objectID() }))
}

View File

@@ -41,5 +41,5 @@ internal protocol RelationshipProtocol: PropertyProtocol {
var renamingIdentifier: () -> String? { get }
var minCount: Int { get }
var maxCount: Int { get }
var valueForSnapshot: Any { get }
var valueForSnapshot: Any? { get }
}

View File

@@ -272,9 +272,9 @@ public enum TransformableContainer<O: CoreStoreObject> {
}
}
internal var valueForSnapshot: Any {
internal var valueForSnapshot: Any? {
return self.value as Any
return self.value
}
@@ -494,9 +494,9 @@ public enum TransformableContainer<O: CoreStoreObject> {
}
}
internal var valueForSnapshot: Any {
internal var valueForSnapshot: Any? {
return self.value as Any
return self.value
}

View File

@@ -310,9 +310,9 @@ public enum ValueContainer<O: CoreStoreObject> {
}
}
internal var valueForSnapshot: Any {
internal var valueForSnapshot: Any? {
return self.value as Any
return self.value
}
@@ -575,9 +575,9 @@ public enum ValueContainer<O: CoreStoreObject> {
}
}
internal var valueForSnapshot: Any {
internal var valueForSnapshot: Any? {
return self.value as Any
return self.value
}