Search code examples
iosswiftcore-dataconstraints

Core Data Entity Unique Constraint Does Not Work


I am trying to set a constraint in core data with the new Entity Constraints inspector (To make the name of the item unique). All that I've read says it's pretty simple - Set the constraint and handle the error. I don't get any errors and can add the same entry as many times as I want.

The app does require IOS 9.0, Xcode tools requirement is set to 7.0

The constraint, category1Name, is a String.

My addItem code is:

func addNewRecord() {

    //check to be sure the entry is not empty
    if (categoryTextField.text == "") {

        //prompt requiring a name
        let ac = UIAlertController(title: nil, message: "Name Required", preferredStyle: .Alert)
        ac.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))
        self.presentViewController(ac, animated: true, completion: nil)

    } else {

    let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName("Category1", inManagedObjectContext: kAppDelegate.managedObjectContext) as! Category1

    newManagedObject.category1Name = categoryTextField.text
    newManagedObject.category1Description = categoryTextView.text

    //bunch more items...

    //save it
    kAppDelegate.saveContext()
    makeEntryFieldsEnabledNO()
    performSegueWithIdentifier("unwindToCategoriesTableViewController", sender: self)

    }//if  else

}//addNewRecord

The AppDelegate save is standard:

func saveContext () {
    if managedObjectContext.hasChanges {
        do {
            try managedObjectContext.save()
        } catch {

            //insert your standard error alert stuff here
            let nserror = error as NSError
            print("From the print line: Unresolved error \(nserror), \(nserror.userInfo)")

            abort()
        }//do catch
    }//if moc
}//saveContext

Here's the Core Data constraint:

enter image description here

This app is iCloud enabled.

The managedObjectContext merge policy is set to NSMergeByPropertyObjectTrumpMergePolicy

lazy var managedObjectContext: NSManagedObjectContext = {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
    let coordinator = self.persistentStoreCoordinator
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = coordinator
    managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    return managedObjectContext

}()//var managedObjectContext

Any guidance would be appreciated.


Solution

  • If you want to get an error when there are merge conflicts and handle them manually then you need to change your policy to NSErrorMergePolicy and you will get an error and in the user info the object IDs that you need to solve merge conflict , otherwise it will merge and save according to the specified merge policy. The policy that you set will overwrite the object attributes but not relationships, if you want to overwrite the attributes and relationships then specify the NSMergeByPropertyObjectTrumpMergePolicy.