forked from zelo72/mastodon-ios
82 lines
2.6 KiB
Swift
82 lines
2.6 KiB
Swift
//
|
|
// Managed.swift
|
|
// CoreDataStack
|
|
//
|
|
// Created by Cirno MainasuK on 2020-8-6.
|
|
//
|
|
|
|
import Foundation
|
|
import CoreData
|
|
|
|
public protocol Managed: AnyObject, NSFetchRequestResult {
|
|
static var entityName: String { get }
|
|
static var defaultSortDescriptors: [NSSortDescriptor] { get }
|
|
}
|
|
|
|
extension Managed {
|
|
public static var defaultSortDescriptors: [NSSortDescriptor] {
|
|
return []
|
|
}
|
|
|
|
public static var sortedFetchRequest: NSFetchRequest<Self> {
|
|
let request = NSFetchRequest<Self>(entityName: entityName)
|
|
request.sortDescriptors = defaultSortDescriptors
|
|
return request
|
|
}
|
|
|
|
}
|
|
|
|
extension NSManagedObjectContext {
|
|
public func insertObject<T: NSManagedObject>() -> T where T: Managed {
|
|
guard let object = NSEntityDescription.insertNewObject(forEntityName: T.entityName, into: self) as? T else {
|
|
fatalError("Wrong object type")
|
|
}
|
|
|
|
return object
|
|
}
|
|
}
|
|
|
|
extension Managed where Self: NSManagedObject {
|
|
public static var entityName: String { return entity().name! }
|
|
}
|
|
|
|
extension Managed where Self: NSManagedObject {
|
|
public static func findOrCreate(in context: NSManagedObjectContext, matching predicate: NSPredicate, configure: (Self) -> Void) -> Self {
|
|
guard let object = findOrFetch(in: context, matching: predicate) else {
|
|
let newObject: Self = context.insertObject()
|
|
configure(newObject)
|
|
return newObject
|
|
}
|
|
|
|
return object
|
|
}
|
|
|
|
public static func findOrFetch(in context: NSManagedObjectContext, matching predicate: NSPredicate) -> Self? {
|
|
guard let object = materializedObject(in: context, matching: predicate) else {
|
|
return fetch(in: context) { request in
|
|
request.predicate = predicate
|
|
request.returnsObjectsAsFaults = false
|
|
request.fetchLimit = 1
|
|
}.first
|
|
}
|
|
|
|
return object
|
|
}
|
|
|
|
public static func materializedObject(in context: NSManagedObjectContext, matching predicate: NSPredicate) -> Self? {
|
|
for object in context.registeredObjects where !object.isFault {
|
|
guard let result = object as? Self, predicate.evaluate(with: result) else { continue }
|
|
return result
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
public static func fetch(in context: NSManagedObjectContext, configurationBlock: (NSFetchRequest<Self>) -> Void = { _ in }) -> [Self] {
|
|
let request = NSFetchRequest<Self>(entityName: Self.entityName)
|
|
configurationBlock(request)
|
|
return try! context.fetch(request)
|
|
}
|
|
}
|
|
|