Возможно ли использование NSArray в Codable? (преобразование "Object Mapper" в "Codable") - PullRequest
2 голосов
/ 15 мая 2019

Я пытаюсь преобразовать "Object Mapper" в "Codable".Мой ответ от службы включает NSArray, который включает в себя пользовательские объекты.Мне нужно использовать NSArray и NSDictionary в Codable Class.Но я потерпел неудачу. Я попытался использовать стороннюю библиотеку, такую ​​как AnyCodable , но мне снова не удалось.Я не могу изменить ответ на стороне сервера.Это должно прийти как массив.Я должен использовать массив.Есть ли у вас какие-либо предложения или информация?

class Person : Codable { //Error 1
  var name: String?
  var data: NSArray?

  private enum CodingKeys : String, CodingKey {
      case name
      case data
  }

  func encode(to encoder: Encoder) throws {
      var container = encoder.container(keyedBy: CodingKeys.self)
      try container.encode(name, forKey: .name)
      try container.encode(data, forKey: .data) //Error 2
  }

  func decode(from decoder: Decoder) throws {
      let container = try decoder.container(keyedBy: CodingKeys.self)
      self.name = try container.decode(String.self, forKey: .name)
      self.data = try container.decode(NSArray.self, forKey: .data) //Error 3
  } 
}

Ошибка 1: «Тип« Персона »не соответствует протоколу« Декодируемый »»

Ошибка 2: «Тип аргумента« NSArray »не соответствует ожидаемому типу« Кодируемый »»

Ошибка 3: Декодирование «Метод экземпляра» (_: forKey :)'требует, чтобы' NSArray 'соответствовал' Decodable ''

Пример ответа приведен здесь. Все элементы в массиве не имеют одинакового содержимого.Каждый элемент в массиве имеет свой тип.

{
  "data": [
    {
      "languageCode": "EN",
      "deviceInformation": {
        "screenSize": "height:812.0 width:375.0",
        "connectionType": "wifi",
        "deviceType": "iPhone",
        "deviceCode": "D01D304C-D05C-4443-9A92-031C55D14XC7",
        "operatingSystemVersion": "12.2",
        "applicationVersion": "1.0"
      },
      "lastUpdatedParamDate": "13.05.2019 14:44:24",
      "skipOptionalUpdate": 0
    }
  ]
}

1 Ответ

1 голос
/ 15 мая 2019

Когда вы делаете это

var data: NSArray?

, это промежуточная цель - тип c, имеющий Any в качестве типа элементов, а Any не соответствует Codable, поэтому явно сделайте его таким, как

var data:[SomeModel]

или используйте JSONSerialization вместо


struct Root: Codable {
    let data: [Model]
}

struct Model: Codable {
    let languageCode: String
    let deviceInformation: DeviceInformation
    let lastUpdatedParamDate: String
    let skipOptionalUpdate: Int
}

struct DeviceInformation: Codable {
    let screenSize, connectionType, deviceType, deviceCode: String
    let operatingSystemVersion, applicationVersion: String
}

let eventData = try JSONDecoder().decode(Root.self, from: data) 

если у вас есть больше атрибутов, вы можете добавить их, если некоторые возвращают nil в некоторых случаях делает их необязательными, но если тип меняется, то с Codable это никак не получается

...