Я пытался решить эту проблему в течение некоторого времени, но безрезультатно.
При доступе к управляемому объекту из настраиваемого действия UserNotification, а затем при попытке сохранить изменения в этом объекте я получаю следующее сообщение:
[ошибка] ошибка: CoreData: ошибка: не удалось вызвать назначенный инициализатор для класса NSManagedObject «NSManagedObject».
По сути, установка выглядит следующим образом:
1. Пользователь получает уведомление
2. Выбирает пользовательское действие
3. Из информации в уведомлении делегат Центра UserNotification Centerизвлекает URI объекта, а затем извлекает его из постоянного хранилища
4. После завершения и приведения типа делегат вызывает соответствующий метод для объекта
5. После возврата метода делегат пытается сохранить контекст, и этогде появляется ошибка.
Вот соответствующий код:
// - UNUserNotification Centre delegate
extension HPBUserNotificationsHandler: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
guard let object = getAssociatedObject(id: response.notification.request.identifier) else { return }
switch response.actionIdentifier {
case UNNotificationDismissActionIdentifier:
....
case UNNotificationDefaultActionIdentifier:
....
case HPBReminderAction.take.rawValue:
// get intake object
guard let reminder = object as? HPBIntake else { return }
reminder.take(at: Date())
try! dataController.saveContext() // here is when the error is raised
default:
break
}
completionHandler()
}
Функция для извлечения объекта из постоянного хранилища:
func getAssociatedObject(id: String) -> NSManagedObject? {
guard let psc = dataController.managedObjectContext.persistentStoreCoordinator else { return nil }
guard let objURL = URL(string: id) else { return nil }
guard let moid = psc.managedObjectID(forURIRepresentation: objURL) else { return nil }
return dataController.managedObjectContext.object(with: moid)
}
Если я внесу те же изменения непосредственно в этот объектв приложении - все работает.Поэтому я предполагаю, что проблема заключается в получении объекта из настраиваемого действия в уведомлении пользователя.Но я не могу понять, в чем проблема.
Вот дополнительная информация.Когда я проверяю объект reminder
прямо перед вызовом функции take(on:)
, он выдает ошибку:
Home_Pillbox.HPBIntake: 0x7fb1a9074e90 (entity: Intake; id: 0x7fb1a9069e50 x-coredata: /// Intake / tAC4BBCD4-B128-4C6F-8E1B-2EE7D4EDBCB34; data: fault)
Конечно, при вызове функции выдается ошибка, но объект инициализируется неправильно и вместо этого заполняетсявсе свойства как nil
:
Home_Pillbox.HPBIntake: 0x7fb1a9074e90 (сущность: входная;{дозировка = 0; идентификатор = ноль; localNotification = ноль; журнал = ноль; прием пищи = 0; medName = ноль; уведомлениеRequest = ноль; profileName = ноль; расписание = ноль; статус = 1; лечение = ноль; единица измерения = 0; userNotes= nil;})
Поэтому, когда контекст пытается сохранить его, он не может этого сделать, так как свойства имеют значение nil
, что недопустимо в модели данных.Что также беспокоит меня, так это то, что в ошибке упоминается обозначенный инициализатор на NSManagedObject
вместо имени подкласса HPBIntake
, даже если объект четко введен правильно.
Любая помощь будет высоко оценена.
РЕДАКТИРОВАТЬ: Вот реализация функции saveContext()
в DataController:
func saveContext() throws {
if managedObjectContext.hasChanges {
do {
try managedObjectContext.save()
} catch let syserr as NSError {
throw syserror
}
}
}