Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从json对象中提取值作为数据?_Json_Swift - Fatal编程技术网

如何从json对象中提取值作为数据?

如何从json对象中提取值作为数据?,json,swift,Json,Swift,我试图解码一个json文件,但是它包含元数据,而不仅仅是一个简单的对象数组。目前,我的解决方案涉及将数据转换为json对象,提取结果,然后将其再次转换为数据,然后进行解码。它能用,但太乱了。有没有更直接的方法 我的json文件itemsActual.json: { "count": 2, "next": null, "previous": null, "results": [ { "id": 1, "

我试图解码一个json文件,但是它包含元数据,而不仅仅是一个简单的对象数组。目前,我的解决方案涉及将数据转换为json对象,提取结果,然后将其再次转换为数据,然后进行解码。它能用,但太乱了。有没有更直接的方法

我的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
        }
    ]
}

我只想用类型数据清晰地提取结果:

也就是说,我想在不必先转换到字典然后再转换回数据的情况下执行以下操作:

编辑:当前我正在使用的代码,以实现我需要的:

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)
}