Querying Core data with predicates

1.2k views Asked by At

So i am building this app using CoreData.

The two entities I have are Lists and Items. They have a to many relationship i.e. A List can have multiple items.

For example: List1 has Items: item1, item2

I have written the code for storing the Items in the specific list but i am having a difficult time on figuring out how to fetch and proccess the Items from a specific List.

What I have done so far is as follows

func getItemsOnList(){

        let app = UIApplication.shared.delegate as! AppDelegate
        let context = app.persistentContainer.viewContext

        //fetchRequest to get the List
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "List")
        let predicate = NSPredicate(format: "title == %@", listName)
        fetchRequest.returnsObjectsAsFaults = false
        fetchRequest.predicate = predicate

        if let fetchResults = try? context.fetch(fetchRequest){
            if fetchResults.count > 0 {
                for listEntity in fetchResults {
                    let list = listEntity as! List
                    print(list.title as Any)
                    itemsOnList = list.contains!
                    print(itemsOnList)
                    print("The list with name:\(list.title)has \(itemsOnList.count) items")

                }
            }
        }
    }

This function returns an NSSet which is suppose to contain all the Items in that particular List.

My Data model is :

Data model

My questions are:

A. Is the way I coded the getItemsOnList() function correct? Or is there something I am doing wrong.

B. Given that the code is correct and the NSSet I get is correct with all the Items, how would I get each Item in that NSSet in order for me to put it on a TableView.

2

There are 2 answers

0
Gabriel On

Answers: A) Yes. You are using the graph of objects from a fetch. That is the main functionality of Core Data. B) To fill a table view you cannot use a set. You need some kind of sorted list of elements. That is, an array. Use -orderedArrayUsingDescriptors: to get the sorted array.

6
Jagdeep On
 func getItemsWithFilter(filterQuery:NSPredicate,sortBy:String?,order:Bool) -> Array<Items> {
var fetchedResults:Array<Items> = Array<Items>()


let fetchRequest = NSFetchRequest(entityName: "Items")
fetchRequest.predicate = filterQuery

if sortBy != nil{
  let sortDescriptor = NSSortDescriptor(key:sortBy! ,
                                        ascending:order )
  let sortDescriptors = [sortDescriptor]
  fetchRequest.sortDescriptors = sortDescriptors
}

//Execute Fetch request you can go with your approach to
do {
  fetchedResults = try self.mainContextInstance.executeFetchRequest(fetchRequest) as! [Items]
} catch let fetchError as NSError {
  print("retrieveById error: \(fetchError.localizedDescription)")
  fetchedResults = Array<Items>()
}catch {
  fetchedResults = Array<Items>()
}

return fetchedResults

}

for calling this method you can pass the List item in predicate to as query saying fetch Items in which List.id == XXX

 let predicate = NSPredicate(format: "ANY list.name in %@", name)
let myResult = self.getItemsWithFilter(predicate,sortBy:nil,order:false)