[英]Convenient way to decode nested JSON object in Swift?
假設您有一些JSON:
{
"status": "error",
"data": {
"errormessage": "Could not get user with ID: -1.",
"errorcode": 14
}
}
對於給定的錯誤結構:
struct APIError: Decodable {
let code: Int?
let message: String?
enum CodingKeys: String, CodingKey {
case code = "errorcode"
case message = "errormessage"
}
}
點擊Web服務,獲取JSON,並初始化結構:
let urlRequest = URLRequest(url: url)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest)
{ (data, response, error) in
// Doesn't work because the portion of the JSON we want is in the "data" key
let e = try? JSONDecoder().decode(APIError.self, from: data)
}
task.resume()
有一些簡單的方法可以做類似data["data"]
事情嗎? 遵循的正確模型是什么?
解決方案A-將數據轉換為JSON對象,獲取所需的對象,然后將其轉換為Data對象並進行解碼。
let jsonFull = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any]
let json = jsonFull["data"]
let data_error = try? JSONSerialization.data(withJSONObject: json, options: [])
let e = try? JSONDecoder().decode(APIError.self, from: data_error)
解決方案B-將目標項目包裝在另一個結構中
struct temp : Decodable {
let status: String?
let data: APIError?
}
let e = try? JSONDecoder().decode(temp.self, from: data).data
解決方案C-在解碼中設置嵌套結構(如果深度為幾個對象該怎么辦?)
let e = try? JSONDecoder().decode([Any, APIError.self], from: data)
我缺少什么模式? 最優雅的方法是什么?
您可以使用以下方法:
struct APIError: Decodable {
let code: Int
let message: String
enum CodingKeys: String, CodingKey {
case data
}
enum ErrorCodingKeys: String, CodingKey {
case code = "errorcode"
case message = "errormessage"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let nestedContainer = try container.nestedContainer(keyedBy: ErrorCodingKeys.self, forKey: .data)
code = try nestedContainer.decode(Int.self, forKey: .code)
message = try nestedContainer.decode(String.self, forKey: .message)
}
}
let data = try! JSONSerialization.data(withJSONObject: ["status": "error", "data": ["errorcode": 14, "errormessage": "Could not get user with ID: -1."]], options: [])
let error = try! JSONDecoder().decode(APIError.self, from: data)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.