Ich entwerfe einen Datenmanager für mein Core-Datenmodell und ich möchte eine generische Funktion erstellen, um Verwandte einer Klasse zu holen.Erhalte Core-Entity-Verwandte mit einer generischen Funktion
Ich habe ein Protokoll erstellt, das das Erstellen von Managern für jeden Datentyp ermöglicht. In diesem Protokoll habe ich bereits zwei assoziierte Typen T und K und einige einfache Funktionen definiert. Jetzt stehe ich bei einer Klassen-Verwandten-Methode - ich muss irgendwie angeben, dass T Verwandte hat. Ich habe vergeblich versucht, ein Protokoll zu erstellen, das diese Beziehung durch gegenseitige Eigenschaften anzeigt, so dass beide Klassen diesem Protokoll entsprechen könnten. Irgendeine Idee, ist es überhaupt möglich?
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 }
}
}