Reputation: 71
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:
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?
}
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)")
}
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?
Upvotes: 1
Views: 663
Reputation: 11
Swift 5
If the relationship is properly set up in the Coredata-Model, The only thing you need to do is
item.container = container
/*let container = NSManagedObject(entity: containerEntity, insertInto: managedContext) as! Container
let items = NSManagedObject(entity: itemEntity, insertInto: managedContext) as! Items
let containerEntity = NSEntityDescription.entity(forEntityName: "Container", in: managedContext)!
let items = NSManagedObject(entity: itemEntity, insertInto: managedContext)*/
//or
let container = Container(context: managedContext)
container.index = someIndex
container.name = someName
let item = Item(context: managedContext) // I think 'Item' would be better as a model name.
item.text = someText
item.image = someImage
item.index = someIndex
item.container = container // setting for Many to one relationShip
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
Upvotes: 0
Reputation: 115051
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 Item
s 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)")
}
Upvotes: 1
Reputation: 29676
If set up correctly a there should be an addToItems()
anyContainerObject.addToItems(value: Items)
Upvotes: 2