如何从json对象中提取值作为数据?
我试图解码一个json文件,但是它包含元数据,而不仅仅是一个简单的对象数组。目前,我的解决方案涉及将数据转换为json对象,提取结果,然后将其再次转换为数据,然后进行解码。它能用,但太乱了。有没有更直接的方法 我的json文件itemsActual.json:如何从json对象中提取值作为数据?,json,swift,Json,Swift,我试图解码一个json文件,但是它包含元数据,而不仅仅是一个简单的对象数组。目前,我的解决方案涉及将数据转换为json对象,提取结果,然后将其再次转换为数据,然后进行解码。它能用,但太乱了。有没有更直接的方法 我的json文件itemsActual.json: { "count": 2, "next": null, "previous": null, "results": [ { "id": 1, "
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"uid": "a019bf6c-44a2-11e9-9121-4ccc6afe39a1",
"company": "Bioseed",
"item_class": "Seeds",
"name": "9909",
"stock": 0,
"average_cost": 0.0,
"otc_price": 0.0,
"dealer_price": 0.0,
"ctc_price": 0.0
},
{
"id": 2,
"uid": "a019bf71-44a2-11e9-9121-4ccc6afe39a1",
"company": "Pioneer",
"item_class": "Seeds",
"name": "4124YR",
"stock": 0,
"average_cost": 0.0,
"otc_price": 0.0,
"dealer_price": 0.0,
"ctc_price": 0.0
}
]
}
我只想用类型数据清晰地提取结果: 也就是说,我想在不必先转换到字典然后再转换回数据的情况下执行以下操作: 编辑:当前我正在使用的代码,以实现我需要的:
let filename = "itemsActual.json"
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
// Load the json file with metadata
var data = try Data(contentsOf: file)
// Split up the string and extract only the value of results
let str = data.asString().components(separatedBy: "\"results\":")[1].dropLast(3)
print(str) // Printing here results in just the results
// Convert back to type Data so I can pass it off to be decoded
data = str.asData()
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
我想这里的问题是为什么只需要结果数组的内容? 你提到你对数组进行解码,所以我假设你在这里需要的只是一个包装容器结构,用于解码,例如类似这样的东西
struct ResultHolder: Decodable {
let results: [YourCustomType]
}
let resultHolder = try JSONDecoder().decode(ResultHolder.self, from: data)
//use your array:
print(resultHolder.results)
编辑:
我假设所有来自JSON的API的响应都遵循类似的结构。因此,现在是引入泛型的好时机。e、 g.例如:
struct ResultHolder<T>: Decodable where T: Decodable {
let results: [T]
}
这是不需要任何额外编码的最短和通用的方法,如果这对你来说是太多的代码,那么我想你的问题的答案是不,这是不可能的
do {
let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
if let results = json["results"] as? [[String: Any]] {
let dataResults = try JSONSerialization.data(withJSONObject: results)
}
} catch {
print(error)
}
你可以直接查询结果数组?这是我的问题。为了做到这一点,我需要1将其转换为字典2检索结果3将结果转换为数据。我想知道是否有一种更简洁的方法,直接将结果数组提取为数据?这里没有什么看起来混乱的。你能展示你的解码代码吗?我只是想清楚地提取数据,你这里的数据是什么意思。。。你们只想打印干净的数组列表???@Kamran我现在不在,所以我回来后会分享我的解码码!我只需要内容,因为我不希望为了处理数据而制作包装结构。对于几十个模型,如果我必须为每个模型编写一个包装器类,那么应用程序会很快变得臃肿。您可以引入泛型,或者您可以将包装器数据类型设置为解码函数的本地类型,这样就不会污染名称空间。我可以将泛型ResultHolder与不同的模型一起重用吗?因为这就是我需要的。如果不是这样的话,我仍然必须为每个模型编写一个,这会使我的应用程序膨胀。我现在正在尝试,但我似乎无法让它发挥作用,如果我做错了,请道歉是的,这就是泛型背后的想法。现在什么对你不起作用?哦,我明白了。那我可能是说错了。我将尝试做更多关于如何使用泛型的研究,看看是否能从这里开始工作。谢谢你引导我朝这个方向走!谢谢Joakim,这不完全是我想要的答案,但至少这比我现在拥有的感觉更合适
struct ResultHolder: Decodable {
let results: [YourCustomType]
}
let resultHolder = try JSONDecoder().decode(ResultHolder.self, from: data)
//use your array:
print(resultHolder.results)
struct ResultHolder<T>: Decodable where T: Decodable {
let results: [T]
}
do {
let json = try JSONSerialization.jsonObject(with: data) as! [String: Any]
if let results = json["results"] as? [[String: Any]] {
let dataResults = try JSONSerialization.data(withJSONObject: results)
}
} catch {
print(error)
}