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?
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With