在Swift 3中解析JSON时出错
我正在使用Swift 3中的iOS应用程序,并且调用服务器并返回json并将其序列化。在Swift 3中解析JSON时出错
当我尝试分析它,我得到这个错误:
"Could not cast value of type '__NSArrayI' (0x1a779acc8) to 'NSDictionary' (0x1a779b128). 2017-03-16 09:53:00.710776 AutoBuddy[3164:706970] Could not cast value of type '__NSArrayI' (0x1a779acc8) to 'NSDictionary' (0x1a779b128)."
我已经看到了这个问题的其他几个版本,但我仍然感到困惑。从我所知道的情况来看,JSON可以作为带有键值对的字典返回[String:Any]。
我试着明确地调用了“as?Dictionary < String,Any>但是失败的调用结果,这对我没有意义,因为我似乎正在获取字典,但它不表现行为作为一个目前该程序崩溃在我的parseJSON函数的第一行我有一种感觉,问题是要么我得到的JSON回来,或如何序列化它,因为我已经使用过类似的解析方法之前和它总是工作或者如果它是一个分析问题,可能有人向我解释,正确的方法来分析这一点,我会后的代码,它序列化JSON的例子
JSON:?
["id": 745, "year": 1995, "styles": <__NSArrayI 0x170e68f00>(
{
id = 7654;
name = "2dr Coupe";
submodel = {
body = Coupe;
modelName = "Mustang Coupe";
niceName = coupe;
};
trim = Base;
},
{
id = 7653;
name = "2dr Convertible";
submodel = {
body = Convertible;
modelName = "Mustang Convertible";
niceName = convertible;
};
trim = Base;
},
{
id = 7648;
name = "GT 2dr Coupe";
submodel = {
body = Coupe;
modelName = "Mustang Coupe";
niceName = coupe;
};
trim = GT;
},
{
id = 7647;
name = "GT 2dr Convertible";
submodel = {
body = Convertible;
modelName = "Mustang Convertible";
niceName = convertible;
};
trim = GT;
},
{
id = 7650;
name = "GTS 2dr Coupe";
submodel = {
body = Coupe;
modelName = "Mustang Coupe";
niceName = coupe;
};
trim = GTS;
}
)
]
Swift代码:
func getJSONData(path: String)
{
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: path + "API key")!
let task = session.dataTask(with: url, completionHandler:
{
(data, response, error) in
if error != nil
{
print(error!.localizedDescription)
}
else
{
do {
if let resultJSON = try JSONSerialization.jsonObject(with: data!) as? [String: Any]
{
print(resultJSON)
self.parseJSON(json: resultJSON)
}
}
catch
{
print("\(error)")
}
}
})
task.resume()
}
func parseJSON(json: [String: Any])
{
let styles = json["styles"] as! [String:Any] // Crashes Here
print(styles)
let names = styles["name"] as! String
print(names)
}
我最终解决了这个问题,以防万一任何人将此作为参考。
func getJSONData(path: String)
{
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: path + API_Key)!
let task = session.dataTask(with: url, completionHandler:
{
(data, response, error) in
if error != nil
{
print(error!.localizedDescription)
}
else
{
do {
let resultJSON = try JSONSerialization.jsonObject(with: data!) as! [String: Any]
let styles = resultJSON["styles"] as! NSArray
for i in 0..<styles.count
{
let name = styles[i] as! Dictionary<String, Any>
self.trims.append(name["name"] as! String)
}
DispatchQueue.main.async() {
self.tableView.reloadData()
self.tableView.isHidden = false
return
}
}
catch
{
print("Error: \(error)")
}
}
})
task.resume()
}
请仔细阅读JSON,这是非常容易的:
-
[]
表示一个数组中,斯威夫特[[String:Any]]
或有时[Any]
-
{}
代表一个字典,在Swift[String:Any]
。
为styles
的价值显然是一个阵列(甚至明文指出:“风格”:< __NSArrayI 0x170e68f00>)
let styles = json["styles"] as! [[String:Any]]
,你需要一个重复循环,以获得名
for style in styles {
let name = style["name"] as! String
print(name)
}
,或者您可以使用flatMap
let names = styles.flatMap { $0["name"] as? String }
print(names)
PS:在JSON的根对象似乎也是一个数组,如果是的话,你需要投
if let resultJSON = try JSONSerialization.jsonObject(with: data!) as? [[String: Any]]
然后,你必须也改变
func parseJSON(json: [[String: Any]]) {
let styles = json[0]["styles"] as! [[String:Any]]
避免方括号混淆我建议使用类型别名:
typealias JSONDictionary = [String:Any]
然后一个字典是JSONDictionary
,一个字典数组是[JSONDictionary]
,很容易区分。
的[在夫特3正确地分析JSON]可能的复制(http://*.com/questions/39423367/correctly-parsing-json-in-swift-3) – JAL