iMobileBand iMobileBand - 5 months ago 24
Swift Question

The operation couldn’t be completed. (Cocoa error 133021.) + swift 2

I am currently using core data in my application. I have the following entities : Notification (to-1), People (to-many). The entities are as follows:

schema for Notification entity

schema for People entity

The People entity has a unique constraint which is the field id. Basically I'm going to receive notifications(which will be saved in Notification entity) from persons (which will be saved in People entity). I want to update the People entity if a person with a specific id sends more than one notifications and not create a new one (which will be duplicate).

When I am doing the above I get the following error:

The operation couldn’t be completed. (Cocoa error 133021.)

Can someone please help me solve this issue. Below is my code and an example of the data that I am trying to save.

let entityNotification = NSEntityDescription.entityForName("Notification", inManagedObjectContext: self.managedContext)

let newNotification = Notification(entity: entityNotification!, insertIntoManagedObjectContext: self.managedContext)

newNotification.message = data["message"] as? String

if let actor = data["actor"] as? [String : AnyObject]
{
let newPeople = NSEntityDescription.insertNewObjectForEntityForName("People", inManagedObjectContext: self.managedContext) as! People

newPeople.id = actor["id"] as? Int
newPeople.name = actor["name"] as? String

newNotification.actor = newPeople
}

if let designator = data["designator"] as? [String : AnyObject]
{
let newPeople = NSEntityDescription.insertNewObjectForEntityForName("People", inManagedObjectContext: self.managedContext) as! People

newPeople.id = designator["id"] as? Int
newPeople.name = designator["name"] as? String

newNotification.designator = newPeople
}

do
{
try newNotification.managedObjectContext?.save()
}
catch let error as NSError
{
print(error.localizedDescription)
}


Data model:

let notif = ["message" : "testing",
"actor" : ["id": 1, "name": "jim"],
"designator" : ["id": 2, "name": "dave"]]

let notif1 = ["message" : "testing 1",
"actor" : ["id": 1, "name": "jim21"],
"designator" : ["id": 2, "name": "dave"]]

Answer

The traditional way to resolve your issue of duplicate creation is to do a fetch request for a Person with that identity and update instead of creating new. This may also be the best option for you, testing will tell.

With unique constraints core data can do a merge for you, but you need to tell it how. Currently it's merging by throwing an error, which isn't so useful. You need to set the mergePolicy on the context to NSMergeByPropertyObjectTrumpMergePolicy and then try it out to see if the result is really what you want...