Декодирование вручную некодируемого свойства класса Codable - PullRequest
1 голос
/ 27 июня 2019

ClassA соответствует Cadable и обладает множеством свойств. Одним из них является свойство уже существующего очень сложного 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' не соответствует протоколу 'Encodable'

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Да, вы можете.

Ошибка в том, что вы пропускаете func encode(to encoder: Encoder) throws в ClassA.Codable = Encodable & Decodable, поэтому он пытается найти способ также кодировать ClassA.ClassB не кодируется, поэтому он не может делать это автоматически, и вы также не сказали, как это сделать вручную.

Если вам не нужно кодировать ClassA экземпляры, простосделать это Decodable.В противном случае реализуйте отсутствующий encode func.

Или просто включите в работу и сделайте кодировку ClassB также.Вы можете использовать расширение, чтобы добавить его после факта.Если вы не хотите этого делать, я использовал обходной путь, чтобы объявить небольшую частную кодируемую структуру внутри ClassA как struct ClassBInfo: Codable.Используйте это, чтобы получить необходимую информацию, затем прочитайте ее свойства для init ClassB.

0 голосов
/ 27 июня 2019

попробуйте

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