使用Decodable

时间:2019-09-24 09:52:27

标签: json swift decodable

我有一些JSON(来自last.fm),如下所示:

{
    "results": {
        "opensearch:Query": {
            "#text": "",
            "role": "request",
            "searchTerms": "believe",
            "startPage": "1"
        },
        "opensearch:totalResults": "119100",
        "opensearch:startIndex": "0",
        "opensearch:itemsPerPage": "50",
        "albummatches": {
            // It's this array that I actually want:
            "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"
                        },
                        // There are more here.
                        …
                    ]
                },
                // There are more here.
                …
            }
        }
    }
}

我想对嵌套数组album进行解码,该数组深达三层。我可以为此高兴地实现一个Decodable结构,它将是这样的(未经测试,但可以构建):

struct Album: Decodable {
  let name: String
  let artist: String
  let url: URL
  let image: [Image]

  struct Image: Decodable {
    let url: URL
    let size: String

    enum CodingKeys: String, CodingKey {
      case url = "#text"
      case size
    }
  }
}

但是,有没有一种很好的方法可以访问JSON并开始在album数组中进行解析?

我可以像这样实现ResponseContainerResultsAlbumMatches结构来实现:

struct ResponseContainer: Decodable {
   let results: Results
}

struct Results: Decodable {
    let albummatches: AlbumMatches
}

struct AlbumMatches: Decodable {
    let album: [Album]
}

...但是当我真正想做的事情像这样时,这似乎不是一个好方法:

let decoder = JSONDecoder()
let albums = try! decoder.decode(
  [Album].self, 
  for: jsonData, 
  // Made up path parameter to let me jump to a child.
  at: "results.albummatches.album"
)

我还想避免使用JSONSerialization.jsonObject(with: …, options: …)反序列化JSON,取出特定片段并重新序列化,然后再使用JSONDecoder,因为这看起来非常浪费,尽管它肯定会工作。

0 个答案:

没有答案