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

时间:2019-06-18 19:32:22

标签: swift xcode core-data

我已经设置了一个tableview控制器,并将其用于带有核心数据的重量跟踪列表,以保存所有输入的内容。尽管一切正常,只要在打开应用程序时添加条目并显示它们,它就不会在下次应用程序加载时显示这些条目。对于快速编码来说,我的帮助相对较新,我对此表示赞赏。

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()
    }

}

1 个答案:

答案 0 :(得分:0)

将您的项目数组更新为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