核心数据 – 如何在核心数据中使用swift 4 Codable?
发布时间:2020-12-14 05:49:32 所属栏目:百科 来源:网络整理
导读:Codable似乎是一个非常令人兴奋的功能。但我想知道如何在核心数据中使用它?特别是,是否可以直接从/向NSManagedObject编码/解码JSON? 我尝试了一个非常简单的例子: 并自己定义了Foo: import CoreData@objc(Foo)public class Foo: NSManagedObject,Codabl
Codable似乎是一个非常令人兴奋的功能。但我想知道如何在核心数据中使用它?特别是,是否可以直接从/向NSManagedObject编码/解码JSON?
我尝试了一个非常简单的例子: 并自己定义了Foo: import CoreData @objc(Foo) public class Foo: NSManagedObject,Codable {} 但是当像这样使用它时: let json = """ { "name": "foo","bars": [{ "name": "bar1",}],[{ "name": "bar2" }] } """.data(using: .utf8)! let decoder = JSONDecoder() let foo = try! decoder.decode(Foo.self,from: json) print(foo) 编译器因此错误而失败: super.init isn't called on all paths before returning from initializer 目标文件是定义Foo的文件 我想我可能做错了,因为我甚至没有传递NSManagedObjectContext,但我不知道在哪里坚持它。 Core Data是否支持Codable?
您可以将Codable接口与CoreData对象一起使用来对数据进行编码和解码,但是它不像使用普通的旧swift对象那样自动化。以下是如何使用Core Data对象直接实现JSON解码:
首先,使对象实现Codable。必须在对象上定义此接口,而不是在扩展中定义。您还可以在此课程中定义编码密钥。 class MyManagedObject: NSManagedObject,Codable { @NSManaged var property: String? enum CodingKeys: String,CodingKey { case property = "json_key" } } 接下来,您可以定义init方法。这也必须在类方法中定义,因为Decodable协议需要init方法。 required convenience init(from decoder: Decoder) throws { } 但是,与托管对象一起使用的正确初始化程序是: NSManagedObject.init(entity: NSEntityDescription,into context: NSManagedObjectContext) 所以,这里的秘密是使用userInfo字典将适当的上下文对象传递给初始化器。为此,您需要使用新密钥扩展CodingUserInfoKey结构: extension CodingUserInfoKey { static let context = CodingUserInfoKey(rawValue: "context") } 现在,您可以作为上下文的解码器: required convenience init(from decoder: Decoder) throws { guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError() } guard let entity = NSEntityDescription.entity(forEntityName: "MyManagedObject",in: context) else { fatalError() } self.init(entity: entity,in: context) let container = decoder.container(keyedBy: CodingKeys.self) self.property = container.decodeIfPresent(String.self,forKey: .property) } 现在,当您为托管对象设置解码时,您需要传递正确的上下文对象: let data = //raw json data in Data object let context = persistentContainer.newBackgroundContext() let decoder = JSONDecoder() decoder.userInfo[.context] = context _ = try decoder.decode(MyManagedObject.self,from: data) //we'll get the value from another context using a fetch request later... try context.save() //make sure to save your data once decoding is complete 要编码数据,您需要使用编码协议功能执行类似操作。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |