[英]Swift: Decodable
可以說我有一個來自API請求的json:
friends: {
"john":31,
"mark":27,
"lisa":17,
"tom":41
}
我通常期望它采用數組格式:
friends: [
{ "john":31 },
{ "mark":27 },
{ "lisa":17 },
{ "tom":41 }
]
但是API不會以這種方式向我提供結果。 所以我最終希望將其映射到[Friend]的數組,其中Friend是:
class Friend: Decodable {
let name: String
let age: Int
}
我應該如何序列化此json以獲取[Friend]?
首先,示例根本不是有效的json。 為了有效,它要么不應該包含“ friends”標簽,要么應該嵌入到另一個這樣的對象中
{
"friends": {
"john":31,
"mark":27,
"lisa":17,
"tom":41
}
}
如果我正確理解問題,則想將json對象解碼為swift數組。 我認為沒有編寫自定義解碼的方法是不可能的。 相反,您可以將json解碼為Dictionary
並在手動映射時像這樣
struct Friend {
let name: String
let age: Int
}
struct Friends: Decodable {
let friends: [String: Int]
}
let friends = try! JSONDecoder().decode(Friends.self, from: json.data(using: .utf8)!)
.friends
.map { (name, age) in Friend(name: name, age: age) }
免責聲明 :我建議將您的API格式更改為@scriptable的答案中的一種 (我在回答時已刪除,hm),其中正確定義了name
和age
字段。 而且您基本上不局限於要解析的一對鍵值。
但是,如果您無法更改,則可以使用如下所示的方式來解碼您的Friend
類型:
struct Friend: Decodable {
let name: String
let age: UInt
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let dictionary = try container.decode([String: UInt].self)
guard dictionary.count == 1, let (name, age) = dictionary.first else {
throw DecodingError.invalidFriendDictionary
}
self.name = name
self.age = age
}
enum DecodingError: Error {
case invalidFriendDictionary
}
}
struct Friends: Decodable {
let friends: [Friend]
}
let friends = try JSONDecoder().decode(Friends.self, from: data)
它假定key
是name
, value
是age
。 並檢查是否只有一對要解析。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.