1
votes

I am facing issues with my app where if i create or delete a new object, then save the object within a different entity object, then go back and try to make a new object of the first entity type, my app will crash.

I can then reopen then app and make the object that crashed the app with no issue.

This is all being done via core data, there is an exercise, exercises are saved as a routine, then creating a new exercise after having created a routine will crash the app. Furthermore, deleting an exercise and a routine then trying to create a new one straight after will also crash the app

I have spend a long time reading around this and believe the likely cause is managed object context and wondered if creating it as a singleton was the solution? I set up the MoC by running the below in each VC's viewdidload:

func getMainContext() -> NSManagedObjectContext {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    return appDelegate.persistentContainer.viewContext
}

I then reference this VC level variable via .self wherever i need to reference the MoC to avoid clashes with creating further MoC within a VC.

I believed this should prevent issues as all core data work is linked to the shared MoC. However as documented above, there are still crashes occurring.

Below is a console print of the crash which hopefully will narrow down the source.

fatal error: Failure to save context: Error Domain=NSCocoaErrorDomain Code=134020 "(null)" UserInfo={NSAffectedObjectsErrorKey= (entity: UserExercise; id: 0x600000025060

The code block this is triggering off as an example as 1 location in the app it occurs is included below, to clarify this only occurs when i just deleted other objects, if i reloaded the app now this code would work and save just fine:

func createExercise() {
    print("SAVE EXERCISE PRESSED")

    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.dateCreated = NSDate()
        newUserExercise.hasBeenTickedDone = false 

     } if self.associatedRoutineToAddTo != nil {

            let fetchRequest: NSFetchRequest<UserRoutine> = UserRoutine.fetchRequest()
            fetchRequest.predicate = NSPredicate(format: "name == %@", self.associatedRoutineToAddTo!)

            do {
                let existingUserRoutine = try self.managedObjectContext!.fetch(fetchRequest).first
                print("RETRIVED ROUTINES ARRAY CONTAINING \(existingUserRoutine)")
                existingUserRoutine?.addToUserexercises(newUserExercise) 
                print("EXERCISE SUCESSFULLY ADDED TO ROUTINE")
            } catch {
                print("Fetching Routine Failed")
            }
            } else if self.associatedRoutineToAddTo == nil {
            print("THIS IS A FRESH EXERCISE WITHOUT A PARENT ROUTINE")
        }

    } else if let userExercise = userExercise {
        print("UPDATING THE EXISTING EXERCISE")
        userExercise.name = userExerciseName.text
        userExercise.sets = Int64(userSetsCount)
        userExercise.reps = Int64(userRepsCount)
    }

    do {
        try self.managedObjectContext?.save()
        print("THE EXERCISE HAS BEEN SAVED")
    } catch {
        fatalError("Failure to save context: \(error)")
    }

The variable declarations are:

var managedObjectContext: NSManagedObjectContext!
var userExercise: UserExercise?
var associatedRoutineToAddTo : String?
var editingUserExerciseID: NSManagedObjectID?
var editingUserExercise: UserExercise?
1
Do you have any properties defined in your model as mandatory? do you have any other constraints defined in you model? - Jon Rose
everything is optional so i dont think this could be a cause, already checked it out! - jwarris91
Are you always running on the main thread? - Jon Rose
Id assume so, i dont set it be anything else? Im not too knowledgeable with threading coredata - jwarris91

1 Answers

0
votes

I was receiving the "NSCocoaErrorDomain Code=134020 (null)" error because my new entity was not added to the proper CoreData Configuration.