Search code examples
swiftcore-dataswift5

How to run a generic method on a core data entity on Swift, the smarter way


I have a lot of core data entities, they all have this method:

class func count(_ context:NSManagedObjectContext) -> Int

Suppose the entities are called: Car, Bus, Plane, etc.

What I would like to do is this, as I would normally.

let carCount = Car.count(coreDataContext)

of

 let busCount = Bus.count(coreDataContext)

but, all I have is the entity name, as described previously

How do I run that method from an entity just by the name of that entity?


Solution

  • Create a protocol with associated type

    protocol Fetchable
    {
        associatedtype FetchableType: NSManagedObject = Self
        static var entityName : String { get }
        static func count(_ context: NSManagedObjectContext) throws -> Int
    }
    

    and a protocol extension

    extension Fetchable where Self : NSManagedObject
    {
        
        static var entityName : String { return String(describing:self) }
    
        static func count(_ context: NSManagedObjectContext) throws -> Int
        {
            let request = NSFetchRequest<FetchableType>(entityName: entityName)        
            return try context.count(for: request)
        }
    }
    

    Adopt Fetchable in the NSManagedObject subclasses