我正在尝试在 iOS 13.1.2 和 Swift 4.2 上创建一个对象类,它既是符合 Encodable
又符合 NSManagedObject
的类。这是我的课:
import CoreData
class Test: NSManagedObject, Decodable {
@NSManaged var name: String?
enum CodingKeys: String, CodingKey {
case name
}
required convenience init(from decoder: Decoder) throws {
let managedContext = AppDelegate.persistentContainer.viewContext
guard let entity = NSEntityDescription.entity(forEntityName: "TestEntity", in: managedContext) else { fatalError() }
self.init(entity: entity, insertInto: managedContext)
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
}
}
还有我在 AppDelegate 中的 persistentContainer:
static var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "testContainer")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
我使用此方法创建我的 Test
类的新实例:
do {
let test = try JSONDecoder().decode(Test.self, from: "{\"name\":\"Test\"}".data(using: .utf8)!)
print(test.name)
} catch let error {
print(error)
}
但这给了我以下错误:
valueNotFound(Test.Test, Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data did not contain a top-level value.", underlyingError: nil))
我在这里做错了什么?
最佳答案
我终于让它工作了。这发生在我身上是因为我使用了一个单独的模型,该模型是我为符合 NSManagedObject 和 Decodable 而制作的,很像 OP 的测试类。答案here让我完成了部分工作,但我缺少的是,我没有使用单独的模型,而是必须修改生成的实体类以符合 Decodable 并将其用作我的可编码模型。
因此,在将 Codegen 更改为 Manual 并像上面提到的链接那样创建 NSManagedObject 类之后,您在文件 Test+CoreDataClass.swift 中的类变成了这样:
import CoreData
@objc(Test)
public class Test: NSManagedObject, Decodable {
@NSManaged var name: String?
enum CodingKeys: String, CodingKey {
case name
}
required convenience init(from decoder: Decoder) throws {
let managedContext = AppDelegate.persistentContainer.viewContext
guard let entity = NSEntityDescription.entity(forEntityName: "TestEntity", in: managedContext) else { fatalError() }
self.init(entity: entity, insertInto: managedContext)
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decodeIfPresent(String.self, forKey: .name)
}
}
关于ios - CoreData NSManagedObject 和 JSON Encodable 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58236346/