How to implement the new Core Data model builder 'unique' property in iOS 9.0 Beta

[亡魂溺海] 提交于 2019-12-19 00:57:12

问题


In the WWDC15 video session, 'What's New in Core Data' at 10:45 mins (into the presentation) the Apple engineer describes a new feature of the model builder that allows you to specify unique properties. Once you set the those unique properties, Core Data will not create a duplicate object with that property. This is suppose to eliminate the need to check if an identical object before you create a new object.

I have been experimenting with this but have no luck preventing the creation of new objects with identical 'unique' properties (duplicate objects). Other than the 5 minute video explanation, I have not found any other information describing how to use this feature.

Does anyone have any experience implementing the 'unique' property attribute in the Core Data Model?


回答1:


Short answer: You'll need to add this line to your Core Data stack setup code:

managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

Long answer: I struggled with this for some time, but I think I have figured it out now:

Unique Constraints (UC) do not prevent creating duplicates in a context. Only when you try to save that context, Core Data checks for the uniqueness of the UCs.

If it finds more than one object with the same value for a UC, the default behaviour is to throw an error because the default merge policy for conflicts is NSErrorMergePolicyType. The error contains the conflicting objects in its userInfo.conflictList, so you could manually resolve the conflict.

But most of the time you probably want to use one of the other merge policies instead and let Core Data merge the conflicts automatically. These merge policies did exist before, they are used for conflicts between objects in different contexts. Maybe that's why they were not mentioned in the context of the UC feature at WWDC Session 220. Usually the right choice is NSMergeByPropertyObjectTrumpMergePolicy. It basically says "new data trumps old data", which is what you want in the common scenario when you import new data from external sources.

(Tip: First I had problems verifying this behaviour, because the duplicate objects seem to remain in the context until the save operation is finished - which in my case happened asynchronously in a background queue. So if you fetch/count your objects right after hitting the save button, you might still see the duplicates.)




回答2:


I don't know the right answer, as this is a beta version, but after playing with it for a minute I found a way to make it work:

  1. Tell the model which attributes form the unique constraint, exactly as shown in the image you have in your question.

  2. Add a new record:

let newTag = NSEntityDescription.insertNewObjectForEntityForName("Tag", inManagedObjectContext: context) as! Tag
  1. Assign the values to the attribues.

  2. Save your changes:

do {
  try context.save()
} catch let error as NSError {
  print("Error: \(error.localizedDescription)")
  context.reset()
}

The key is in the catch block. If an error happens, reset the context to the previous state. As the save operation failed, the duplicate records won't be there.

Please notice that you should check the error to see if it was caused by a duplicated record.

I hope this helps.



来源:https://stackoverflow.com/questions/30894026/how-to-implement-the-new-core-data-model-builder-unique-property-in-ios-9-0-be

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!