swift - 尝试使用 coredata 保存待办事项列表不会保存

标签 swift xcode core-data

我已经设置了一个表格 View Controller ,并将其用于带有核心数据的体重跟踪列表,以保存所有所做的条目。虽然在应用程序打开时添加条目并显示它们一切正常,但它不会在下一次应用程序加载时显示这些条目。我很感谢您的帮助,因为我对 swift 编码还比较陌生。

data model screenshot

import UIKit
import CoreData

class TodoViewController: UITableViewController {

    var items = [Items]()

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    var selectedCategory: Items?{
        didSet{
            loadItems()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //MARK: Table View Datasource Methods
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Item", for: indexPath)
        let item = items[indexPath.row]
        cell.textLabel?.text = item.name
        cell.accessoryType = item.completed ? .checkmark : .none
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        items[indexPath.row].completed = !items[indexPath.row].completed
        saveItems()
    }

    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == .delete){
            let item = items[indexPath.row]
            items.remove(at: indexPath.row)
            context.delete(item)

            do{
                try context.save()
            }catch{
                print("Error deleting item with \(error)")
            }
            tableView.deleteRows(at: [indexPath], with: .automatic)
        }
    }

    @IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
        var textField = UITextField()
        let alert = UIAlertController(title: "Add New Weight", message: "", preferredStyle: .alert)
        let action = UIAlertAction(title: "Save", style: .default) { (action) in

            let newItem = Items(context: self.context)
            newItem.name = textField.text!
            self.items.append(newItem)
            self.saveItems()
        }
        alert.addAction(action)
        alert.addTextField { (field) in
            textField = field
            textField.placeholder = "Add Weight"
        }
        present(alert, animated: true, completion: nil)
}
    func saveItems(){
        do{
            try context.save()
        }catch{
            print("Error Saving item with \(error)")
        }
        self.tableView.reloadData()
    }

    func loadItems(){
        let request: NSFetchRequest<Items> = Items.fetchRequest()

        do{
            items = try context.fetch(request)
        }catch{
            print("Error fetching data from context \(error)")
        }
        tableView.reloadData()
    }

}

最佳答案

将您的项目数组更新为 NSManagedObject

var items: [NSManagedObject] = []

使用此方法进行保存并从保存操作中调用它:

func save(name: String, completed: Bool) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
  return
}

let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Items", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
item.setValue(name, forKeyPath: "name")
item.setValue(completed, forKeyPath: "completed")

do {
  try managedContext.save()
  items.append(item)
} catch let error as NSError {
  print("Could not save. \(error), \(error.userInfo)")
}
}

要加载项目,请使用此方法:

func loadItems() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
  return
}

let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Items")

do {
  items = try managedContext.fetch(fetchRequest)
} catch let error as NSError {
  print("Could not fetch. \(error), \(error.userInfo)")
}
}

然后将 cellForRowAtIndexPath 方法更新为如下所示:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Item", for: indexPath)
    let item = items[indexPath.row]
    cell.textLabel?.text = item.value(forKeyPath: "name") as? String
    cell.accessoryType = item.value(forKeyPath: "completed") as? Bool ? .checkmark : .none
    return cell
}

使用 KVC 访问数组项中的任何属性,如下所示:

item.value(forKeyPath: "name") as? String

关于swift - 尝试使用 coredata 保存待办事项列表不会保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56655872/

相关文章:

ios - 两天后核心数据消失

cocoa - 使用核心数据时出现问题

ios - 默认上下文为零!你忘记初始化核心数据栈了吗? [魔法唱片]

arrays - 自定义单元格在 TableView 中全白

swift - "Cannot assign value of type ' 整数 ' to type ' 单位 ' "

swift - GKState : Why is self. 状态机 == nil?

iphone - 根据 Setting.bundle 切换开关状态更改应用程序的 MainView?

ios - 无法快速编译着色器

ios - 仅限生产版本的 EXC_BREAKPOINT (SIGTRAP)

ios - 用于在设备上分析 ui 自动化的正确构建选项/代码签名/方案设置是什么?