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

标签 ios swift xcode core-data codable

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

因此,我创建了一个 CoreData 托管类来表示我的对象,因此它继承了 NSManagedObject。这将使我能够处理本地存储,将数组放入存储中,并在应用程序完成后放回一个新数组。

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

我尝试了两种方法来做到这一点,但都不起作用。

问题:

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

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

替代方案:

我创建了一个方法 func getDataClass(from detector: 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)

关于ios - NSManagedObject 和 Codable 用于存储在服务器和本地存储中的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52459182/

相关文章:

ios - 如何在 Xcode 4.2 中启用 ARC 项目范围

iphone - 在格式化价格时获取 NSNumberFormatter 以拼出货币

ios - 检测文本字段应该从TableViewController中的Custom UITableViewCell返回以添加新行

ios - 用户在屏幕外点击 UISearchBar 的完整动画

没有初始化器的 Swift 类可以工作吗?

ios - Xcode 11 存档给出 PhaseScriptExecution 失败

ios - 如何在 iOS/macOS 上以编程方式获取我的 IP 地址?

ios - 无法在我的 Xcode 应用程序中使用暗模式

ios - 拼接两个视频

ios - iOS 开发中的可重用性