使用 Decodable(嵌套数组)解析不同的 JSON
Parse different JSON with Decodable (Nested array)
我正在开发来自 NiceHash api 的应用程序。我必须使用的 JSON 看起来像这样:
{
"result":{
"addr":"37ezr3FDDbPXWrCSKNfWzcxXZnc7qHiasj",
"workers":[
[ "worker1", { "a":"45.7" }, 9, 1, "32", 0, 14 ],
[ "worker1", { }, 5, 1, "100000", 0, 22 ],
]
"algo":-1
},
"method":"stats.provider.workers"
}
为了解析做了这样的结构
struct Root: Decodable {
var result: WorkersResult?
var method: String?
}
struct WorkersResult: Decodable {
var addr: String?
var workers: [Workers]?
var algo: Int?
}
struct Workers: Decodable {
var worker: [Worker]?
}
struct Worker: Decodable {
var name: String?
var hashrate: Hashrate?
var time: Int?
var XNSUB: Int?
var difficult: String?
var reject: Int?
var algo: Int?
}
struct Hashrate: Decodable {
var rate: String?
}
响应等于零,我不明白我做错了什么,我知道问题出在解析工人数组上,因为如果我评论工人,响应等于一些有效数据。
感谢您的帮助!
您 JSON 实际上是无效的,因为逗号放错了。 运行 它通过 JSON 验证器得到我现在的意思。
总之,由于Worker
(单数)被编码为一个数组,你需要为它提供一个自定义的解码器。 Workers
(复数)是不必要的。
struct Root: Decodable {
var result: WorkersResult?
var method: String?
}
struct WorkersResult: Decodable {
var addr: String?
var workers: [Worker]?
var algo: Int?
}
struct Worker: Decodable {
var name: String?
var hashrate: Hashrate?
var time: Int?
var XNSUB: Int?
var difficult: String?
var reject: Int?
var algo: Int?
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
name = try container.decodeIfPresent(String.self)
hashrate = try container.decodeIfPresent(Hashrate.self)
time = try container.decodeIfPresent(Int.self)
XNSUB = try container.decodeIfPresent(Int.self)
difficult = try container.decodeIfPresent(String.self)
reject = try container.decodeIfPresent(Int.self)
algo = try container.decodeIfPresent(Int.self)
}
}
struct Hashrate: Decodable {
var rate: String?
private enum CodingKeys: String, CodingKey {
case rate = "a"
}
}
用法:
let jsonData = """
{
"result":{
"addr":"37ezr3FDDbPXWrCSKNfWzcxXZnc7qHiasj",
"workers":[
[ "worker1", { "a":"45.7" }, 9, 1, "32", 0, 14 ],
[ "worker1", { }, 5, 1, "100000", 0, 22 ]
],
"algo":-1
},
"method":"stats.provider.workers"
}
""".data(using: .utf8)!
let r = try JSONDecoder().decode(Root.self, from: jsonData)
print(r)
我正在开发来自 NiceHash api 的应用程序。我必须使用的 JSON 看起来像这样:
{
"result":{
"addr":"37ezr3FDDbPXWrCSKNfWzcxXZnc7qHiasj",
"workers":[
[ "worker1", { "a":"45.7" }, 9, 1, "32", 0, 14 ],
[ "worker1", { }, 5, 1, "100000", 0, 22 ],
]
"algo":-1
},
"method":"stats.provider.workers"
}
为了解析做了这样的结构
struct Root: Decodable {
var result: WorkersResult?
var method: String?
}
struct WorkersResult: Decodable {
var addr: String?
var workers: [Workers]?
var algo: Int?
}
struct Workers: Decodable {
var worker: [Worker]?
}
struct Worker: Decodable {
var name: String?
var hashrate: Hashrate?
var time: Int?
var XNSUB: Int?
var difficult: String?
var reject: Int?
var algo: Int?
}
struct Hashrate: Decodable {
var rate: String?
}
响应等于零,我不明白我做错了什么,我知道问题出在解析工人数组上,因为如果我评论工人,响应等于一些有效数据。 感谢您的帮助!
您 JSON 实际上是无效的,因为逗号放错了。 运行 它通过 JSON 验证器得到我现在的意思。
总之,由于Worker
(单数)被编码为一个数组,你需要为它提供一个自定义的解码器。 Workers
(复数)是不必要的。
struct Root: Decodable {
var result: WorkersResult?
var method: String?
}
struct WorkersResult: Decodable {
var addr: String?
var workers: [Worker]?
var algo: Int?
}
struct Worker: Decodable {
var name: String?
var hashrate: Hashrate?
var time: Int?
var XNSUB: Int?
var difficult: String?
var reject: Int?
var algo: Int?
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
name = try container.decodeIfPresent(String.self)
hashrate = try container.decodeIfPresent(Hashrate.self)
time = try container.decodeIfPresent(Int.self)
XNSUB = try container.decodeIfPresent(Int.self)
difficult = try container.decodeIfPresent(String.self)
reject = try container.decodeIfPresent(Int.self)
algo = try container.decodeIfPresent(Int.self)
}
}
struct Hashrate: Decodable {
var rate: String?
private enum CodingKeys: String, CodingKey {
case rate = "a"
}
}
用法:
let jsonData = """
{
"result":{
"addr":"37ezr3FDDbPXWrCSKNfWzcxXZnc7qHiasj",
"workers":[
[ "worker1", { "a":"45.7" }, 9, 1, "32", 0, 14 ],
[ "worker1", { }, 5, 1, "100000", 0, 22 ]
],
"algo":-1
},
"method":"stats.provider.workers"
}
""".data(using: .utf8)!
let r = try JSONDecoder().decode(Root.self, from: jsonData)
print(r)