Возможно ли использование NSArray в Codable? (преобразование Object Mapper в Codable)

Я пытаюсь преобразовать «Object Mapper» в «Codable». Мой ответ, полученный от службы, включает NSArray, который включает настраиваемые объекты. Мне нужно использовать NSArray и NSDictionary в классе Codable. Но мне это не удалось. Я попытался использовать стороннюю библиотеку, такую ​​как 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' не соответствует ожидаемому типу 'Encodable'»

Ошибка 3: «Метод экземпляра 'decode (_: 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
    }
  ]
}

person Okan    schedule 15.05.2019    source источник
comment
Используйте массив, а не NSArray. Каково содержание данных (массива)?   -  person Joakim Danielson    schedule 15.05.2019
comment
Я пробовал. Когда использую Array ‹Any›. Я снова потерпел неудачу. Ни один не соответствует ...... та же ошибка. @JoakimDanielson   -  person Okan    schedule 15.05.2019
comment
Да, вам нужно указать точный тип. Вы пишете нестандартные объекты того же класса или? Вам также необходимо включить определение этого настраиваемого класса.   -  person Joakim Danielson    schedule 15.05.2019
comment
Содержание данных непостоянно. Это может быть что угодно. Первый индекс = Int, Второй индекс = String, Третий индекс = Object.   -  person Okan    schedule 15.05.2019


Ответы (1)


Когда ты это сделаешь

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

person Sh_Khan    schedule 15.05.2019
comment
Содержание данных непостоянно. Это может быть что угодно. Первый индекс = Int, Второй индекс = String, Третий индекс = Object. - person Okan; 15.05.2019
comment
тогда Codable нельзя использовать иди с JSONSerialization - person Sh_Khan; 15.05.2019
comment
Я поделился образцом ответа. Это невозможно с Codable? - person Okan; 15.05.2019
comment
Да, я знаю это решение, но у меня много таких отзывов. Мне нужна общая вещь. - person Okan; 15.05.2019
comment
У меня есть не только DeviceInformation и Model. У меня много таких моделей в NSArray. Мне нужно найти общее. - person Okan; 15.05.2019
comment
если у вас есть больше атрибутов, вы можете добавить их, если некоторые из них возвращают nil, в некоторых случаях сделайте их необязательными, но если тип изменяется, то с Codable никак. - person Sh_Khan; 15.05.2019
comment
Да, тип меняется при каждом ответе и при каждом индексе. Хорошо, я понял. Спасибо за помощь. - person Okan; 15.05.2019
comment
Можете ли вы добавить этот комментарий к своему сообщению? Для других?? @Sh_Khan - person Okan; 15.05.2019
comment
Я знаю этот способ. Но все элементы в массиве не имеют одинакового содержимого. Поделился ответом, проверьте. @vadian - person Okan; 15.05.2019
comment
@Okan, если data контент может быть другого типа, вы можете попробовать использовать Codable enum. - person user28434'mstep; 15.05.2019
comment
@ user28434 enum подходит для 2 значений, но если оно превышает это значение, это будет запутанный код с множеством переключателей вокруг - person Sh_Khan; 15.05.2019
comment
@Sh_Khan, а? Каждый enum регистр предназначен только для разделения разных наблюдений и должен содержать только одно связанное значение некоторого типа Codable. Нравится enum Datum: Codable { case int(Int); case string(String; case object(SomeObject) } - person user28434'mstep; 15.05.2019
comment
я говорю о проверке типа в вашем опубликованном комментарии, вы бы сделали переключение - person Sh_Khan; 15.05.2019
comment
@Sh_Khan, если вы не знаете фактический тип, вы все равно переключитесь, только позже в коде. - person user28434'mstep; 15.05.2019