swift - 快速解码复合结构数据
问题描述
我有以下 json 数据并试图解析它,但我得到了对象的数量,但数组中的对象本身都是零。
我不想解码origin
下面的 json 对象。
顺便说一句,下面的字符串首先转换为数据,然后将其传递给parse
下面的函数。
数据如下:
[
[
{"id": "152478", "age": 20},
{"character": "king","isDead":"no", "canMove" :"yes", "origin" :"south africa"}
],
[
{"id": "887541", "age": 22},
{"character": "lion", "isDead":"no", "canMove" :"yes", "origin" :"south america"}
]
]
楷模
struct A: Codable {
let id: String?
let age: Int?
enum CodingKeys: String, CodingKey {
case id
case age
}
}
struct B: Codable {
let character, isDead, canMove: String?
enum CodingKeys: String, CodingKey {
case character
case isDead
case canMove
}
}
struct AB :Codable {
let a: A
let b: B
init(from decoder: Decoder) throws {
guard var container = try? decoder.unkeyedContainer() else {
//no error here!!!
fatalError()
}
print(container)
guard let a = try? container.decode(A.self),
let b = try? container.decode(B.self)
else {
// throw since we didn't find A first, followed by B
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: nil)
)
}
self.a = a
self.b = b
}
}
视图模型
private func parse(jsonData : Data){
do {
let decoder = JSONDecoder()
let response = try decoder.decode([AB].self, from: jsonData)
print(response)
}
catch (let error as NSError) {
print(error)
}
}
更新: 顺便说一句,以下代码有效。我想知道为什么上面的代码不能处理?
private func parseData(jsonData : Data)
{
do {
response = try JSONSerialization.jsonObject(with: jsonData) as! [[[String: Any]]]
for i in 0..<response.count
{
for j in 0..<response[i].count
{
if j == 0
{
let jsonDat = (try? JSONSerialization.data(withJSONObject:response[i][j]))!
let b = try JSONDecoder().decode(A.self, from: jsonDat)
}
else if j == 1
{
let jsonDatt = (try? JSONSerialization.data(withJSONObject:response[i][j]))!
let a = try JSONDecoder().decode(B.self, from: jsonDatt)
}
}
}
print(response)
}
catch let error as NSError {
print(error)
}
}
更新二:
如果我进行以下更改[AB]
--> [[AB]]
,然后按如下方式调用它,它会解码数据,但在我最终得到的数组中,A 对象有值,但 B 为零,反之亦然。
let response = try decoder.decode([[AB]].self, from: jsonData)
guard var container = try? decoder.singleValueContainer() else
{
fatalError()
}
解决方案
我刚刚在操场上尝试了您的代码的精简版本
let json = """
[
[
{"id": "152478", "age": 20},
{"character": "king","isDead":"no", "canMove" :"yes", "origin" :"south africa"}
],
[
{"id": "887541", "age": 22},
{"character": "lion", "isDead":"no", "canMove" :"yes", "origin" :"south america"}
]
]
""".data(using: .utf8)!
struct A: Codable {
let id: String
let age: Int
}
struct B: Codable {
let character, isDead, canMove: String
}
struct AB: Codable {
let a: A
let b: B
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
self.a = try container.decode(A.self)
self.b = try container.decode(B.self)
}
}
do {
let ab = try JSONDecoder().decode([AB].self, from: json)
print(ab.count)
print(ab[0].a.id)
print(ab[0].b.character)
print(ab[1].a.id)
print(ab[1].b.character)
} catch {
print(error)
}
它工作得很好。也许这有助于弄清楚发生了什么。
推荐阅读
- javascript - 如何使用 Vanilla Javascript 检查标签中是否包含图像?
- c# - 在 C# 中使用 Exchange ActiveSync
- javascript - GreaseMonkey - 防止在线脚本
- python - 我似乎无法在没有错误的情况下在 django 中使用 DateTimeField
- android - 找不到明确的活动类 {...}; 您是否在 AndroidManifest.xml 中声明了此活动?
- javascript - React-Redux - TypeError:state.menu 不可迭代
- typescript - Typescript - 为什么没有相应地强制实现接口
- javascript - Angular-7 - 如何创建混合网络和气泡图
- r - R中两个数据集之间的近似字符串匹配
- json - Filtering with regex vs json