json - 如何使用响应数据解码值
问题描述
投资组合模型
public struct PortfolioModel : Decodable {
let symbols_requested: Int
let symbols_returned: Int
let data: [Portfolio]
}
struct Portfolio : Decodable {
let stockValue : StockValue
let todaysLowHigh : HighLowValue
let fiftyTwoWeekLowHigh : HighLowValue
let priceBandLowHigh : HighLowValue
let stockPriceValue : StockPriceValue
let stockStatistics : StockStatistics
struct StockValue: Decodable {
let stockName: String?
let stockCurrentPrice: String?
let stockChangeValue : String?
let stockVolume : String?
let stockDateValue : String?
}
struct HighLowValue: Decodable {
let minimumValue : String?
let maximumValue : String?
let currentValue : String?
}
struct StockPriceValue: Decodable {
let bidPriceValue : String?
let bidQtyValue : String?
let offerPriceValue : String?
let offerOtyValue : String?
let openPriceValue : String?
}
struct StockStatistics : Decodable{
let stockMarketCapValue : String?
let stockDividendValue : String?
let stockDivYield : String?
let stockfaceValue :String?
let stockMarketLot : String?
let stockIndustryPE : String?
let stockEPSTTM : StandColidate
let stockPC : StandColidate
let stockPE : StandColidate
let stockPriceBook : StandColidate
let stockBookValue : StandColidate
let stockDeliverables : String?
}
struct StandColidate : Decodable{
let standalone : String?
let consolidate: String?
}
}
WebServicesClientServer
.responseJSON { response in
switch response.result {
case .success:
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
let result = try decoder.decode(PortfolioModel.self, from: response.data!)
self.portfolio = result.data
print(result.data)
completion(self.portfolio)
return
}
catch {
MKProgress.hide()
print("Decoding error:", error)
}
case .failure(let error):
MKProgress.hide()
print("Request failed with error: \(error)")
}
服务器响应
{
"symbols_requested": 1,
"symbols_returned": 1,
"data": [
{
"symbol": "AAPL",
"name": "Apple Inc.",
"currency": "USD",
"price": "196.85",
"price_open": "196.45",
"day_high": "197.10",
"day_low": "195.93",
"52_week_high": "233.47",
"52_week_low": "142.00",
"day_change": "1.16",
"change_pct": "0.59",
"close_yesterday": "195.69",
"market_cap": "926316741610",
"volume": "8909408",
"volume_avg": "28596757",
"shares": "4715280000",
"stock_exchange_long": "NASDAQ Stock Exchange",
"stock_exchange_short": "NASDAQ",
"timezone": "EDT",
"timezone_name": "America/New_York",
"gmt_offset": "-14400",
"last_trade_time": "2019-04-05 12:28:19"
}
]
}
我收到了 catch 块错误消息
解码错误:keyNotFound(CodingKeys(stringValue: "stockValue", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue : 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"stockValue\", intValue: nil) (\"stockValue\").", underlyingError: nil))
我知道它的错误解码方式!所有所有字符串值都变成一个struct Portfolio
但是我可以通过以下 ProtfolioModel 来实现它吗?
解决方案
注意:仍然需要验证这一点,但这是我处理 JSON 的解决方案。
解码 JWT 有同样的问题。
步骤如下:
- 将数据转换为 UTF8
let data = response.data(using: .utf8)!
- 序列化 JSON 对象
guard let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] else { return }
- 使用 Struct 解释数据(根据需要修改)
struct Json {
let data: Array?
init(json: [String: Any]) {
data = json["data"] as? Array ?? []
}
}
- 获取数据作为对象键
let dataArray = Json(json: json)
let symbol = dataArray.data.symbol ?? ""
全部一起:
do {
let data = response.data(using: .utf8)!
guard let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] else { return }
let dataArray = Json(json: json)
let symbol = dataArray.data.symbol ?? ""
} catch {
let message = "Failed to extract token from json object"
// Your error message handle
// logMessage(messageText: message)
return
}
推荐阅读
- regex - 需要一个非常简单的正则表达式
- python - 如何获取单元格的宽度和高度(以像素为单位)?excel,openpyxl,python
- apache-flink - Flink 中的 advanceToEndOfEventTime 标志
- android - 在添加 android Fragment 中检查 onPause、onResume 和 onDestroy
- c++ - 在单独的头文件中使用共享枚举时出现 VS2015 C++ LNK2019 错误
- ruby-on-rails - 如何使用 RVM 在 OSX/Ubuntu 上设置 Ruby 的默认版本
- android - Android - 使用 Gradle 将构建输出复制到另一个文件夹
- android - 检查文档是否包含 2 个字符串
- python - 有什么改进我的 CNN 模型的建议(总是同样的低测试精度)?
- java - Jackson:在反序列化期间传递 exta 对象