Convert request Function to Generic type

According to my comment I recommend to use a protocol with extension for example

protocol Fetchable
{
    associatedtype FetchableType: NSManagedObject = Self
    
    static var entityName : String { get }
    static var managedObjectContext : NSManagedObjectContext { get }
    static func objects(for predicate: NSPredicate?) throws -> [FetchableType]
}

extension Fetchable where Self : NSManagedObject
{
    static var entityName : String {
        return String(describing: self)
    }
    
    static var managedObjectContext : NSManagedObjectContext {
        return (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    }
    
    static func objects(for predicate: NSPredicate?) throws -> [FetchableType]
    {
        let request = NSFetchRequest<FetchableType>(entityName: entityName)
        request.predicate = predicate
        return try managedObjectContext.fetch(request)
    }
}

Change (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext to the reference to your managed object context.

Make all NSManagedObject subclasses adopt Fetchable. There is no extra code needed in the subclasses.

Now you can get the data with

do {
   let predicate = NSPredicate(format: ...
   let objects = try MyEntity.objects(for: predicate)
} catch {
    print(error)
}

That’s all, objects are [MyEntity] without any type casting and always non-optional on success.

The protocol is easily extendable by default sorting descriptors, sorting directions etc.

Leave a Comment