在api中我得到以下数据,在这里我需要得到所有数组中的总名数
{
"Flat": [
{
"price": "$5.00",
"id": 11,
"name": "Fixed"
}
],
"United Parcel Service": [
{
"price": "$109.12",
"id": 1,
"name": "worldwide Expedited"
},
{
"price": "$120.18",
"id": 2,
"name": "worldwide Express saver"
}
]
}
我尝试了以下代码来获取所有数组中的名称数
var arrayss = [String:AnyObject]()
var keys = [String]()
let urlString = "http://www.json-generator.com/api/json/get/bVgbyVQGmq?indent=2"
var totalCount = 0
func shippingmethodURL() {
let url = NSURL(string: self.urlString)
URLSession.shared.dataTask(with: (url as URL?)!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
self.arrayss = jsonObj as! [String : AnyObject]
self.keys = jsonObj?.allKeys as! [String]
OperationQueue.main.addOperation({
self.shippingTableView.reloadData()
let sectionHeight = self.arrayss.count * 31
let cellHeight = self.keys.count * 44
self.shippingHeightConstraint.constant = CGFloat(sectionHeight + cellHeight)
self.heightConstant = Int(self.shippingHeightConstraint.constant)
self.delegate?.heightConstant(int: self.heightConstant!)
})
}
}).resume()
}
答案 0 :(得分:0)
首先,当它们具有原生的Swift等价物时(例如Foundation
和NSURL
),请不要使用NSDictionary
数据类型。
除此之外,你的问题是你在计算字典的键。但是,您要做的是遍历您的字典,使用条件转换检查与该键关联的值是否为数组,如果它是一个数组,请检查该数组的字典元素是否具有“name “键,如果有,则增加计数,否则什么也不做。
在解析JSON数据时也不要使用强制解包和强制转换,因为在网络响应中,这些可能会失败并且您的应用程序会崩溃。
func shippingmethodURL() {
guard let url = URL(string: self.urlString) else {return}
URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) -> Void in
if let data = data, let jsonObj = (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String:AnyObject] {
self.arrayss = jsonObj
self.keys = Array(jsonObj.keys)
var totalCount = 0
for value in jsonObj.values {
if let array = value as? [[String:Any]] {
for element in array {
if let name = element["name"] as? String {
totalCount += 1
}
}
}
}
//update UI and other variables here
}
}).resume()
}
答案 1 :(得分:0)
正如在其他答案中所建议的那样,您应该始终考虑除NS
前缀之外的原生Swift类型(即NSDictionary
,NSURL
)。因此,您应该将原生Swift类型用作Dictionary
和URL
。另一件事是 最好使用Any
以外的AnyObject
。你可以看看here为什么我这么说。
说得够,你应该看看:
var arrayss = [String:Any]()
var keys = [String]()
let urlString = "http://www.json-generator.com/api/json/get/bVgbyVQGmq?indent=2"
var nameKeyCount = 0
func shippingmethodURL() {
guard let url = URL(string: self.urlString) else {return}
URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) -> Void in
if let data = data, let jsonObj = (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String:Any] {
self.arrayss = jsonObj
self.keys = Array(jsonObj.keys)
// Now you want to know the count for `name` key
// Below is the standard way in swift.
// Looping through each of the object is cumbersome
self.nameKeyCount = jsonObj.flatMap { $0.value.flatMap { $0.filter { $0.key == "name" } } }.count
// As URLSession's data task is an asynchronous task and done in a thread other than main thread, you should have your main thread to update any UI related thing
Dispatch.main.async {
// update UI here
}
}
}).resume()
}