如何防止核心数据中的删除规则拒绝错误,Swift 3

时间:2017-02-25 15:53:52

标签: core-data swift3

如何防止删除规则拒绝错误?我有一个警告要求用户删除记录,但检查是否可以删除它是在核心数据堆栈的save方法中首先发生的。我试图抓住它:

if (self?.categoryToEdit.toMyplace == nil){
        let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
        let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
            self?.tableView.setEditing(false, animated: true)
            self?.attemptFetch()
            self?.tableView.reloadData()
            return
        })
        alertController.addAction(cancelButton)
        self?.present(alertController, animated: false, completion: nil)
    }else{
        self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
    }

所以我从编译器收到错误:致命错误:在展开可选值时意外发现nil

我该如何解决?

提前致谢!!!!

修改

谢谢! 这里是完整的代码。 它从tableView操作开始,并转发到处理警报的单独函数。此功能中未注释的部分并不真正起作用。我在处理错误时首先收到警报。 如果记录没有从tableView中消失并且在工作数组的索引中留下香,那么这不会是一个巨大的问题。 这个问题一直存在,直到应用程序将重新启动,没有机会获得未删除的记录。我尝试新的获取请求并重新加载表日期,但它一直保持到新的开始。

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let edit = UITableViewRowAction(style: .normal, title: "Ändern") { [weak self] action, index in
        self?.editMode = true
        let cell = tableView.cellForRow(at: indexPath) as! CategoryTVCell
        self?.configureCell(cell: cell, indexPath: indexPath)
        context.performAndWait{
            if let obj = self?.controller.fetchedObjects , obj.count > 0 {
                self?.categoryToEdit = obj[indexPath.row]
                self?.categoryToEditName = self?.categoryToEdit.name!
            }
        }
        self?.showAlertWithText()
        self?.showAlertWithText()
        tableView.isEditing = false
    }

    let delete = UITableViewRowAction(style: .normal, title: "Löschen") { [weak self] action, index in
        self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
    }

    edit.backgroundColor = UIColor(colorLiteralRed: 179.0/255.0, green: 179.0/255.0, blue: 179.0/255.0, alpha: 1)
    delete.backgroundColor = myRedAlertColor
    return [delete, edit]
}
private func displayActionSheet(indexPath: NSIndexPath)
{   let categoryName = categoryArray[indexPath.row]
    let alertController = UIAlertController(title: "Kategorie löschen", message: "Soll die Kategorie " + categoryName + " gelöscht werden?\r\nDie Kategorie kann nur gelöscht werden, wenn kein myPlace damit verbunden ist!", preferredStyle: .actionSheet)

    let deleteCategory = UIAlertAction(title: "Löschen", style: .destructive, handler: { [weak self](action) -> Void in
        self?.tableView.isEditing = false
        //if (self?.categoryToEdit.toMyplace == nil)/*((self?.myPlace?.toCateogry == nil))*/{
            context.delete((self?.controller.fetchedObjects?[indexPath.row])!)
            self?.categoryArray.remove(at: indexPath.row)
            self?.attemptFetch()
            self?.tableView.reloadData()
        //}else{
            /*let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
            let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
                self?.tableView.setEditing(false, animated: true)
                self?.attemptFetch()
                self?.tableView.reloadData()
            })
            alertController.addAction(cancelButton)
            self?.present(alertController, animated: false, completion: nil)*/
        //}
        do{
            try context.save()
        }catch{
            let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nAlle myPlaces verlieren sonst diese Zuordnung!", preferredStyle: .actionSheet)
            let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
                self?.tableView.setEditing(false, animated: true)
                self?.attemptFetch()
                self?.tableView.reloadData()
            })
            alertController.addAction(cancelButton)
            self?.present(alertController, animated: false, completion: nil)

        }
    })

    let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
        self?.tableView.setEditing(false, animated: true)
    })

    alertController.addAction(deleteCategory)
    alertController.addAction(cancelButton)
    alertController.view.tintColor = .orange //UIColor(red: 0, green: 0, blue: 51)
    //self.navigationController!.present(alertController, animated: true, completion: nil)
    present(alertController, animated: false, completion: nil)
}

2 个答案:

答案 0 :(得分:0)

