【问题标题】:Decoding JSON with Codable使用 Codable 解码 JSON
【发布时间】:2021-10-15 07:58:56
【问题描述】:

我有以下JSON 字符串要解码:

{
"albums": {
    "album": [
        {
            "name": "Dark & Wild",
            "mbid": "",
            "url": "https://www.last.fm/music/BTS",
            "artist": {
                "name": "BTS",
                "mbid": "0d79fe8e-ba27-4859-bb8c-2f255f346853",
                "url": "https://www.last.fm/music/BTS"
            },
            "image": [
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/34s/6dfcd9efe7f9560334eadaf3ad6a0049.png",
                    "size": "small"
                },
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/64s/6dfcd9efe7f9560334eadaf3ad6a0049.png",
                    "size": "medium"
                },
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/174s/6dfcd9efe7f9560334eadaf3ad6a0049.png",
                    "size": "large"
                },
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/6dfcd9efe7f9560334eadaf3ad6a0049.png",
                    "size": "extralarge"
                }
            ],
            "@attr": {
                "rank": "1"
            }
        },
        {
            "name": "Agust D",
            "mbid": "",
            "url": "https://www.last.fm/music/Agust+D",
            "artist": {
                "name": "Agust D",
                "mbid": "",
                "url": "https://www.last.fm/music/Agust+D"
            },
            "image": [
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/34s/05ed3fae3b45b2fcda6c80e76c4c8aed.png",
                    "size": "small"
                },
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/64s/05ed3fae3b45b2fcda6c80e76c4c8aed.png",
                    "size": "medium"
                },
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/174s/05ed3fae3b45b2fcda6c80e76c4c8aed.png",
                    "size": "large"
                },
                {
                    "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/05ed3fae3b45b2fcda6c80e76c4c8aed.png",
                    "size": "extralarge"
                }
            ],
            "@attr": {
                "rank": "2"
            }
        }
    ],
    "@attr": {
        "tag": "Hip Hop",
        "page": "1",
        "perPage": "2",
        "totalPages": "6491",
        "total": "12982"
    }
}

我已经实现了以下Codable 结构:

struct Root: Codable {
    var albums: [Album]
}

struct Album: Codable {
    var name: String
    var mbid: String
    var url: String
    var image: AlbumImage
    var artist: AlbumArtist
}

struct AlbumImage: Codable {
    var text: String
    var size: String
}

struct AlbumArtist: Codable {
    var name: String
    var mbid: String
    var url: String
}

然后,当我尝试使用以下函数解码JSON Data 时:

func parse(json: Data) {
    let decoder = JSONDecoder()
    
    do {
        let root = try decoder.decode(Root.self, from: json)
        print("root", root.albums)
        
    } catch {
        print("Failed to decode:", error)
    }        
}

调试器抛出以下错误:

Failed to decode: typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "albums", intValue: nil)], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

有人可以帮我解决这个问题吗? 我是错误地实现了Codable 结构还是我错误地解析了它? 谢谢。

【问题讨论】:

  • 您的结构中缺少一个级别。根有一个名为albums 的属性,它引导一个名为album 的属性的级别——那么,that 是数组开始的地方。将你的 JSON 粘贴到 app.quicktype.io 并检查它的结果。
  • @jnpdx OMG,那个网站太棒了。我会试试那里的输出。
  • @jnpdx 可以确认它解决了我的问题......我确实错过了一个额外的层,因此错误抛出。感谢分享。
  • 您的 JSON 树在末尾缺少一个右括号。
  • 您的 AlbumImage 错误。

标签: ios json swift decode codable


【解决方案1】:

在这里,您错过了“相册”这一顶级属性。根类具有字典类型的单个属性“专辑”,然后该类包含数组属性,如下所示:-

struct Root: Codable {
    let albums: Albums
}

// MARK: - Albums
struct Albums: Codable {
    let album: [Album]
    let attr: AlbumsAttr

    enum CodingKeys: String, CodingKey {
        case album
        case attr = "@attr"
    }
}

【讨论】:

    【解决方案2】:

    我可以看到您已将图像类型指定为 AlbumImage 但它期望 [AlbumImage] 而不是单个元素,请尝试更改模型的图像属性,如下所示

    变种图像:[相册图像]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 2021-09-05
      • 1970-01-01
      相关资源
      最近更新 更多