我必须解码字典的一个数组,其中键是一个枚举值是一个模型对象。
这是我的JSON示例,

[
  {
    "nanomp4": {
      "url": "https://media.tenor.com/videos/a1da4dcf693c2187615721d866decf00/mp4",
      "dims": [
        150,
        138
      ],
      "duration": 2.0,
      "preview": "https://media.tenor.com/images/17d523e6b7c3c9a4ca64566a1890d94d/tenor.png",
      "size": 70381
    },
    "nanowebm": {
      "url": "https://media.tenor.com/videos/aa983425114e32ab446f669d91611938/webm",
      "dims": [
        150,
        138
      ],
      "preview": "https://media.tenor.com/images/17d523e6b7c3c9a4ca64566a1890d94d/tenor.png",
      "size": 53888
    },
  },
  {
    "nanomp4": {
    "url": "https://media.tenor.com/videos/a1da4dcf693c2187615721d866decf00/mp4",
    "dims": [
          150,
          138
          ],
    "duration": 2.0,
    "preview": "https://media.tenor.com/images/17d523e6b7c3c9a4ca64566a1890d94d/tenor.png",
    "size": 70381
    },
  }
]

这是我的解码码,
do {
    let data = try Data(contentsOf: fileURL)
    let decoder = JSONDecoder()
    let collection = try decoder.decode([[GIFFormat:Media]].self, from: data)

    print(collection)
} catch {
    print("Error in parsing/decoding JSON: \(error)")
}

这里,GIFFormat是枚举,Media是模型对象,它们的解码非常好。
enum GIFFormat: String, Decodable {

    case nanoMP4    = "nanomp4"
    case nanoWebM   = "nanowebm"
}

struct Media: Decodable {
    let url: URL?
    let dims: [Int]?
    let duration: Double?
    let preview: URL?
    let size: Int64?
}

我的控制台打印出来,
typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

有人能告诉我这里到底怎么了吗?

最佳答案

即使rawValueGIFFormatStringGIFFormat本身也是一个枚举。你应该更新

let collection = try decoder.decode([[GIFFormat:Media]].self, from: data)


let collection = try decoder.decode([[GIFFormat.RawValue:Media]].self, from: data)

更新:回应你的评论
现在为了获得价值,我需要这样使用,
collection?.first?[GIFFormat.mp4.rawValue]?.url。又丑了
!!
我建议进行一些重构。您可以从完全删除enum开始。保持你的结构。创建新的Media结构
struct Collection: Decodable {
    let nanomp4: Media!
    let nanowebm: Media!
}

然后,您可以将上面的行更新为
let collection = try decoder.decode([Collection].self, from: data)

你丑陋的线条变成
collection.first?.nanomp4.url

注意:此解决方案假设只有Collection&nanomp4作为枚举值。如果不是这样,那么这可能不是最好的解决方案,您可能必须使用第一个解决方案。

10-06 00:22