0
私はコアデータモデルのデータマネージャを設計しています。クラスの親戚をフェッチする汎用関数を作成したいと思います。ジェネリック関数を使用してコアデータエンティティを取得する
各データタイプのマネージャを構築できるプロトコルを作成しました。このプロトコルでは、すでに2つの関連するタイプTとKといくつかの単純な関数を定義しました。今私はクラスの親族をフェッチする方法に固執しています - 私は何とかTにKの親戚があることを示す必要があります。私は無関係で、相互の特性によってこの関係を示すプロトコルを作成しようとしていたので、どちらのクラスもこのプロトコルに準拠することができました。どんなアイデアでも可能ですか?
import Foundation
import CoreData
protocol DataManager {
associatedtype T: NSManagedObject, NSFetchRequestResult
associatedtype K: NSManagedObject, NSFetchRequestResult // Relative
static var sharedInstance: Self { get }
static func getAll(sorted: [NSSortDescriptor]?, context: NSManagedObjectContext) -> [T]?
static func insert(item: T)
static func update(item: T)
static func clean()
static func deleteById(id: String)
// Relatives
static func getRelatives(by: T) -> [K]?
static func get(byRelative: K) -> [T]?
}
extension DataManager {
static func getAll(sorted: [NSSortDescriptor]?, context: NSManagedObjectContext) -> [T]? {
guard let fetchRequest: NSFetchRequest<T> = T.fetchRequest() as? NSFetchRequest<T> else { return nil }
fetchRequest.sortDescriptors = sorted
var results: [T]? = nil
do {
results = try context.fetch(fetchRequest)
} catch {
assert(false, error.localizedDescription)
} //TODO: Handle Errors
return results
}
}
protocol Identifiable {
typealias Identity = String
var id: Identity? { get }
}
extension DataManager where Self.T: Identifiable {
static func get(by id: T.Identity, context: NSManagedObjectContext) -> T? {
guard let fetchRequest: NSFetchRequest<T> = T.fetchRequest() as? NSFetchRequest<T> else { return nil }
fetchRequest.predicate = NSPredicate(format: "%K == %@", "id", id)
var rawResults: [T]? = nil
do {
rawResults = try context.fetch(fetchRequest)
} catch {
assert(false, error.localizedDescription)
} //TODO: Handle Errors
if let result = rawResults?.first {
return result }
else { return nil }
}
}