尝试使用 coredata 保存待办事项列表不保存
Posted
技术标签:
【中文标题】尝试使用 coredata 保存待办事项列表不保存【英文标题】:Attempting to save todo list using coredata doesnt save 【发布时间】:2019-06-18 19:32:22 【问题描述】:我已经设置了一个 tableview 控制器,并将它用于带有 coredata 的重量跟踪列表,以保存所有的条目。虽然在应用程序打开时添加条目并显示它们,但在下一次应用程序加载时它不会显示这些条目。我很感谢您的帮助,因为我对 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()
【问题讨论】:
【参考方案1】:将你的 items 数组更新为 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
【讨论】:
以上是关于尝试使用 coredata 保存待办事项列表不保存的主要内容,如果未能解决你的问题,请参考以下文章