I am trying to update an entity in Coredata using the background/thread. I am passing two variables in the below function, one is date and the other one is Account that has 'to one' relationship with the transaction attribute. I am getting an error when I execute the below code.
The goal is to perform updates to coredata without freezing the tableview and other controls/views.
ERROR - *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'account' between objects in different contexts
public class Transaction: NSManagedObject {
@NSManaged public var transDate: Date?
@NSManaged public var account: Account?
class func addTransaction(transDate : Date, transAccount : Account){
let appDelegate = NSApplication.shared.delegate as! AppDelegate
appDelegate.persistentContainer.performBackgroundTask({ (context) in
let entity = NSEntityDescription.entity(forEntityName: "Transaction", in: context)
let CD = Transaction(entity: entity!, insertInto: context)
CD.transDate = transDate //updated successfully
CD.account = transAccount//Gets an error while performing this line of code.
do {
try context.save()
}
catch {
print("error in saving Transaction data")
}
})
}
}
CodePudding user response:
You can not use objects from different context together, the transaction object is created in your background context but the account object is from your main context.
The solution is to get the corresponding account object from the background context using the objectID which is always the same between contexts.
let account = context.existingObject(with: transAccount.objectID)) as? Account
CD.account = account
Note that account
is optional here so you need to add some error handling in case it is nil, this should never happen but still it needs to be handled.