I have two objects: Category
and Item
. An Item
has a name
field, price
field, and quantity
field. A Category
has a name
field. A category also has many Items
. When I access my tableView of categories
I want to display all the items
related to that category
. Below is my code of how I'm setting the relationship when a new Item
is added and also when a category
is fetched to display all its items. Am I not saving the relationship correctly?
Saving Relationship
func saveItem(name: String, quantity: Int, price: String) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
let entity = NSEntityDescription.entityForName("Item", inManagedObjectContext: managedContext)
let item = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
var error: NSError?
item.setValue(name, forKey: "name")
item.setValue(quantity, forKey: "quantity")
item.setValue(price, forKey: "price")
item.setValue(selectedCategory, forKey: "category")
// selectedCategory: the parent of this new item
selectedCategory.setValue(NSOrderedSet(object: item), forKey: "item")
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
else {
items.append(item)
self.fetchCategories("")
}
}
fetching items of category
func fetchItems() {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
let fetchRequest = NSFetchRequest(entityName: "Item")
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.predicate = NSPredicate(format: "category = %@", category?.valueForKey("name") as! String)
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject]
if let results = fetchedResults {
items = results
}
else {
println("Could not fetch \(error), \(error!.userInfo)")
}
}
my data model
Because the
item
relationship is the inverse of thecategory
relationship, you do not need to set both. If you set the relationship one way, Core Data automatically does the other:So the following lines are not required...
Also your predicate is wrong in the fetch - there is no need to use the
name
attribute in the predicate - CoreData will (under the hood) use its own primary key. So amend this:to this: