在我的应用程序中,我从 API 获取一些数据并将其保存到 Core Data。
然后,我希望能够通过获取新数据来更新我的数据,一旦获取成功(无连接错误),我想用新数据对象替换核心数据对象。但是当我尝试这样做时,我遇到了冲突错误......
这是我的代码:
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedObjectContext = appDelegate.persistentContainer.viewContext
// Try to fetch new data via API request
SDK.fetchData { result in
switch result {
case .success(let items):
// items are already NSManagedObjects decoded from a JSON
// Delete all data
let fetchRequest = Item.fetchRequest()
let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try managedObjectContext.execute(batchDeleteRequest)
} catch {
print(error)
}
// Save new data
do {
try managedObjectContext.save()
} catch {
print(error) // Here I get a conflict error
}
case .failure(let error):
// There has been an error, keep the old data
print(error)
}
}
为了更清楚,这里是 Item
类:
import CoreData
@objc(Item)
class Item: NSManagedObject, Decodable {
@NSManaged var id: String
@NSManaged var name: String
enum CodingKeys: String, CodingKey {
case id, name
}
required convenience init(from decoder: Decoder) throws {
guard let contextUserInfoKey = CodingUserInfoKey.managedObjectContext,
let managedObjectContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext,
let entity = NSEntityDescription.entity(forEntityName: "Item", in: managedObjectContext) else {
fatalError("Failed to decode Item")
}
self.init(entity: entity, insertInto: managedObjectContext)
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(String.self, forKey: .id)
self.name = try container.decode(String.self, forKey: .name)
}
}
关于如何在没有任何冲突的情况下实现这一点有什么想法吗?
最佳答案
根据您的代码,插入了新项目,随后所有项目都被删除了未提交的更改。
更好的工作流程是
- 将所有项目提取到一个临时变量中。
- 从 API 获取新项目。
- 成功提交更改(保存上下文)。
- 删除临时获取的项目,保留新项目。
- 再次保存上下文。
关于swift - 全部删除然后保存Core Data中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57505671/