问题描述
我正在创建一个类,该类代表本地存储中或来自在线的数据。在运行时,我将使用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用于存储在服务器和本地存储中的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!