NSManagedObject features are now fully supported for CoreStoreObject types. MacOSX 10.12 onwards now support ListMonitors and ObjectMonitors

This commit is contained in:
John Estropia
2017-04-07 20:14:13 +09:00
parent 4aa1a63f9a
commit c0ae129b22
58 changed files with 1172 additions and 803 deletions

View File

@@ -27,16 +27,15 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - CoreStoreFetchedResultsController
@available(OSX 10.12, *)
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController<NSManagedObject> {
// MARK: Internal
@nonobjc
internal convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
internal convenience init<T: DynamicObject>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
self.init(
context: dataStack.mainContext,
@@ -48,7 +47,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
}
@nonobjc
internal init<T: NSManagedObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
internal init<T: DynamicObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
_ = from?.applyToFetchRequest(
fetchRequest,
@@ -115,5 +114,3 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
@nonobjc
private let reapplyAffectedStores: (_ fetchRequest: NSFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) -> Bool
}
#endif

View File

@@ -27,10 +27,9 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - FetchedResultsControllerHandler
@available(OSX 10.12, *)
internal protocol FetchedResultsControllerHandler: class {
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeObject anObject: Any, atIndexPath indexPath: IndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
@@ -47,7 +46,8 @@ internal protocol FetchedResultsControllerHandler: class {
// MARK: - FetchedResultsControllerDelegate
internal final class FetchedResultsControllerDelegate<EntityType: NSManagedObject>: NSObject, NSFetchedResultsControllerDelegate {
@available(OSX 10.12, *)
internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResultsControllerDelegate {
// MARK: Internal
@@ -240,5 +240,3 @@ internal final class FetchedResultsControllerDelegate<EntityType: NSManagedObjec
@nonobjc
private var insertedSections = Set<Int>()
}
#endif

View File

@@ -34,15 +34,16 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
// MARK: FetchableSource
@nonobjc
public func fetchExisting<T: NSManagedObject>(_ object: T) -> T? {
public func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
if object.objectID.isTemporaryID {
let rawObject = object.cs_toRaw()
if rawObject.objectID.isTemporaryID {
do {
try withExtendedLifetime(self) { (context: NSManagedObjectContext) -> Void in
try context.obtainPermanentIDs(for: [object])
try context.obtainPermanentIDs(for: [rawObject])
}
}
catch {
@@ -56,8 +57,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
}
do {
let existingObject = try self.existingObject(with: object.objectID)
return (existingObject as! T)
let existingRawObject = try self.existingObject(with: rawObject.objectID)
if existingRawObject === rawObject {
return object
}
return T.cs_fromRaw(object: existingRawObject)
}
catch {
@@ -70,11 +75,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
}
@nonobjc
public func fetchExisting<T: NSManagedObject>(_ objectID: NSManagedObjectID) -> T? {
public func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
do {
return (try self.existingObject(with: objectID) as! T)
let existingObject = try self.existingObject(with: objectID)
return T.cs_fromRaw(object: existingObject)
}
catch _ {
@@ -83,25 +89,25 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
}
@nonobjc
public func fetchExisting<T: NSManagedObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
return objects.flatMap { (try? self.existingObject(with: $0.objectID)) as? T }
return objects.flatMap({ self.fetchExisting($0.cs_toRaw().objectID) })
}
@nonobjc
public func fetchExisting<T: NSManagedObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
return objectIDs.flatMap { (try? self.existingObject(with: $0)) as? T }
return objectIDs.flatMap({ self.fetchExisting($0) })
}
@nonobjc
public func fetchOne<T: ManagedObjectProtocol>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
return self.fetchOne(from, fetchClauses)
}
@nonobjc
public func fetchOne<T: ManagedObjectProtocol>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
@@ -114,18 +120,17 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
return nil
}
return self.fetchOne(fetchRequest.dynamicCast())
.flatMap(from.entityClass.cs_from)
return self.fetchOne(fetchRequest.dynamicCast()).flatMap(from.entityClass.cs_fromRaw)
}
@nonobjc
public func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
return self.fetchAll(from, fetchClauses)
}
@nonobjc
public func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
@@ -138,17 +143,18 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
return nil
}
return self.fetchAll(fetchRequest.dynamicCast())
let entityClass = from.entityClass
return self.fetchAll(fetchRequest.dynamicCast())?.map(entityClass.cs_fromRaw)
}
@nonobjc
public func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
return self.fetchCount(from, fetchClauses)
}
@nonobjc
public func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
@@ -162,13 +168,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
}
@nonobjc
public func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
return self.fetchObjectID(from, fetchClauses)
}
@nonobjc
public func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
@@ -185,13 +191,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
}
@nonobjc
public func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
return self.fetchObjectIDs(from, fetchClauses)
}
@nonobjc
public func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
@@ -238,13 +244,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
// MARK: QueryableSource
@nonobjc
public func queryValue<T: NSManagedObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
return self.queryValue(from, selectClause, queryClauses)
}
@nonobjc
public func queryValue<T: NSManagedObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
@@ -263,13 +269,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
}
@nonobjc
public func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
return self.queryAttributes(from, selectClause, queryClauses)
}
@nonobjc
public func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
@@ -296,6 +302,34 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
}
// MARK: Deleting
@nonobjc
internal func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
return self.deleteAll(from, deleteClauses)
}
@nonobjc
internal func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
fetchRequest.returnsObjectsAsFaults = true
fetchRequest.includesPropertyValues = false
deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
guard storeFound else {
return nil
}
return self.deleteAll(fetchRequest.dynamicCast())
}
// MARK: Deprecated
@available(*, deprecated, renamed: "unsafeContext()")
@@ -520,31 +554,6 @@ internal extension NSManagedObjectContext {
// MARK: Deleting
@nonobjc
internal func deleteAll<T: NSManagedObject>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
return self.deleteAll(from, deleteClauses)
}
@nonobjc
internal func deleteAll<T: NSManagedObject>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
let fetchRequest = CoreStoreFetchRequest()
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
fetchRequest.returnsObjectsAsFaults = true
fetchRequest.includesPropertyValues = false
deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
guard storeFound else {
return nil
}
return self.deleteAll(fetchRequest.dynamicCast())
}
@nonobjc
internal func deleteAll<T: NSManagedObject>(_ fetchRequest: NSFetchRequest<T>) -> Int? {