TransWikia.com

CoreData how to add items to a NSSet which is related to an entity

Stack Overflow Asked by moyes on December 16, 2020

In my project I created two entities: Container and Items. There’s a one to many relationship between the two. In Container I called the relationship item and I set it to "To Many" because I want to have many items in each container. In Items I called the relationship container and I set it to "To One" because each item must be associated to one and only one container.

This aside, in my project I have a tableview where I can add new containers and when I press on a cell I can see its items. The code to create the containers is fine. The problem comes when I try to create the items: they are created successfully but they appear in each container.

In the following part I’ll post the objects, how I save containers and how I save items:

  • Objects:
extension Container {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Container> {
        return NSFetchRequest<Container>(entityName: "Container")
    }

    @NSManaged public var name: String?
    @NSManaged public var index: Int64
    @NSManaged public var items: NSSet?

}

extension Items {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Items> {
        return NSFetchRequest<Items>(entityName: "Items")
    }

    @NSManaged public var text: String?
    @NSManaged public var image: UIImage?
    @NSManaged public var index: Int64
    @NSManaged public var container: Container?

}
  • Creating container:
let containerEntity = NSEntityDescription.entity(forEntityName: "Container", in: managedContext)!
        
        let items: NSSet = []
        
        let container = NSManagedObject(entity: containerEntity, insertInto: managedContext) as! Container
        
        ///Count is just an int variable
        container.setValue("Name", forKeyPath: "name")
        container.setValue(count, forKeyPath: "index")
        container.setValue(items, forKey: "items")
        
        do {
            try managedContext.save()

        } catch let error as NSError {
            print("Could not save. (error), (error.userInfo)")
        }
  • Creating item:
  let itemEntity = NSEntityDescription.entity(forEntityName: "Items", in: managedContext)!
        
        let items = NSManagedObject(entity: itemEntity, insertInto: managedContext) as! Items
 
        items.setValue("item", forKeyPath: "text")
        items.setValue(count, forKeyPath: "index")
     
        
        do {
            try managedContext.save()

        } catch let error as NSError {
            print("Could not save. (error), (error.userInfo)")
        }
        

Anyway I think that instead of creating items entities I should edit the container entity adding to it items. To do that I tried this but I feel like I’m missing something because this thing crashes.

let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "container")
       
       do {
           let test = try managedContext.fetch(fetchRequest)
           
           let objectUpdate = test[containerIndex] as! NSManagedObject
           
           objectUpdate.setValue("item", forKey: "text")
           objectUpdate.setValue(count, forKey: "index")
           
           do{
               try managedContext.save()
           } catch {
               print(error)
           }
          
       }
       catch {
           print(error)
       }

So how can I add items to a specific container?

Plus, is it ok if two of my entities attributes are called index?

2 Answers

If set up correctly a there should be an addToItems()

anyContainerObject.addToItems(value: Items)

Correct answer by lorem ipsum on December 16, 2020

As long as you have set up the inverse relationships correctly in your core data model, the simplest approach is just to assign the relevant Container instance to the new Item's container property. Core data will take care of updating the Container's set of Items for you.

let itemEntity = NSEntityDescription.entity(forEntityName: "Items", in: managedContext)!
        
let items = NSManagedObject(entity: itemEntity, insertInto: managedContext) as! Items
 
items.setValue("item", forKeyPath: "text")
items.setValue(count, forKeyPath: "index")
items.setValue(container, forKeyPath: "container")

do {
    try managedContext.save()
} catch let error as NSError {
    print("Could not save. (error), (error.userInfo)")
}

Your code will be simpler and easier to maintain if you use the objects that are automatically created for your Core Data entities

        
let items = Item(context:managedObjectContext)
 
items.text = item
items.count = index
items.container = container

do {
    try managedContext.save()
} catch let error as NSError {
    print("Could not save. (error), (error.userInfo)")
}

Answered by Paulw11 on December 16, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP