NSManagedObject和Codable用于存储在服务器和本地存储中的类 [英] NSManagedObject and Codable for class stored in server and local storage

查看:75
本文介绍了NSManagedObject和Codable用于存储在服务器和本地存储中的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个类,该类代表本地存储中或来自在线的数据。在运行时,我将使用get请求从服务器获取这些对象的数组,并将它们与CoreData中的现有对象进行比较,以确定将用于应用程序并存储的一组新对象。

I am creating a class that represents data that is either in local storage or comes in from online. On runtime I will use a get request to get an array of these objects from a server and compare them to the existing ones in CoreData in order to determine a new set of objects to be used for the app and to be stored.

这样,我创建了一个CoreData托管类,该类代表我的对象,因此它继承了 NSManagedObject 。这将使我能够处理本地存储,从而将阵列存储到存储中,并在应用程序完成后放回新存储。

As such I have created a CoreData managed class that represents my object as such it inherits NSManagedObject. This will allow me to deal with the local storage getting the array in storage and putting back a new one after the app has finished.

然后,我想做这个类可以这样编码,我可以实现所需的公共init(来自解码器:解码器)方法,该方法允许我在get请求中获取这样的对象数组。 JSONDecoder()。decode([DataClass] .self,from:data!)

I would then like to make this class Codable that way I can implement the required public init(from decoder: Decoder) method that allows me to get my array of objects like this in the get request. JSONDecoder().decode([DataClass].self, from: data!).

有两种方法我正在尝试执行此操作,但它们都不起作用。

There are two ways I am trying to do this and neither of them are working.

问题:

我在类范围内有一个私有枚举CodingKeys:String,CodingKey {...} 并使用它进行编码非常有用,但是由于某种原因会触发错误提示该类没有实现我无意实现的编码。我不确定为什么这么重要。

I have a private enum CodingKeys: String, CodingKey {...} in class scope and using that to encode works great but for whatever reason that triggers an error that says that the class doesn't implement encode which I have no intention of implementing. I am not sure why that matters.

我可以将枚举值放在初始化程序的范围内,但如果这样做,则会弹出一个新问题。我必须调用 NSManagedObject 的指定初始化程序。这是一个问题,因为该调用需要一个我没有的 NSManagedObjectContext

I can put the enum inside the scope of the initializer but if I do that a new problem pops up. I must call a designated initializer of NSManagedObject. This is a problem because that call requires a NSManagedObjectContext which I dont have.

作为替代:

我已经创建了一种方法 func getDataClass(来自解码器:Decoder)-> DataClass?,但这也带来了两个问题。我仍然必须以某种方式初始化 DataClass 对象,而且我不知道如何将其带入 JSONDecoder()。decode([DataClass] .self,来自:数据!)行。

I have create a method func getDataClass(from decoder: Decoder) -> DataClass? however this also brings with it two problems. I still must initialize a DataClass object somehow and I have no clue how to bring that into the JSONDecoder().decode([DataClass].self, from: data!) line.

推荐答案

您必须创建 DataClass 符合 Codable

首先创建两个扩展名,以便能够通过 JSONDecoder userInfo 词典中的 NSManagedObjectContext

First of all create two extensions to be able to pass the NSManagedObjectContext in the userInfo dictionary of the JSONDecoder.

extension CodingUserInfoKey {
    static let context = CodingUserInfoKey(rawValue: "context")!
}

extension JSONDecoder {
    convenience init(context: NSManagedObjectContext) {
        self.init()
        self.userInfo[.context] = context
    }
}






下面的示例仅在 DataClass 中使用一个属性 name

Codable 方法必须位于 CoreDataProperties 扩展名之外的类中。


The following example uses only one attribute name in DataClass.
The Codable methods must be in the class not in the CoreDataProperties extension.

class DataClass: NSManagedObject, Codable {

    private enum CodingKeys: String, CodingKey { case name }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(name, forKey: .name)
    }

    required convenience init(from decoder: Decoder) throws {
        guard let context = decoder.userInfo[.context] as? NSManagedObjectContext else { fatalError("Error: NSManagedObject not specified!") }
        let entity = NSEntityDescription.entity(forEntityName: "DataClass", in: context)!
        self.init(entity: entity, insertInto: context)
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decode(String.self, forKey: .name)
    }
}

要使用解码器,您必须使用初始化程序

To use the decoder you have to use the initializer

let context = // get the managed object context
let decoder = JSONDecoder(context: context)

这篇关于NSManagedObject和Codable用于存储在服务器和本地存储中的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