2017-01-27 16 views
0

Я добавляю только что созданное пользовательское упражнение к существующей пользовательской процедуре с помощью команды save. Чтобы объяснить приведенный ниже код, я устанавливаю objectcontext, тогда это упражнение новое (userExercise is nil) Я выполняю новый блок сохранения.Неустранимая ошибка при попытке сохранить основные объекты данных через связь

Затем я проверяю, добавлено ли это новое упражнение в существующую процедуру (связанныйRoutineToAddTo - это имя строковой подпрограммы из предыдущего VC).

Здесь проблема. Я пытаюсь получить объект UserRoutine, к которому он должен быть добавлен, используя предикат, основанный на имени подпрограмм, из строки, переданной из предыдущего VC. то я пытаюсь добавить упражнение к рутине. Это приводит к сбою.

Остальная часть кода не слишком уместна, так как она отлично работает с точки зрения сохранения редактирования или нового упражнения без родительской подпрограммы, а именно этой части.

Вот что я пытаюсь:

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") 
     } 
    } 

Ошибка гласит:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'usersroutine' between objects in different contexts (source = <UserExercise: 0x618000280e60> 

редактировать: пересмотренный мою выборку код для обзора:

 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) 
+1

Просьба показать журнал сбоя и распечатку ошибки – jrturton

+0

Я обновил OP – jwarris91

ответ

2

Вы создаете объект здесь:

let newUserExercise = UserExercise(context: self.managedObjectContext!)

И получать связанный объект здесь:

let existingUserRoutine = UserRoutine(context: managedObjectContext)

Вы создали локальную переменную с именем managedObjectContext здесь:

let managedObjectContext = getMainContext()

И ваша ошибка гласит:

попытка установить отношения «usersroutine» между объектами в различных контекстах

Таким образом, ваше имущество managedObjectContext не то же самое, что и возвращаемый getMainContext()

В дополнение ко всему этому вы создаете совершенно новый UserRoutine и присваиваете его значению existingRoutine, а затем создаете запрос на выборку, который вы ничего не делаете ч, что говорит о том, что вы немного смущены тем, что должно происходить здесь.

+0

Я удалил self, так что оба контекста управляютсяObjectContext и это разрешает сбой, однако, как вы сказали, похоже, просто создайте новый рутина. Я немного смущен, поскольку Im не имеет опыта в основных данных. как я мог бы успешно добавить упражнение в рутину и сохранить существующую рутину, а не новую рутину? Цените совет – jwarris91

+0

Вместо того, чтобы создавать новую процедуру, выполните запрос на выборку и используйте результат – jrturton

+0

Я добавил исправленный код в нижней части моего OP, я знаю его не на 100%, поскольку у меня есть ошибки, но верно ли эта логика? запросить пользовательские подпрограммы на основе предиката существующего имени подпрограмм, а затем установить этот результат как существующую процедуру и добавить пользовательское упражнение в подпрограмму? – jwarris91

0

Когда вы делаете UserExcercise вас ссылаются на контекст, сохраненный на вашем VC:

let newUserExercise = UserExercise(context: self.managedObjectContext!) 

Тогда

 let existingUserRoutine = UserRoutine(context: managedObjectContext) 

Контекст getMainContext() приобретают здесь?