如何在目标 c 数据模型类中使用 Codable 协议?

Posted

技术标签:

【中文标题】如何在目标 c 数据模型类中使用 Codable 协议?【英文标题】:How to use Codable protocol in objective c data model class? 【发布时间】:2018-11-10 01:37:52 【问题描述】:

我正在研究混合搭配 ios 源代码。我已经为 swift 数据模型类实现了可编码,这减少了编写解析器逻辑的负担。我试图使我的目标 c 类符合可编码协议,这反过来又引发了错误“找不到'可编码'的协议声明”。有什么方法可以将此快速协议用于目标 c 类?或者是否有任何其他目标 c api 提供与 Codable 相同的功能?这个想法是让 swift 和 Objective c 类的解析逻辑相同。

【问题讨论】:

NSCoding 是对应的 Objective-C 协议,在引入 Codable 之前也用于 Swift @JoakimDanielson - 符合 NSCoding 协议,自定义类对象可以序列化/反序列化为存档/取消存档。这是否有助于将 jsonobject 解析为自定义类型,反之亦然? 没有。你不能。 Codable 仅适用于 SwiftObjective-C 没有对应物,因为如果有,那为什么还要引入 Codable 呢? 阅读 Jordan Rose 的解释,Why You Cant Make Someone Else's Class Decodable,其中涉及所需的初始化程序和子类如何解决非最终数据结构的问题。 ObjC 没有final,因此这些原因也适用于当前发布者的问题。 【参考方案1】:
class LoginDataModel: NSObject ,Codable 
 @objc var stepCompleted: String?
 @objc var userID: Int?
 @objc var authkey: String?
 @objc var type, status: String?


 enum CodingKeys: String, CodingKey 
    case stepCompleted = "step_completed"
    case userID = "user_id"
    case authkey
    case type, status
  

【讨论】:

【参考方案2】:

是的,您可以将 Codable 与 Obj-C 一起使用。棘手的部分是因为 Obj-C 看不到Decoder,所以当你需要从 Obj-C 端分配它时,你需要创建一个辅助类方法。

public class MyCodableItem: NSObject, Codable 
    private let id: String
    private let label: String?

    enum CodingKeys: String, CodingKey 
        case id
        case label
    

    @objc public class func create(from url: URL) -> MyCodableItem 
        let decoder = JSONDecoder()
        let item = try! decoder.decode(MyCodableItem.self, from: try! Data(contentsOf: url))
        return item
    

    public required init(from decoder: Decoder) throws 
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decode(String.self, forKey: .id)
        label = try? container.decode(String.self, forKey: .label)
        super.init()
    

    required init(coder decoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

嗨,我可以将 i 字典而不是 url 传递给 create func 吗?而且,在 create 函数中返回 item 有什么意义呢? objc 调用将如何与这个快速编码的 cls 交互?因为您似乎根本没有使用 swift 类,而只是在其中创建一个 func 来进行解析,而无需重用 swift 类已经提供的可编码代码。 公开create 方法的目的是将其用作一种变通方法,以便Objective-C 可以以某种方式与Codable 一起使用。因此,您绝对可以创建一些其他辅助方法来帮助您将任何类型的数据转换为 Codable 类。

以上是关于如何在目标 c 数据模型类中使用 Codable 协议?的主要内容,如果未能解决你的问题,请参考以下文章

当超类也是 Codable 时,如何在子类中使用 CodingKeys?

使用 Codable 解析 JSON 数据

Swift 使用Codable协议进行json转模型

如何从 Swift 类中检索目标 C 类中的 Userdefault?

在 swift 中使用“默认值”创建非可选 Codable 的最佳方法

如何从 iOS Swift Codable 中的 API 响应通知或打印模型类上缺少的密钥?