Debugging Core Data __NSCFSet addObject nil exception
In swift 5
Create Persistence container
private final class PersistanceContainerProvider {
var container: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Test")
container.loadPersistentStores(completionHandler: { storeDescription, error in
if let error = error as NSError? {
fatalError("Unable to load persistance store")
}
})
return container
}()
}
Created ManagedContext with background concurrency
private init(persistentContainerProvider: DefaultPersistanceContainerProvider = PersistanceContainerProvider()){
self.persistentContainer = persistentContainerProvider.container
self.managedObjectContext = persistentContainer.newBackgroundContext()
print("Wasim \(self.managedObjectContext.concurrencyType.rawValue)")
}
Apply managedObjectContext.performAndWait
func addTargetCode(symbol: Symbol) {
managedObjectContext.performAndWait {
do {
if let existing = try managedObjectContext.fetch(ManagedTargetCurrency.fetchRequest(by: symbol.code)).first {
existing.code = symbol.code
existing.name = symbol.name
try save()
} else {
let added = (NSEntityDescription.insertNewObject(forEntityName: ManagedTargetCurrency.entityName, into: managedObjectContext) as? ManagedTargetCurrency).require(hint: "Wrong Core Data Configuration?")
added.code = symbol.code
added.name = symbol.name
try save()
}
} catch let error {
print(Errors.addError(cause: error))
}
}
}
Thanks to @bteapot for suggesting I add the -com.apple.CoreData.ConcurrencyDebug 1
argument to my scheme. I got more information on how this works from Ole Begemann's excellent Core Data Concurrency Debugging article.
Adding this flag causes an exception to be thrown as soon as your code calls into your NSManagedObjectContext
from an incorrect thread. This works great in Xcode, but be advised that in an Xcode Bot, this causes tests to fail with this unhelpful message:
Lost connection to test manager service