![](/img/trans.png)
[英]Elegant solutions to decoding a JSON nested array in swift using decodable
[英]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))
誰能告訴我這里到底有什么問題?
即使rawValue
的GIFFormat
是String
, GIFFormat
本身也是一個枚舉。 你應該更新
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
注意:此解決方案假定您只將nanomp4
和nanowebm
作為枚舉值。 如果不是這種情況,那么這可能不是最佳解決方案,您可能不得不采用第一個解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.