我目前正在嘗試Request在我的 SwiftUI 應用程式中撰寫一個與我正在構建的 API 一致的通用物件。我已經用 JSON 有效負載寫了一些簡單的東西,作為例子,我遇到了物件解碼的問題。下面是請求物件。
let json = """
{
"object": "bottle",
"has_more": false,
"data": [
{
"id": "5ffa81e7-1d91-43b5-83cc-9ee1ab634c7b",
"name": "14 Hands Hot to Trot White Blend",
"price": "$8.99",
"image": "https://cdn11.bigcommerce.com/s-7a906/images/stencil/1000x1000/products/8186/10996/14-Hands-Hot-to-Trot-White-Blend__56901.1488985626.jpg?c=2",
"sku": "088586004490",
"size": "750ML",
"origination": "USA, Washington",
"varietal": "White Wine",
"information": "14 Hands Hot to Trot White Blend",
"proof": 121.5,
"brand_id": "1",
"rating": 1,
"review_count": 5
}
]
}
"""
struct Request: Decodable {
let object: String
let has_more: Bool
let data: [RequestData]
}
struct Bottle: Decodable {
let id: String
let name: String
let price: String
let image: String
let sku: String
let size: String
let origination: String
let varietal: String
let information: String
let proof: Float
let brand_id: String
let rating: Int
let review_count: Int
}
enum ObjectType: String, Decodable {
case bottle
}
enum BottleData: Decodable {
case bottle(Bottle)
}
struct RequestData: Decodable {
let hasMore: String
let object: ObjectType
let innerObject: BottleData
enum CodingKeys: String, CodingKey {
case hasMore
case object
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.object = try container.decode(ObjectType.self, forKey: .object)
self.hasMore = try container.decode(String.self, forKey: .hasMore)
switch object {
case .bottle:
self.innerObject = .bottle(
try Bottle(from: decoder)
)
}
}
}
let decoder = JSONDecoder()
let requestData = try decoder.decode(Request.self, from: json.data(using: .utf8)!)
for data in requestData.data {
switch data.innerObject {
case .bottle(let bottle):
print(bottle.name)
}
}
嘗試測驗此物件時收到以下錯誤。
DecodingError
? keyNotFound : 2 elements
- .0 : CodingKeys(stringValue: "object", intValue: nil)
? .1 : Context
? codingPath : 2 elements
- 0 : CodingKeys(stringValue: "data", intValue: nil)
? 1 : _JSONKey(stringValue: "Index 0", intValue: 0)
- stringValue : "Index 0"
? intValue : Optional<Int>
- some : 0
- debugDescription : "No value associated with key CodingKeys(stringValue: \"object\", intValue: nil) (\"object\")."
- underlyingError : nil
鑒于我目前只有一個物件,我有點困惑為什么這不像我預期的那樣作業(沒有任何錯誤)。任何人都可以發現我在這里可能做錯了什么嗎?
uj5u.com熱心網友回復:
請仔細閱讀錯誤。
這些CodingPath組件指示錯誤的確切位置。它是
CodingKeys(stringValue: "object", intValue: nil)
CodingKeys(stringValue: "data", intValue: nil)
_JSONKey(stringValue: "Index 0", intValue: 0)
CodingKeys(stringValue: "object", intValue: nil).
其中 - 轉換為關鍵路徑 - 是
object.data[0].object
實際的錯誤資訊
“沒有與鍵 CodingKeys(stringValue: "object", intValue: nil) ("object") 關聯的值。”
說沒有鑰匙object的RequestData,它是真實的物件。
我想這只是一個錯字。代替
let data: [RequestData]
和
let data: [Bottle]
并洗掉RequestData和相關的結構。他們毫無意義。
編輯:
您可以執行類似的操作,但由于 JSON 僅包含一種型別,因此該解決方案僅解碼此特定 JSON
let json = """
{
"object": "bottle",
"has_more": false,
"data": [
{
"id": "5ffa81e7-1d91-43b5-83cc-9ee1ab634c7b",
"name": "14 Hands Hot to Trot White Blend",
"price": "$8.99",
"image": "https://cdn11.bigcommerce.com/s-7a906/images/stencil/1000x1000/products/8186/10996/14-Hands-Hot-to-Trot-White-Blend__56901.1488985626.jpg?c=2",
"sku": "088586004490",
"size": "750ML",
"origination": "USA, Washington",
"varietal": "White Wine",
"information": "14 Hands Hot to Trot White Blend",
"proof": 121.5,
"brand_id": "1",
"rating": 1,
"review_count": 5
}
]
}
"""
enum RequestData {
case bottle([Bottle])
}
enum ObjectType: String, Decodable {
case bottle
}
struct Request: Decodable {
let object: ObjectType
let hasMore: Bool
let data: RequestData
enum CodingKeys: String, CodingKey { case hasMore = "has_more", object, data}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.object = try container.decode(ObjectType.self, forKey: .object)
self.hasMore = try container.decode(Bool.self, forKey: .hasMore)
switch object {
case .bottle:
let bottleData = try container.decode([Bottle].self, forKey: .data)
data = RequestData.bottle(bottleData)
}
}
}
struct Bottle: Decodable {
let id: String
let name: String
let price: String
let image: String
let sku: String
let size: String
let origination: String
let varietal: String
let information: String
let proof: Float
let brand_id: String
let rating: Int
let review_count: Int
}
let decoder = JSONDecoder()
let requestData = try decoder.decode(Request.self, from: Data(json .utf8))
print(requestData)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/317532.html
