【问题标题】:"Expected to decode String but found a dictionary instead."“本应解码字符串,但找到了字典。”
【发布时间】:2018-09-30 16:53:41
【问题描述】:

我正在尝试解码此 JSON,但到目前为止我一直无法解码。我正在尝试遍历专辑数组并获取 JSON,但我必须先浏览不同的字典。我怎样才能解决这个问题?我不得不从结果转移到专辑匹配,最后是专辑,但它仍然期待字典。我该如何构建它并获得正确的格式?

完全错误:

(_AD7BA6EDB44A00F25A39B8A21DBEFF83 中的 CodingKeys).image, Foundation.(_12768CA107A31EF2DCE034FD75B541C9 中的 _JSONKey)(stringValue: "Index 0", intValue: Optional(0))], debugDescription: "期望解码字符串,但找到了字典。",底层错误:无))

JSON:

{
  "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()
        }
    }

【问题讨论】:

    标签: json swift alamofire decodable


    【解决方案1】:

    您的image 类型不正确(错误消息告诉您这一点)。你应该是[String],它应该是......

    struct Image { 
        let text: URL 
        let size: String 
    
        enum CodingKeys: String, CodingKey {
            case text = "#text", size
        }      
     }
    

    然后

    let image: [Image]
    

    【讨论】:

      【解决方案2】:

      阅读错误信息。很清楚:key image 的值是字典数组,而不是字符串数组。

      字典被解码为一个结构,所以创建一个结构Image,我建议将text解码为URLsize为枚举

      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,根本不需要使用可选项

      【讨论】:

        【解决方案3】:

        根据您的回复,图片有Arraykey-value pair(Dictionary) 所以您需要添加图片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?
        }
        

        (推荐第二种方式)

        您可以为此再创建一个结构,如下所示:

        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
            }
        
        }
        

        【讨论】:

        • 你应该有一个struct Image { let text: URL let size: String }
        • @AshleyMills:我已经添加了两个答案
        猜你喜欢
        • 2021-08-08
        • 1970-01-01
        • 1970-01-01
        • 2019-09-11
        • 1970-01-01
        • 2018-10-15
        • 2019-12-06
        • 1970-01-01
        • 2021-06-22
        相关资源
        最近更新 更多