我正在尝试解码json文件,但是它包含元数据,而不仅仅是对象的直接排列。目前,我的解决方案涉及将数据转换为json对象,提取results
,然后再将其转换为Data
,然后进行解码。它可以工作,但是太乱了。有没有更直接的方法?
我的json文件“ itemsActual.json”:
{
"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
}
]
}
我只想干净提取类型为Data
的结果:
[
{
"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
}
]
I.E。我想执行以下操作而不必先强制转换为Dictionary
,然后重新转换为Data
:
// What I want to do
let data: Data = try Data(contentsOf: "items.json")
let resultsData: Data = data["results"]
编辑:当前,我正在使用的代码可以实现所需的功能:
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)")
}
答案 0 :(得分:1)
let dataContacts = // your array or dict
let data = try JSONEncoder().encode(dataContacts) // converting to data
答案 1 :(得分:1)
我猜这里的问题是“为什么只需要结果数组的内容?”
您提到您decode
个数组,所以我假设这里所需的只是一个包装容器结构,仅用于解码,例如像这样
struct ResultHolder: Decodable {
let results: [YourCustomType]
}
let resultHolder = try JSONDecoder().decode(ResultHolder.self, from: data)
//use your array:
print(resultHolder.results)
编辑:
我假设您对API的所有响应(即JSON的来源)都遵循类似的结构。因此,现在是引入泛型的好时机。例如像:
struct ResultHolder<T>: Decodable where T: Decodable {
let results: [T]
}
答案 2 :(得分:1)
这是最短,最通用的方法,不需要任何额外的编码,如果这对您来说是很多代码,那么我想您的问题的答案是“不,它无法完成”
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)
}