核心数据 NSManagedObject 到 JSON 编码不起作用
Posted
技术标签:
【中文标题】核心数据 NSManagedObject 到 JSON 编码不起作用【英文标题】:CoreData NSManagedObject & JSON Encodable not working 【发布时间】:2019-10-04 12:22:00 【问题描述】:我正在尝试在 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))
我在这里做错了什么?
【问题讨论】:
嘿!你是如何解决这个问题的? 我也遇到了同样的问题 【参考方案1】:我终于让它工作了。这发生在我身上,因为我使用了一个符合 NSManagedObject 和 Decodable 的单独模型,就像 OP 的 Test 类一样。答案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)
【讨论】:
【参考方案2】:当您使用“新建文件...”手动添加子类时,可能会发生这种情况。
要将子类添加为项目中的可编辑类文件,而不是自己添加,请执行以下操作:
-
打开数据模型文件
在实体下,选择相关实体
在 Data model Inspector 中,确保“Codegen”设置为“Manual”
从上方菜单中,选择Editor -> Create NSManagedObject subclass...
【讨论】:
以上是关于核心数据 NSManagedObject 到 JSON 编码不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何在不复制目标 NSManagedObject 的情况下将目标 NSManagedObject 添加到另一个具有反向多对多核心数据关系的对象?
核心数据:更新 NSManagedObject 并选择回退到原始状态