手动解码Codable类的非Codable属性

时间:2019-06-27 20:17:44

标签: ios swift codable

ClassA符合Cadable,并具有许多属性。其中之一是不符合Codable的已经非常复杂的ClassB的属性。我可以手动解码Codable类的非Codable属性吗?

struct ClassA: Codable {

   let title: String?
   let subtitle: String?
   let property: ClassB?

    enum CodingKeys: String, CodingKey {
      case title
      case subtitle
      case property
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        title = try container.decode(String.self, forKey: .title)
        subtitle = try container.decode(String.self, forKey: .subtitle)
        let JSONString = ?
        property = ClassB.initWith(JSONString: JSONString)
  }

class ClassB: NSObject {

    // Already existing very complex ClassB implemenatation...
}

我收到错误消息:

  

类型“ ClassA”不符合协议“可编码”

2 个答案:

答案 0 :(得分:1)

是的。

错误是您在func encode(to encoder: Encoder) throws中缺少ClassACodable = Encodable & Decodable,因此它也在尝试寻找一种对ClassA进行编码的方法。 ClassB不可编码,因此它不能自动执行,您也没有告诉它如何手动执行。

如果您不需要编码ClassA实例,只需将其设置为Decodable。否则,请实现缺少的encode函数。

或者只是投入工作并使ClassB也可编码。您可以使用扩展名在事实之后添加它。如果您也不想这样做,我使用的一种解决方法是在ClassA内声明一个小的私有可编码结构,例如struct ClassBInfo: Codable。使用它来获取所需的信息,然后读取其属性以初始化ClassB

答案 1 :(得分:0)

尝试

struct ClassA: Codable {

   let title: String?
   let subtitle: String?
   let property: ClassB?

    enum CodingKeys: String, CodingKey {
      case title
      case subtitle
      case property
    }

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)

        title = try container.decode(String.self, forKey: .title)
        subtitle = try container.decode(String.self, forKey: .subtitle)
        let JSONString = ?
        property = ClassB.initWith(JSONString: JSONString)
  }

class ClassB: Codable {

    // Already existing very complex ClassB implemenatation...
}