How To Save Re-Ordered Tableview Cells To Core Data

送分小仙女□ 提交于 2020-07-10 03:51:39

问题


So I have my tableview when I re-order my rows it updates the tableview and everything but it isn't saving to core data.

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {


    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext
    let movedCampSites = itemName[sourceIndexPath.item]
    itemName.remove(at: sourceIndexPath.item)
    itemName.insert(movedCampSites, at: destinationIndexPath.item)
    context.delete(itemName[sourceIndexPath.row])
    context.insert(itemName[destinationIndexPath.row])

    do
    {
        try context.save()
    }
    catch
    {
        print("Could not move rows")
    }



}

Everything works up till context.insert(itemName[destinationIndexPath.row]) for example if I comment that out and run it, it will move the rows and delete the row and save to core data, but the context.insert doesn't save the new row position. For some reason it is running my catch block as I am getting the error Could not move rows.

Here is some of the error that is in the console.

2018-07-22 09:27:01.884925-0700 Search Bar Core Data[67957:5383630] [error] error: (1555) UNIQUE constraint failed: ZTITLE.Z_PK CoreData: error: (1555) UNIQUE constraint failed: ZTITLE.Z_PK Could not move rows

Thanks in advance.


回答1:


Here is my take on this issue:

Like 'vadian' said, when you create an object you add a property for the array that appends to the Core Data, like this,

var itemsArray: [NSManagedObject] = []

save(sortOrder: itemsArray.count, item: itemTextField.text!) //Calling the save method wherever you need to, catching for example a UITextField user input

private func save(sortOrder: Int, item: String) {

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    let context = appDelegate.persistentContainer.viewContext
    guard let entity = NSEntityDescription.entity(forEntityName: "CoreDataBaseName", in: context) else { return }
    let itemManagedObject = NSManagedObject(entity: entity, insertInto: context)

    itemManagedObject.setValue(sortOrder, forKeyPath: "sortOrder")
    itemManagedObject.setValue(item, forKeyPath: "item")

    do {
        try context.save()
        itemsArray.append(itemManagedObject)

    } catch let error as NSError {
        print("Could not save item to Core Data: \(error)")
    }
}

Then we come to the tableView's moveRowAt method,

override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    let context = appDelegate.persistentContainer.viewContext
    let movedItem = itemsArray[sourceIndexPath.row]

    itemsArray.remove(at: sourceIndexPath.row)
    itemsArray.insert(movedItem, at: destinationIndexPath.row)

    //This 'for-in loop' is at the heart of the solution
    for (i, item) in itemsArray.enumerated() {
        item.setValue(i, forKey: "sortOrder")
    }

    do {
        try context.save()
    } catch let error as NSError {
        print("Could not save/persist Core Data items in moveRowAt: \(error)")
    }
}

... And at the end of everything we fetch the rearranged order with,

private func fetch() {

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    let context = appDelegate.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "CoreDataBaseName")
    let sortDescriptor = NSSortDescriptor(key: "sortOrder", ascending: true)

    fetchRequest.sortDescriptors = [sortDescriptor]

    do {
        itemsArray = try context.fetch(fetchRequest)
    } catch let error as NSError {
        print("Could not fetch Core Data entities: \(error)")
    }
}

There's a million different ways that you can improve this idea (which is always welcome), but this is a pedagogical example of a solution.

I hope it can help somebody out there!



来源:https://stackoverflow.com/questions/51467055/how-to-save-re-ordered-tableview-cells-to-core-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!