谢谢! 这里是完整的代码。 它从tableView操作开始,并转发到处理警报的单独函数。此功能中未注释的部分并不真正起作用。我在处理错误时首先收到警报。 如果记录没有从tableView消失并且在工作数组的索引中留下香,那将不会是一个巨大的问题。 这个问题一直存在,直到应用程序将重新启动,没有机会获得未删除的记录。我尝试新的获取请求并重新加载表日期,但它一直保持到新的开始。

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let edit = UITableViewRowAction(style: .normal, title: "Ändern") { [weak self] action, index in
        self?.editMode = true
        let cell = tableView.cellForRow(at: indexPath) as! CategoryTVCell
        self?.configureCell(cell: cell, indexPath: indexPath)
        context.performAndWait{
            if let obj = self?.controller.fetchedObjects , obj.count > 0 {
                self?.categoryToEdit = obj[indexPath.row]
                self?.categoryToEditName = self?.categoryToEdit.name!
            }
        }
        self?.showAlertWithText()
        self?.showAlertWithText()
        tableView.isEditing = false
    }

    let delete = UITableViewRowAction(style: .normal, title: "Löschen") { [weak self] action, index in
        self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
    }

    edit.backgroundColor = UIColor(colorLiteralRed: 179.0/255.0, green: 179.0/255.0, blue: 179.0/255.0, alpha: 1)
    delete.backgroundColor = myRedAlertColor
    return [delete, edit]
}
private func displayActionSheet(indexPath: NSIndexPath)
{   let categoryName = categoryArray[indexPath.row]
    let alertController = UIAlertController(title: "Kategorie löschen", message: "Soll die Kategorie " + categoryName + " gelöscht werden?\r\nDie Kategorie kann nur gelöscht werden, wenn kein myPlace damit verbunden ist!", preferredStyle: .actionSheet)

    let deleteCategory = UIAlertAction(title: "Löschen", style: .destructive, handler: { [weak self](action) -> Void in
        self?.tableView.isEditing = false
        //if (self?.categoryToEdit.toMyplace == nil)/*((self?.myPlace?.toCateogry == nil))*/{
            context.delete((self?.controller.fetchedObjects?[indexPath.row])!)
            self?.categoryArray.remove(at: indexPath.row)
            self?.attemptFetch()
            self?.tableView.reloadData()
        //}else{
            /*let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nSie ist ", preferredStyle: .actionSheet)
            let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
                self?.tableView.setEditing(false, animated: true)
                self?.attemptFetch()
                self?.tableView.reloadData()
            })
            alertController.addAction(cancelButton)
            self?.present(alertController, animated: false, completion: nil)*/
        //}
        do{
            try context.save()
        }catch{
            let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName + " kann nicht gelöscht werden!\r\nAlle myPlaces verlieren sonst diese Zuordnung!", preferredStyle: .actionSheet)
            let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
                self?.tableView.setEditing(false, animated: true)
                self?.attemptFetch()
                self?.tableView.reloadData()
            })
            alertController.addAction(cancelButton)
            self?.present(alertController, animated: false, completion: nil)

        }
    })

    let cancelButton = UIAlertAction(title: "Abbrechen", style: .cancel, handler: { [weak self](action) -> Void in
        self?.tableView.setEditing(false, animated: true)
    })

    alertController.addAction(deleteCategory)
    alertController.addAction(cancelButton)
    alertController.view.tintColor = .orange //UIColor(red: 0, green: 0, blue: 51)
    //self.navigationController!.present(alertController, animated: true, completion: nil)
    present(alertController, animated: false, completion: nil)
}

答案 1 :(得分:0)

这里是解决方案:

let delete = UITableViewRowAction(style: .normal, title: "Löschen") 
{ 
   [weak self] action, index in

    do{
          try self?.controller.fetchedObjects?[indexPath.row].validateForDelete()
          self?.displayActionSheet(indexPath: indexPath as NSIndexPath)
       }catch{
          let categoryName = self?.categoryArray[indexPath.row]
          let alertController = UIAlertController(title: "Kategorie löschen", message: "Die Kategorie " + categoryName! + " kann nicht gelöscht werden!\r\nSie wird bereits verwendet!", preferredStyle: .actionSheet)
          let cancelButton = UIAlertAction(title: "Abbrechen", 
                                           style: .cancel, handler: { 

                        [weak self](action) -> Void in
                        self?.tableView.setEditing(false, animated: true)
                        self?.attemptFetch()
                        self?.tableView.reloadData()
            })

          alertController.addAction(cancelButton)
          self?.present(alertController, animated: false, completion: nil)
      }
}

这只是函数.validateForDelete()