我正在尝试在Core Data中保存两个数组titles
和bodys
。我在代码中找不到错误。我认为下面的代码非常明显。我也无法判断我的问题是数据是否未正确保存,因此,下次无法加载。或者它保存得当,加载永远不会有效。
最后,每次打开应用程序时都会调用函数loadAPIData。
我首先想到的错误是它是一个线程问题
func loadCoreData() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Saved")
request.returnsObjectsAsFaults = false
do {
let results = try context.fetch(request)
for result in results as! [NSManagedObject]{
if let title = result.value(forKey: "title") as? String {
titles.append(title)
} else if let body = result.value(forKey: "body") as? String {
bodys.append(body)
}
}
} catch {
print("failed")
}
}
func saveCoreData() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Saved")
let request = NSBatchDeleteRequest(fetchRequest: fetch)
do {
_ = try context.execute(request)
} catch {
print("we could not delete")
}
//delete first ^^^
//save everything
let newValue = NSEntityDescription.insertNewObject(forEntityName: "Saved", into: context)
for a in 0..<bodys.count {
newValue.setValue(titles[a], forKey: "title")
newValue.setValue(bodys[a], forKey: "body")
do {
try context.save()
}
catch {
print("Did not save")
}
}
}
另一种可能有用的方法:
var titles: [String] = []
var bodys: [String] = []
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
titles.remove(at: indexPath.item)
bodys.remove(at: indexPath.item)
table.reloadData()
saveCoreData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadCoreData()
if (bodys.count == 0) {
loadAPIData()
saveCoreData()
}
//some ommited because irrelevant
}
答案 0 :(得分:0)
您必须在批量删除请求后合并更改。
我就是这样做的
let moc = context
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Members")
request.returnsObjectsAsFaults = false
moc.perform {
// create deletion request.
let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
deleteRequest.resultType = .resultTypeObjectIDs
do {
let resultBox = try moc.execute(deleteRequest) as! NSBatchDeleteResult
let objectIdArray = resultBox.result as? [NSManagedObjectID]
let changes = [NSDeletedObjectsKey : objectIdArray]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [moc])
do {
try context.save()
}
catch {
}
// save after deletion
for objectToSave in self.objectArray {
let object = NSEntityDescription.insertNewObject(forEntityName: "YourEntity", into: context)
objectToSave.setValue(member.duration, forKey: "duration")
do {
try context.save()
}
catch {
}
}
do {
let results = try context.fetch(request)
print(results.count)
}
catch {
print("Error")
}
}
catch {
print("error encountered")
abort()
}
}
答案 1 :(得分:0)
我认为你这一切都错了,在你的代码中使用Saved实体作为一个类,并跳过这个删除全部/插入你拥有的所有逻辑。
用
替换标题和正文数组var savedItems: [Saved]()
并将loadCoreData()中的do {}替换为
do {
savedItems() = try context.fetch(request)
}
只需执行
,就可以在tableView(... commit ...)方法中删除let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let saved = savedItems[indexPath.row]
context.delete(saved)
在saveCoreData()函数中,删除提取逻辑和删除逻辑,然后只保存上下文。
do {
try context.save()
} catch {
print("Did not save")
}
我没有指出你的代码有什么问题,但是这应该会使代码变得更简单,并且在我看来更容易找到任何错误。