I have save values to entity method which save new data and updates existing data.
func saveSteps(_ serverJson: [[String: Any]]){
let stepService = StepService(context: context);
if(serverJson.count > 0){
for step in serverJson {
let stepTitle = step["stepTitle"] as? String ?? ""
let stepDescription = step["stepDescription"] as? String ?? ""
let stepId = step["_id"] as? String ?? ""
let predicate: NSPredicate = NSPredicate(format: "stepId=%@", stepId)
let stepList = stepService.get(withPredicate: predicate);
if(stepList.count == 0){
stepService.create(stepId: stepId, stepTitle: stepTitle, stepDescription: stepDescription);
}else{
if let updatableStep = stepList.first{
updatableStep.stepDescription = stepDescription //EXC_BAD_ACCESS Error Here
updatableStep.stepName = stepName
updatableStep.stepTitle = stepTitle
stepService.update(updatedStep: updatableStep)
}else{
stepService.create(stepId: stepId, stepTitle: stepTitle, stepDescription: stepDescription);
}
}
saveContext()
}
My Create update and get methods are in stepService
func create(stepId:String, stepDescription: String, stepTitle:String){
let newItem = NSEntityDescription.insertNewObject(forEntityName: "Steps", into: context) as! Steps //EXC_BAD_ACCESS Error Here
newItem.stepId = stepId
newItem.stepTitle = stepTitle
newItem.stepDescription = stepDescription
}
func update(updatedStep: Steps){
if let step = getById(id: updatedStep.objectID){
step.stepId = updatedStep.stepId
step.stepTitle = updatedStep.stepTitle
step.stepDescription = updatedStep.stepDescription
}
func get(withPredicate queryPredicate: NSPredicate) -> [Steps]{
let fetchRequest: NSFetchRequest<Steps> = Steps.fetchRequest()
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = queryPredicate
do {
let response = try context.fetch(fetchRequest)
return response
} catch let error as NSError {
// failure
print(error)
return [Steps]()
}
}
}
Mysave context method is
// Creating private queue to save the data to disk
lazy var savingModelcontext:NSManagedObjectContext = {
var managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = self.coordinator
return managedObjectContext
}()
// Creating Context to save in block main queue this will be temporary save
lazy var context:NSManagedObjectContext = {
var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.parent = self.savingModelcontext
return managedObjectContext
}()
func saveContext () {
guard savingModelcontext.hasChanges || context.hasChanges else {
return
}
context.performAndWait {
do {
try self.context.save()
} catch let error as NSError {
print("Could not save in Context: \(error.localizedDescription)")
}
}
savingModelcontext.perform {
do {
try self.savingModelcontext.save()
} catch let error as NSError {
print("Could not save savingModelContext: \(error.localizedDescription)")
}
}
}
There are two places that core data crashes with same error message one is when i access the data to update the method and other is when i am trying to create a new item using NSEntityDescription.insertNewObject with entity name. while saing i have tried Dispach queue with qos of userInitiated and default. I didn't use background as user might open some thing that might use this.
The problem is the crash is not consistanct and has never crashed when doing a debug which leads me to belive it is concurrency issue but the data is never deleted or read when being updated.
PS: I have read the questions with same and similar issues but i could not get a working answer here the question.
Kidly point out if i have made any mistakes
Thanks any help is appreciated