我有一個必須消費的 JSON 塊。我無法控制 JSON 資料的形狀。
。假設我有一個看起來像這樣的回應blob:
{
"resultStatus" : 1,
"resultEntities" : [...]
}
在resultEntities陣列中,有兩個不同的物件;一種型別總是在索引0處,基本上是后面一切的頭,而索引1...->包含另一種型別(我可以控制我要求的型別)。這兩個物件之間的欄位有一些重疊,但在總共約30個欄位中,只有幾個欄位重疊。
{
"rectype" : 1,
"recname" : "header",
"companyname" : "Smithson & Jones" ,
"companyId" : "q1w2e3r4",
...。
}
而且
{
"rectype" : 2,
"recname" : "詳細記錄"。
"locationId" : "123 Miami Warehouse"。
"shelvingUnits" : 654,
...。
我的接收物件看起來基本上是這樣的:
struct APIResponse : Decodable {
let resultStatus : Int
let results : [...] //<--這就是問題所在。
我不認為我可以定義我的接收物件,使results[0]總是試圖決議到頭,而所有其他的決議到細節,對嗎?
我顯然不能做這樣的事情(偽代碼,我知道這不會被編譯 - 它只是在這里澄清我正在處理的問題):
let results : [ 0 = header type, 。 ... = 詳細型別 ] 。
或者
let results[0] : Header
let results[...] : Detail[/span
以此類推。
因此,在結果中作為陣列的物件應該只是頭和細節的混合體,所有欄位(除了已知的重疊欄位)都是可選的嗎?
我希望我解釋得夠清楚。
你怎么看?
有什么想法?
uj5u.com熱心網友回復:
這里是一個只使用Codable的解決方案,有一個自定義的init(from:),我們使用一個無鍵的容器來解碼陣列的內容。請注意,頭的值已經從陣列中移出,進入了Result結構中自己的屬性
struct Result。Decodable {
let status。Int Int
let header: Header Header
var entities: [DetailRecord]。
enum CodingKeys。String, CodingKey {
case status = "resultStatus"
case entities = "resultEntities" >。
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(Int.self, forKey: .status)
var嵌套= try container.nestedUnkeyedContainer(forKey: .entities)
header = try nested.Decode(Header.self)
物體 = []
while !nested.isAtEnd {
let detail = try nested.delode(DetailRecord.self)
entities.append(detail)
}
}
}
如果你只是想得到一個快速而簡單的解決方案,你可以使用
JSONSerialzation
span class="hljs-keyword">do {
let dictionary = try JSONSerialization. jsonObject(with: data) as! [String: Any] 。
if let entities = dictionary["resultEntities"] as? [Any], !entities.isEmpty {
let header = entities.first!
print(header)
let details = Array(entities.dropFirst() )
print(details)
}
} catch {
print(error)
當然,與擁有符合Codable的預定義型別相比,這在訪問單個屬性時將更加麻煩。
在這里使用Codable的一種方法是首先將header和details變數轉換為json資料物件,然后使用解碼器將其轉換為適當的物件
let detailsData = try JSONSerialization. data(withJSONObject: details)
let headerData = try JSONSerialization.data(withJSONObject: header)
let decoder = JSONDecoder()
let headerObject = try decoder.decode(Header.self, from: headerData)
let detailsArray = try decoder.decode([DetailRecord].self, from: detailsData)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/321917.html
標籤:
下一篇:如何在本地通知中實作深層鏈接
