NSManagedObject 和 Codable,用于存储在服务器和本地存储中的类



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

因此,我创建了一个 CoreData 托管类,该类表示我的对象,因此它继承了NSManagedObject.这将允许我处理本地存储,在存储中获取阵列,并在应用程序完成后放回一个新阵列。

然后我想使这个类可编码,这样我就可以实现required public init(from decoder: Decoder)方法,该方法允许我在 get 请求中获取这样的对象数组。JSONDecoder().decode([DataClass].self, from: data!).

我正在尝试两种方法,但它们都不起作用。

问题:

我在类范围内有一个private enum CodingKeys: String, CodingKey {...},使用它进行编码效果很好,但无论出于何种原因,都会触发一个错误,说该类没有实现我无意实现的编码。我不确定为什么这很重要。

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

作为替代方案:

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

你必须使DataClass符合Codable

首先创建两个扩展,以便能够传递JSONDecoderuserInfo字典中的NSManagedObjectContext

extension CodingUserInfoKey {
static let context = CodingUserInfoKey(rawValue: "context")!
}
extension JSONDecoder {
convenience init(context: NSManagedObjectContext) {
self.init()
self.userInfo[.context] = context
}
}

以下示例仅使用DataClass中的一个属性name
Codable方法必须位于类中,而不是在CoreDataProperties扩展中。

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)
}
}

要使用解码器,您必须使用初始值设定项

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

相关内容

  • 没有找到相关文章

最新更新