#ios #json #swift
#iOS #json #swift
Вопрос:
Когда я пытаюсь декодировать JSON, я получаю сообщение об ошибке:
Несоответствие типов (Swift.Строка, Swift.Ошибка декодирования.Context(codingPath: [_JSONKey(stringValue: «Index 1972», intValue: 1972), CodingKeys(stringValue: «song_name», intValue: nil)], debugDescription: «Ожидалось декодировать строку, но вместо этого найдено число.», underlyingError: nil))
- JSON:
[
{
"song_id": 1373123,
"song_name": "신라의 달밤",
"artist": "현인",
"album": "현인",
"Like_count": 100,
"Lyric": "아~ 신라의 밤이여n불국사의 종소리 들리어 온다n지나가는 나그네야 걸음을 멈추어라n고요한 달빛 어린 금오산 기슭에서n노래를 불러보자 신라의 밤 노래를nn아~ 신라의 밤이여n아름다운 궁녀들 그리워라n대궐 뒤에 숲 속에서 사랑을 맺었던가n님들의 치맛소리 귓속에 들으면서n노래를 불러보자 신라의 밤 노래를",
"cover_url": "https://image.bugsm.co.kr/album/images/200/1134/113497.jpg?version=20170925032718.0"
},
...
- Код Swift
let decoder = JSONDecoder()
do {
self.songs = try decoder.decode([Song].self, from: asset.data)
} catch {
print(error)
}
- Модель
struct Song: Codable {
// var id: Int
var title: String
var artist: String
// var album: String
// var like: Int
// var lylic: String
// var coverURL: String
enum CodingKeys: String, CodingKey {
// case id = "song_id"
case title = "song_name"
case artist = "artist"
// case album = "album"
// case like = "Like_count"
// case lylic = "Lyric"
// case coverURL = "cover_url"
}
}
Комментарии:
1. Все работает с опубликованным вами JSON. Ошибка означает, что
song_name
это было число вместо строки. Возможно, в реальном JSON иногда есть объект сsong_name
числом?
Ответ №1:
Ошибка предельно ясна: в 1973-м элементе массива (индекс 1972) значением для ключа song_name
является число. Вы должны добавить пользовательский инициализатор, чтобы устранить проблему, например
struct Song: Decodable {
let id : Int
let title : String
// ... other struct members
enum CodingKeys: String, CodingKey {
case id = "song_id"
case title = "song_name"
// ... other CodingKeys
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int.self, forKey: .id)
do {
self.title = try container.decode(String.self, forKey: .title)
} catch {
let numberName = try container.decode(Int.self, forKey: .title)
self.title = String(numberName)
}
// other lines to initialize the other struct members
}
}
Если ошибка все еще сохраняется, число также может быть Double
или Bool
.
Комментарии:
1. Когда мы указываем тип как необязательный, он по-прежнему не анализирует JSON, в идеале он должен анализировать с нулевым значением для данных, которые он не смог проанализировать. Например, структура песни: декодируемая { пусть идентификатор: Int пусть заголовок: Строка? } поэтому, когда мы декодируем, он должен иметь значение в идентификаторе, но не в названии. но возникает ошибка, не удается проанализировать JSON. Как это исправить без сбоя приложения