Reputation: 1019
I'am using ios 10, xcode 8 (if that even matters, just mentioning everything). So according to wwmd, a fetch request is not needed to check if something is in core data, and then if it is, not save so as to not duplicate. Unique Constraints have been introduced for that matter. So I have an entity called List, with id
as an attribute. In contraints, I listed id (as the demonstrator on wwmd did). I also gave the context I'am using a merge policy of NSMergeByPropertyObjectTrumpMergePolicy
.
var context: NSManagedObjectContext {
mutating get {
if #available(iOS 10.0, *) {
let context = persistentContainer.viewContext
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return context
} else {
return managedObjectContext
}
}
}
To my point, it's not working. I can save the same id and it will Duplicate!!!. and there is absolutely no documentation on this relating to IOS 10. I made it work using swift IO9 managedObjectContext, but cannot make it work with IOS10 persistentcontainer.viewcontext. If someone has a solution for this, it would be immensely appreciated.
Upvotes: 3
Views: 1026
Reputation: 11782
I am using something like this to avoid duplicates, using unique constraint does not work while adding managed objects via relationship addToXXX() method
let ids = e.results.map { $0._identifier }
let request = MovieObject.fetchRequest()
request.predicate = NSPredicate(format: "id in %@", ids)
let existing = (try? request.execute() as? [MovieObject]) ?? []
let toUpdate = e.results.filter {
existing.map { $0.id }.contains($0._identifier)
}.map { movie in
(movie, existing.first(where: { $0.id == movie._identifier })!)
}
let toInsert = e.results.filter {
!existing.map { $0.id }.contains($0._identifier)
}
toInsert.forEach { movie in
let o = MovieObject(context: self.managedObjectContext!)
o.encode(entity: movie)
self.addToResults(o)
}
toUpdate.forEach {
let (m, o) = $0
o.encode(entity: m)
self.addToResults(o)
}
Upvotes: 0
Reputation: 1019
Solution: I added the mergepolicy in view didload in whichever viewcontroller needed the context. Update: Better solution : as Core data's unique constraints do not work with relationships, i ended up using Core Store which has a wonderful uniqueness algorithm as well as many useful core data wrappers.
Upvotes: 1
Reputation: 357
Unique Constraints only work when you save the context.
After creating NSMangaedObjects save that NSManagedContext in which they were created.
Yes unique constraints doesnot work if you have relationship in your entity.(I tried this with xcode 7.3 ios9)
Upvotes: 3