簡體   English   中英

Swift 4 Decodable:解碼復雜的JSON

[英]Swift 4 Decodable: Decoding complex JSON

我必須解碼字典的數組,其中鍵是枚舉,值是模型對象。

這是我的示例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是Enum, 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結構。 創建一個新的Collection結構

struct Collection: Decodable {
    let nanomp4: Media!
    let nanowebm: Media!
}

然后,您可以將上面的行更新為

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

你的丑陋的線條變成

collection.first?.nanomp4.url

注意:此解決方案假定您只將nanomp4nanowebm作為枚舉值。 如果不是這種情況,那么這可能不是最佳解決方案,您可能不得不采用第一個解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM