我正在尝试解码这个JSON,但到目前为止我无法解码。我正在尝试遍历专辑数组并获取 JSON,但我必须首先浏览不同的字典。我该如何解决这个问题?我不得不从结果移动到专辑匹配,最后是专辑,但它仍然期待字典。我怎样才能构建它并获得正确的格式?
完全错误:
(CodingKeys in _AD7BA6EDB44A00F25A39B8A21DBEFF83(.image, Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9((stringValue: "Index 0", intValue: Optional(0((], debugDescription: "预期解码字符串,但找到了字典。
杰森:
{
"results": {
"opensearch:Query": {
"#text": "",
"role": "request",
"searchTerms": "believe",
"startPage": "1"
},
"opensearch:totalResults": "113802",
"opensearch:startIndex": "0",
"opensearch:itemsPerPage": "50",
"albummatches": {
"album": [
{
"name": "Believe",
"artist": "Disturbed",
"url": "https://www.last.fm/music/Disturbed/Believe",
"image": [
{
"#text": "https://lastfm-img2.akamaized.net/i/u/34s/bca3b80481394e25b03f4fc77c338897.png",
"size": "small"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/64s/bca3b80481394e25b03f4fc77c338897.png",
"size": "medium"
}
],
"streamable": "0",
"mbid": "c559efc2-f734-41ae-93bd-2d78414e0356"
},
{
"name": "Believe",
"artist": "Justin Bieber",
"url": "https://www.last.fm/music/Justin+Bieber/Believe",
"image": [
{
"#text": "https://lastfm-img2.akamaized.net/i/u/34s/899fe1643173a9568ac6e832327e7b57.png",
"size": "small"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/64s/899fe1643173a9568ac6e832327e7b57.png",
"size": "medium"
}
],
"streamable": "0",
"mbid": "5d88ae0c-c4bf-4e64-bc97-45789880d910"
}
}
法典:
struct SearchResults: Decodable {
let results: Results
}
struct Results: Decodable {
let albumMatches: AlbumMatches
enum CodingKeys: String, CodingKey {
case albumMatches = "albummatches"
}
}
struct AlbumMatches: Decodable {
let album: [Album]
}
struct Album: Decodable {
let name: String?
let image: [String]
let artist: String?
}
class APIService {
static let shared = APIService()
func fetchArtists(searchText: String, url: URL, completionHandler: @escaping ([Album]) ->()) {
Alamofire.request(url, method: .get, encoding: URLEncoding.default, headers: nil).responseData { (dataResponse) in
if let error = dataResponse.error {
print("Failed to contact last fm", error)
return
}
guard let data = dataResponse.data else { return }
do {
let decoder = JSONDecoder()
let searchResult = try decoder.decode(SearchResults.self, from: data)
searchResult.results.albumMatches.album.forEach({ (album) in
print(searchResult.results.albumMatches.album)
})
} catch let decodeError {
print("Failed to decode", decodeError)
}
}
}
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
print(searchText)
let baseLastfmUrl = "http://ws.audioscrobbler.com/2.0/?method=album.search&album=believe&api_key=MyKey&format=json"
guard let url = URL(string: baseLastfmUrl) else { return }
APIService.shared.fetchArtists(searchText: searchText, url: url) { (album) in
self.albums = album
self.tableView.reloadData()
}
}
您的image
类型不正确(错误消息告诉您这一点(。你把它当作[String]
它应该的时候...
struct Image {
let text: URL
let size: String
enum CodingKeys: String, CodingKey {
case text = "#text", size
}
}
然后
let image: [Image]
请阅读错误消息。很明显:键image
的值是字典数组,而不是字符串数组。
字典被解码为结构,因此创建一个结构Image
,我建议text
解码为URL
,size
为枚举
struct Album: Decodable {
let name: String
let image: [Image]
let artist: String
}
enum ImageSize : String, Decodable {
case small, medium, large
}
struct Image : Decodable {
private enum CodingKeys: String, CodingKey { case text = "#text", size }
let text : URL
let size : ImageSize
}
根据给定的 JSON,根本不需要使用可选
根据您的回复,图像具有key-value pair(Dictionary)
的Array
,因此您需要添加图像struct
对象,如下所示(目前您已添加[String]
但需要添加[[String: String]]
(
"image": [
{
"#text": "https://lastfm-img2.akamaized.net/i/u/34s/899fe1643173a9568ac6e832327e7b57.png",
"size": "small"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/64s/899fe1643173a9568ac6e832327e7b57.png",
"size": "medium"
}
]
struct Album: Decodable {
let name: String?
let image: [[String:String]]
let artist: String?
}
OR(推荐第二种方式(
您可以为此再创建一个结构,如下所示:
struct Album: Decodable {
let name: String?
let image: [Images]
let artist: String?
}
struct Images: Decodable {
let text: String?
let size: String?
enum CodingKeys: String, CodingKey {
case text = "#text"
case size
}
}