Here's the version I use.
public protocol DDRCoreData where Self: NSManagedObject {
/// fetch NSManagedObject items for a specific entity type; default implementation provided below in extension
///
/// in order to use this, with the default implementation, use Xcode's codegen option of Category/Extension
/// and then write class such as:
///
/// @objc(Person) final class Person: NSManagedObject, DDRCoreData { }
///
/// the class must be declared final so that [Self] can be used as the return type
///
/// - Parameters:
/// - context: the NSManagedObjectContext to fetch the values in
/// - predicate: optional NSPredicate to limit the values that are fetched
/// - sorters: optional array of NSSortDescriptors to sort them by
/// - Returns: an array of the matching items sorted by the sort descriptors
static func items(for context: NSManagedObjectContext, sortedBy sorters: [NSSortDescriptor]?, matching predicate: NSPredicate?) throws -> [Self]
}
public extension DDRCoreData {
static func items(for context: NSManagedObjectContext, sortedBy sorters: [NSSortDescriptor]? = nil, matching predicate: NSPredicate? = nil) throws -> [Self] {
let request: NSFetchRequest<Self> = NSFetchRequest(entityName: String(describing: Self.self))
request.predicate = predicate
request.sortDescriptors = sorters
do {
let results = try context.fetch(request)
return results
} catch {
print("error fetching", String(describing: Self.self), error.localizedDescription)
return []
}
}
}
Then I have Xcode generate category/extension versions of the NSManaged Object and declare the class as:
@objc(Person) final public class Person: NSManagedObject, DDRCoreData { }
Then I can use:
do {
let p = try Person.items(for: managedObjectContext, sortedBy: [], matching: nil)
} catch {
}
HTH,
Dave