Anusha Kottiyal
Anusha Kottiyal

Reputation: 3905

Generic method to fetch data from different core data entities and cast result to respective classes

I am writing a generic method to fetch data from core data entity with given entityName, predicate and sortDescriptors. I want to return the result as an array of requested entity. If I give Student as entityName, I need to return an array of Students as given below,

do {
        if let results = try CoreDataController.sharedInstance.masterManagedObjectContext.fetch(request) as? [Student] {

            if results.count > 0 {

                return results
            }
        }
    }

The problem here is, how to cast the results to array of respective entity class, in generic method using given entity name?

I have tried to generate class from entity name,

let coreDataClass = NSClassFromString(entityName) as! NSManagedObject.Type

But it is no taken in array declaration (in the place Student in above code). Please help me to find the correct way.

Thanks in advance!

Upvotes: 2

Views: 1680

Answers (1)

viral
viral

Reputation: 4208

You can use Swift Generics for the exact same scenario.

Consider the following Swift (Version 3.0.1) code for fetching an array of object with predicate & sort descriptor provided as parameter (You can define this function in your coredata helper class as a class method):

class func arrayOf<T: NSManagedObject>(_ entity: T.Type, 
                                       predicate: NSPredicate? = nil,
                                       sortDescriptor: [NSSortDescriptor]? = nil,
                                       context: NSManagedObjectContext = CoreDataHelper.shared.context()) -> NSMutableArray? {

    let fetchRequest = NSFetchRequest<T>(entityName: NSStringFromClass(T.self))

    if predicate != nil {
        fetchRequest.predicate = predicate!
    }

    if sortDescriptor != nil {
        fetchRequest.sortDescriptors = sortDescriptor!
    }

    fetchRequest.returnsObjectsAsFaults = false

    do {

        let searchResult = try context.fetch(fetchRequest)
        if searchResult.count > 0 {
            // returns mutable copy of result array
            return NSMutableArray.init(array: searchResult)
        } else {
            // returns nil in case no object found
            return nil
        }

    } catch {
        print(error.localizedDescription)
        return nil
    }
}

Hope that helps.

Upvotes: 8

Related Questions