I am adding a newly created user exercise to an existing user routine via a save command. To explain the code below, I set the objectcontext, then is the exercise is new (userExercise is nil) I execute a new save block.
I then check if this new exercise is being added to an existing routine (associatedRoutineToAddTo is a string routine name from the previous VC).
This is where the issue is. I attempt to get the UserRoutine object that it needs to be added to, using a predicate based on the routines name from the string i passed from the previous VC. then i attempt to add the exercise to the routine. This causes the crash.
The rest of the code isnt too relevant as it works fine in terms of saving an edit or new exercise with no parent routine, its just this one part.
Here is what I am trying:
func getMainContext() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
func createExercise() {
print("SAVE EXERCISE PRESSED")
let managedObjectContext = getMainContext()
if userExercise == nil {
print("SAVING THE NEW EXERCISE")
let newUserExercise = UserExercise(context: self.managedObjectContext!)
newUserExercise.name = userExerciseName.text
newUserExercise.sets = Int64(userSetsCount)
newUserExercise.reps = Int64(userRepsCount)
newUserExercise.weight = Double(self.userExerciseWeight.text!)!
newUserExercise.dateCreated = NSDate()
if self.associatedRoutineToAddTo != nil {
let existingUserRoutine = UserRoutine(context: managedObjectContext)
let request: NSFetchRequest<UserExercise> = UserExercise.fetchRequest()
request.predicate = NSPredicate(format: "usersroutine.name == %@", self.associatedRoutineToAddTo!)
existingUserRoutine.addToUserexercises(newUserExercise)
do {
try managedObjectContext.save()
} catch {
fatalError("Failure to save context: \(error)")
}
} else if self.associatedRoutineToAddTo == nil {
print("THIS IS A FRESH EXERCISE WITHOUT A PARENT ROUTINE")
}
}
The error reads:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'usersroutine' between objects in different contexts (source = <UserExercise: 0x618000280e60>
edit: revised my fetch code for review:
let fetchRequest: NSFetchRequest<UserRoutine> = UserRoutine.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "usersroutine.name == %@", self.associatedRoutineToAddTo!)
do {
existingUserRoutine = try managedObjectContext.fetch(fetchRequest) as! UserRoutine
print("Routine Below Fetched")
print(existingUserRoutine)
} catch {
print("Fetch Failed")
}
existingUserRoutine.addToUserexercises(newUserExercise)
You create the object here:
let newUserExercise = UserExercise(context: self.managedObjectContext!)
And fetch the related object here:
let existingUserRoutine = UserRoutine(context: managedObjectContext)
You've created a local variable called managedObjectContext
here:
let managedObjectContext = getMainContext()
And your error states:
attempt to establish a relationship 'usersroutine' between objects in different contexts
Therefore, your property managedObjectContext
is not the same as that returned by getMainContext()
In addition to all that, you're creating a brand new UserRoutine
, and assigning it to a value called existingRoutine
, then creating a fetch request that you don't do anything with, which suggests you're a little confused about what is supposed to be happening here.