How to use generics to return all objects for specific type of NSManagedObject?

203 Views Asked by At

This is what I need to achieve:

extension NSManagedObject {
    class func all<T: Self>(in context: NSManagedObjectContext) -> [T] { //error: Expected a class type or protocol-constrained type restricting '
        return mr_findAll(in: context) as! [T]
    }
}

And I would like to use it like this:

let persons = Person.all(in: context)
let hotels = Hotel.all(in: context)

Is it possible at all?

Person and Hotel inherits from NSManagedObject.

1

There are 1 best solutions below

6
vadian On BEST ANSWER

As a fetch request is already generic this can be accomplished only with a protocol extension and associated type, an NSManagedObject extension doesn't work without any type cast or annotation.

protocol Managed
{
    associatedtype ManagedType: NSManagedObject = Self
    static var entityName : String { get }
    static func all(in context: NSManagedObjectContext) throws -> [ManagedType]
}

extension Managed where Self : NSManagedObject {
    static var entityName : String { return String(describing:self) }

    static func all(in context: NSManagedObjectContext) throws -> [ManagedType] {
        let request = NSFetchRequest<ManagedType>(entityName: entityName)
        return try context.fetch(request)
    }
}

Just add conformance to Managed to all your NSManagedObject subclasses then you can use

let persons = Person.all(in: context)
let hotels = Hotel.all(in: context)