Swift: данные не удалось прочитать, потому что они не в правильном формате

#json #swift #alamofire #jsondecoder

#json #swift #alamofire #jsondecoder

Вопрос:

Я пытаюсь вызвать POST Api с помощью Alamofire, но он показывает мне ошибку неправильного формата.

Это мой ответ в формате JSON:

 [
  {
    "_source": {
      "nome": "LOTERIAS BELEM",
      "endereco": "R DO COMERCIO, 279",
      "uf": "AL",
      "cidade": "BELEM",
      "bairro": "CENTRO"
    },
    "_id": "010177175"
  },
  {
    "_source": {
      "nome": "Bel Loterias"
    },
    "_id": "80224903"
  },
  {
    "_source": {
      "nome": "BELLEZA LOTERIAS",
      "endereco": "R RIVADAVIA CORREA, 498",
      "uf": "RS",
      "cidade": "SANTANA DO LIVRAMENTO",
      "bairro": "CENTRO"
    },
    "_id": "180124986"
  }
]
  

 class Album: Codable {
    var _source :  [_source]

}

class _source: Codable {
    var nome :  String
    var endereco : String
    var uf : String
    var cidade : String
    var bairro : String
}

var arrList = [Album]()
  

И вот как я пытаюсь декодировать с помощью Alamofire.

 func request() {

        let urlString = URL(string: "My Url")
      //  Alamofire.request(url!).responseJSON {(response) in

        Alamofire.request(urlString!, method: .post, parameters: ["name": "belem"],encoding: JSONEncoding.default, headers: nil).responseJSON {
            (response) in

            switch (response.result) {
            case .success:
                if let data = response.data {
                    do {
                        let response = try JSONDecoder().decode([Album].self, from: data)
                        DispatchQueue.main.async {
                             self.arrList = response
                        }
                    }
                    catch {
                        print(error.localizedDescription)
                    }
                }
            case .failure( let error):
                print(error)
            }
       }
 }
  

Комментарии:

1. Никогда не печатайте error.localizedDescription при декодировании JSON. Распечатайте error , это точно скажет вам, что не так. И прекратите использовать эти уродливые символы подчеркивания objective-c-ish . Структуры в Swift начинаются с заглавной буквы!

Ответ №1:

Просто ваша Album модель неверна.

 struct Album: Codable {
    var source : Source
    var id     : String

    enum CodingKeys: String, CodingKey {
        case source = "_source"
        case id = "_id"
    }
}

struct Source: Codable {
    var nome     : String
    var endereco : String?
    var uf       : String?
    var cidade   : String?
    var bairro   : String?
}
  

Если вы не хотите _id полностью, просто удалите связанные части.
Что касается вашего Alamofire связанного кода, эта часть хороша.


Заметные улучшения:

  • Удалось избежать подчеркивания имени переменной в модели, настроив CodingKeys для целей сопоставления ключей
  • Имена типов всегда должны начинаться с заглавной буквы (так _source есть Source )
    • Аналогично, имена переменных всегда должны начинаться со строчной буквы
  • Сделал некоторые переменные необязательными (на основе вашего обновленного ответа)
    • Сохранение необязательной переменной означает, что она должна присутствовать в ответе для создания модели
    • Создание переменной необязательной означает, что ключ может присутствовать или не присутствовать в ответе, и его отсутствие не помешает созданию модели

Комментарии:

1. Хорошо, я пробую это, но keyNotFound(CodingKeys(stringValue: "_source", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "_source", intValue: nil) ("_source").", underlyingError: nil)) отображается ошибка

2. @KrunalNagvadia Поделитесь своим ответом в формате json. Кажется, «_source» отсутствует для какого-то объекта. В любом случае, поделитесь тем, с какими журналами print(try? JSONSerialization.jsonObject(with: data, options: [])) в вашей функции запроса alamofire

3.[drive.google.com/file/d/1V25FAlCQRYNKVAp695SFOzQlLFO8AsIA/…

4. @KrunalNagvadia Хм … у 7-го объекта есть только ключ «nome» и ничего больше. Нам придется сделать остальное необязательным в Source optional.

5. @KrunalNagvadia Проверьте обновленный ответ. Через некоторое время добавим объяснение.

Ответ №2:

Я хотел бы порекомендовать вам использовать json4swift.com. Вам просто нужно скопировать ваш json и вставить туда. Он автоматически создаст модальную структуру или класс из вашего json.

Возвращаясь к вашему вопросу, в вашем альбоме класса нет массива [_source] . По этой причине вы получаете следующую ошибку «Данные не удалось прочитать, потому что они не в правильном формате».

Попробуйте приведенный ниже формат класса album,

 class Album: Codable
{ 
  var source: Source?
  var id: String?
}
  

Пожалуйста, старайтесь избегать использования подчеркивания в Swift.