我有這個json
{
"status": [
{
"state": "checked",
"errorCode": "123",
"userId": "123456"
}
]
}
這是一個狀態陣列,但實施得很糟糕,因為可能只是一個,所以我想只解碼狀態物件
struct StatusResponse: Codable {
let state: String
let error: String
let id: String
enum CodingKeys: String, CodingKey {
case state = "state"
case error = "errorCode"
case id = "userId"
}
}
我嘗試自定義解碼
let container = try decoder.container(keyedBy: ContainerKeys.self)
var statuses = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .status)
但正如預期的那樣,我知道"Expected to decode Dictionary<String, Any> but found an array instead."如何從狀態變數訪問第一個物件并將其解碼為 StatusResponse?或有關如何進行的其他想法?
uj5u.com熱心網友回復:
我會用欄位制作一個結構status來表示頂級物件。該欄位是一個陣列StatusResponse:
struct TopLevelResponse: Codable {
var status: [StatusResponse]
}
解碼json時:
let decoded = JSONDecoder().decode(TopLevelResponse.self, from: data)
let first = decoded.status.first! // Already decoded!
除非保證陣列中至少有一項,否則您應該處理 nil 情況。
uj5u.com熱心網友回復:
我將采用受此答案啟發的解決方案:
fileprivate struct RawStatusResponse: Decodable {
let status: [RawStatus]
struct RawStatus: Decodable {
let state: String
let errorCode: String
let userId: String
}
}
struct StatusResponse: Codable {
let state: String
let error: String
let id: String
enum CodingKeys: String, CodingKey {
case state = "state"
case error = "errorCode"
case id = "userId"
}
public init(from decoder: Decoder) throws {
let raw = try RawStatusResponse(from: decoder)
state = raw.status.first!.state
error = raw.status.first!.errorCode
id = raw.status.first!.userId
}
}
然后在解碼時只解碼實際物件:
let state = try JSONDecoder().decode(StatusResponse, from: json)
uj5u.com熱心網友回復:
您可以將其解碼為字典并用于flatMap獲取陣列
let status = try JSONDecoder().decode([String: [StatusResponse]].self, from: data).flatMap(\.value)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/448198.html
下一篇:識別符號為<team-id.com.example.bundle-id>的應用程式未與域<www.example-domain.com>關聯
