使用可编码并忽略 JSON 的第一层解析 JSON
Posted
技术标签:
【中文标题】使用可编码并忽略 JSON 的第一层解析 JSON【英文标题】:Parsing JSON using codable and ignoring first layer of JSON 【发布时间】:2017-12-19 01:25:58 【问题描述】:我有这样的 JSON:
"success": true,
"message": "",
"result":
"buy": [
"Quantity": 0.0056,
"Rate": 18527
,
"Quantity": 0.11431426,
"Rate": 18526
],
"sell":[
"Quantity": 8.20604116,
"Rate": 18540
,
"Quantity": 0.95600491,
"Rate": 18574.99999998
]
还有一组这样的 JSON:
"lastUpdateId": 1027024,
"bids": [
[
"4.00000000", // PRICE
"431.00000000", // QTY
[] // Can be ignored
]
],
"asks": [
[
"4.00000200",
"12.00000000",
[]
]
]
使用 codable 解析这两个响应的最佳方法是什么?它们都需要使用相同的结构进行解析,或者需要转换为相同的结构(无论哪种方式都能更快地完成工作)。我不想为整个第一个响应创建一个结构,因为我不会使用像 "success"
和 "message"
这样的键。我基本上想忽略这些并直接访问"result"
键但是在第二个响应中,我将使用所有数据,因此我创建了一个名为TotalOrderBook
的结构。做这个的最好方式是什么?
让我感到困惑的是忽略第一个 JSON 响应中的键 "success"
和 "message"
并直接获取键 "result"
的值。是否可以在不创建额外结构的情况下做到这一点?
这就是我现在所拥有的。我想避免添加另一个结构,因为我真正需要的是买/卖和卖/卖下的值。
struct TotalOrderBook:Codable
var buy:[UniversalOrder]?
var sell:[UniversalOrder]?
var bid:[UniversalOrder]?
var ask:[UniversalOrder]?
var buyOrderBook: [UniversalOrder]
return bid ?? buy ?? [UniversalOrder]()
var sellOrderBook: [UniversalOrder]
return ask ?? sell ?? [UniversalOrder]()
var updatedTime:Date
struct UniversalOrder:Codable
var price : Double
return Double(rate ?? binPrice ?? 0)
var size : Double
return Double(quantity ?? binQuantity ?? 0 )
//let numOrders : Int
var quantity:Double?
var rate:Double?
var binPrice:Double?
var binQuantity:Double?
private enum CodingKeys: String, CodingKey
case rate = "Rate"
case quantity = "Quantity"
//case numOrders, binPrice,
init(from decoder: Decoder) throws
var container = try decoder.unkeyedContainer()
binPrice = Double(try container.decode(String.self)) ?? nil
binQuantity = Double(try container.decode(String.self)) ?? nil
quantity = nil
rate = nil
这就是我的解码方式:
let decoder = JSONDecoder()
let data = try! JSONSerialization.data(withJSONObject: value) //value is the response from Alamofire
var theWholeOrderBook:UniversalOrder!
do
theWholeOrderBook = try decoder.decode(UniversalOrder.self, from: data)
catch let error
//print ("error is \(e) ** \(value)")
【问题讨论】:
请注意,Swift 是一种类型推断语言return bid ?? buy ?? []
和 catch let error
是多余的,只是 catch
【参考方案1】:
要直接回答您的问题,是的,很容易忽略 success
和 message
键值对并直接访问 results
。
尽管如此,使用单个结构来解析这两个 JSON 响应会有点复杂。 它们都具有非常不同的结构,这将使使用两个不同的结构来使用编码变得更加容易。突出一些差异:
buy
、sell
嵌套在 results
中。 bids
、asks
不是。
键完全不同。
buy
、sell
有一个键值对数组,而bids
、asks
simple 有一个值数组。
可编码结构应该简单明了。最好有两个对应于每个响应。
【讨论】:
完美。一旦我得到这两个,我应该将它们转换为一个吗?如何忽略成功和消息键值对? 我建议使用不同的结构来对它们进行编码。您不必“忽略”任何键。只需解析您想要解析的键,其余的不用操心。 但我不想有一个只有result
值的结构。那不是没有意义吗?没有办法直接获取 result
键中的值
您的代码已经在这样做了。我的回答是解决你关于拥有两种不同结构的具体问题,如果你想要 Swift 4 中的 JSON 指南,那么这里有一个......benscheirman.com/2017/06/swift-json
我已经看过这个指南了。这是惊人的。但是我仍然无法弄清楚如何在不创建新结构来解析它们的情况下忽略该成功和消息。解码时有没有办法做到这一点?我已添加到我的答案中,以向您展示我是如何进行解码的以上是关于使用可编码并忽略 JSON 的第一层解析 JSON的主要内容,如果未能解决你的问题,请参考以下文章