Home > Net >  Core Data: Generic class function to return object
Core Data: Generic class function to return object

Time:10-15

I have several classes of base type NSManagedObject and each of them contains a class function to return the first object of a given context. Here's an example:

public class Car: NSManagedObject {
    class func first(context: NSManagedObjectContext) -> Car? {
        let fetchRequest = Car.fetchRequest()
        fetchRequest.fetchLimit = 1
        let results = try? context.fetch(fetchRequest)
        return results?.first
    }
}

Instead of writing this function for every subclass I'd like to put a generic version as an extension to NSManagedObject. I've tried this:

extension NSManagedObject {
    class func first(context: NSManagedObjectContext) -> Self? {
        let fetchRequest = Self.fetchRequest()
        fetchRequest.fetchLimit = 1
        let results = try? context.fetch(fetchRequest)
        return results?.first
    }
}

But this gives a "Type of expression is ambigous without more context" error. How can this be done?

CodePudding user response:

context.fetch() returns [Any], but you can conditionally cast it to the expected type [Self]:

extension NSManagedObject {
    class func first(context: NSManagedObjectContext) -> Self? {
        let fetchRequest = Self.fetchRequest()
        fetchRequest.fetchLimit = 1
        let results = try? context.fetch(fetchRequest) as? [Self]
        return results?.first
    }
}

Or with a real do/try/catch for better diagnostics in the error case:

extension NSManagedObject {
    class func first(context: NSManagedObjectContext) -> Self? {
        let fetchRequest = Self.fetchRequest()
        fetchRequest.fetchLimit = 1
        do {
            let results = try context.fetch(fetchRequest) as? [Self]
            return results?.first
        } catch {
            print(error)
            return nil
        }
    }
}
  • Related