I am trying to merge a Core Data object with a unique constraint while preserving relationships. In particular, I am trying to avoid overwriting a relationship with nil.
The relationship is optional, but the inverse is mandatory. As such, the delete rule is set to “Cascade”, which makes it particularly important that it doesn’t get wiped.
I’m using the following custom merge policy, and it seems to work… at first. Before saving is complete, the following warning gets printed to the console: `CoreData: annotation: repairing missing delete propagation for to-one relationship […] on object […] with bad fault […]`. Core Data seems to deliberately erase anything I try to preserve. What is causing that, and how can I stop it?
private class NSMergeByPropertyNonNilObjectTrumpMergePolicy: NSMergePolicy {
override func resolve(constraintConflicts list: [NSConstraintConflict]) throws {
try super.resolve(constraintConflicts:
list.compactMap { conflict in
// don't customize context-level handling
guard
let databaseSnapshot = conflict.databaseSnapshot,
let conflictingObject = conflict.conflictingObjects.first else {
return conflict
}
databaseSnapshot
.filter {
conflictingObject.value(forKey: $0.key) == nil && !($0.value is NSNull)
}
.forEach {
// to-one relationships
if let objectID = $0.value as? NSManagedObjectID {
conflictingObject.setValue(
conflictingObject.managedObjectContext!.object(with: objectID),
forKey: $0.key
)
} else {
conflictingObject.setValue($0.value, forKey: $0.key)
}
}
return conflict
}
)
}
}
I've gone through a bunch of different merge policy approaches, and they all have the same problem.