2016-03-13 2 views
2

При использовании NSFetchedResultsController в моем представлении таблицы данные отображаются правильно сразу после создания нового объекта NSManagedObject, но все строки/разделы удаляются после обновляя его. Ниже, когда вызывается метод update(), и контакт сохраняется, мои операторы печати выводят, что строки и разделы удаляются из представления таблицы. Когда вызывается метод create(), строки/разделы вставляются (как и ожидалось).NSFetchedResultsController удаляет строки вместо их обновления после обновления Core Data

Вот два различных набора продукции после запуска:

enter image description hereenter image description here

После извлечения информации из запроса API, я обновить соответствующую модель ядра данных, как показано ниже, если элемент уже существует (как обозначено уникальный идентификатор):

func update(oldContact: NSManagedObject) -> Bool { 

    //updates contact 
    let contact = populateObject(oldContact) 

    // Delete existing phones 
    if let phoneDataSet = contact.valueForKeyPath("phones") { 
     let phonesArray = phoneDataSet.allObjects as! [NSManagedObject] 
     for object in phonesArray { 
      context.deleteObject(object) 
     } 
    } 
    // Add phones from response 
    for phone in phones { 
     phone.createForContact(contact) 
    } 

    // Save contact 
    do { 
     try contact.managedObjectContext?.save() 
     print("saving contact") 
     return true 
    } catch { 
     let nserror = error as NSError 
     print("error upong saving") 
     NSLog("Unresolved error \(nserror), \(nserror.userInfo)") 
     abort() 
    } 

    return false 
} 

    func populateObject(object: NSManagedObject) -> NSManagedObject { 

    object.setValue(self.name, forKey: "name") 
    object.setValue(self.id, forKey: "id") 
    object.setValue(self.firstLetter, forKey: "firstLetter") 

    return object 
    } 

Если элемент не существует уже в основных данных, он создается следующим образом:

func create() -> Bool { 

    // Quit if contact already exists. 
    let data = CoreData().searchObject("Contact", predicate: "id", value: String(self.id)) 
    guard data == nil else { fatalError("Attempted to insert duplicate contact") } 

    //creates a new contact NSManagedObject 
    var newContact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: context) 
    //sets the contact values 
    newContact = populateObject(newContact) 

    //creates Phone NSManagedObject, then makes a relationship with contact 
    for phone in self.phones { 
     phone.createForContact(newContact) 
    } 

    do { 
     //saves the contact object; also saves the relationship with the phone number 
     try newContact.managedObjectContext?.save() 
     print("Creating contact") 
     return true; 
    } catch { 
     let nserror = error as NSError 
     NSLog("Unresolved error \(nserror), \(nserror.userInfo)") 
     abort() 
    } 

    return false 
} 

Мои FetchedResultsController методы делегата, как показано ниже:

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 
    switch (type) { 
    case .Update: 
     if let indexPath = indexPath { 
      if let cell = tableView.cellForRowAtIndexPath(indexPath) as? PeopleAndPlaceCell { 
       configureCell(cell, atIndexPath: indexPath) 
       tableView.reloadRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade) 
       print("UPDATING ROW") 
      } 
     } 
     break; 
    case .Insert: 
     if let indexPath = newIndexPath { 
      tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
      print("INSERTING ROW") 
     } 
     break; 
    case .Delete: 
     if let indexPath = indexPath { 
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
      print("DELETING ROW") 
     } 
     break; 
    case .Move: 
     if let indexPath = indexPath { 
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 

     if let newIndexPath = newIndexPath { 
      tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
     } 
     break; 
    } 
} 

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { 
    switch type { 
    case .Update: 
     print("UPDATE SECTION") 
     break 
    case .Insert: 
     self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
     print("INSERTING SECTION") 
    case .Delete: 
     self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
     print("DELETING SECTION") 
    case .Move: 
     break 
    } 
} 

UPDATE:

Связь для контакта с телефона является один ко многим, и с телефона на контакт является To-один , Правило удаления контактных отношений в объекте Phone является Cascade. Это также Cascade для отношений телефона в объекте Contact.

+0

Что такое правило удаления отношения 'contact' в сущности' Phone'? – pbasdf

+0

По моему вопросу я включил обновление, чтобы ответить на ваш вопрос. –

ответ

1

Проблема заключается в правиле удаления «Каскад» для отношения contact объекта Phone. В вашем методе update() вы удаляете все «старые» Phone объектов для данного Contact. Правило удаления каскада также приводит к удалению Contact. Измените это правило удаления на «Nullify». (Вы можете оставить обратную связь, phones, в объекте Contact, как «Каскад»: при удалении Contact он удалит все связанные Phones).

+0

Это было! Большое спасибо –

 Смежные вопросы

  • Нет связанных вопросов^_^