使用 Swift 将 JSON 字符串转换为 NSDictionary
Posted
技术标签:
【中文标题】使用 Swift 将 JSON 字符串转换为 NSDictionary【英文标题】:JSON String to NSDictionary with Swift 【发布时间】:2015-03-17 05:46:35 【问题描述】:我正在尝试从服务器中保存的数据创建字典,我收到数据但无法将数据转换为 NSDictionary
,我相信它保存在 NSData
对象中
let JSONDictionary: Dictionary = NSJSONSerialization.JSONObjectWithData(JSONData!, options: nil, error: &error) as NSDictionary
这行代码给我带来了问题,它抛出了BAD_EXEC_INSTRUCTION
。
我的问题:如何将JSON
变成NSDictionary
?
【问题讨论】:
你能发布一些代码来显示你的 NSData 对象是如何声明的以及你在哪里/如何初始化它。 【参考方案1】:您的代码不进行任何错误处理。但它可能(如果此数据来自 Web 服务,将会)以多种方式失败。
-
您必须确保您的数据对象确实存在
您必须确保数据对象可以转换为 JSON
您必须确保 JSON 实际上包含字典
您应该使用 Swift 的条件转换和它的可选绑定功能。
可选绑定 if let JSONData = JSONData
检查 JSONData 是否不为零。如果无法接收到数据,您使用的强制展开 (JSONData!
) 可能会崩溃。
可选绑定if let json = NSJSONSerialization.JSONObjectWithData
检查数据是否可以转换为 JSON 对象。条件转换 as? NSDictionary
检查 JSON 对象是否实际上是字典。您目前不使用这些检查,而是将对象转换为 NSDictionary。如果对象不是有效的 json,或者它不是字典,则会崩溃。
我会推荐这样的东西:
var error: NSError?
if let JSONData = JSONData // Check 1
if let json: AnyObject = NSJSONSerialization.JSONObjectWithData(JSONData, options: nil, error: &error) // Check 2
if let jsonDictionary = json as? NSDictionary // Check 3
println("Dictionary received")
else
if let jsonString = NSString(data: JSONData, encoding: NSUTF8StringEncoding)
println("JSON String: \n\n \(jsonString)")
fatalError("JSON does not contain a dictionary \(json)")
else
fatalError("Can't parse JSON \(error)")
else
fatalError("JSONData is nil")
您可以将检查 2 和 3 合并为一行,并检查 NSJSONSerialization 是否可以直接创建 NSDictionary:
var error: NSError?
if let JSONData = JSONData // Check 1.
if let JSONDictionary = NSJSONSerialization.JSONObjectWithData(JSONData, options: nil, error: &error) as? NSDictionary // Check 2. and 3.
println("Dictionary received")
else
if let jsonString = NSString(data: JSONData, encoding: NSUTF8StringEncoding)
println("JSON: \n\n \(jsonString)")
fatalError("Can't parse JSON \(error)")
else
fatalError("JSONData is nil")
确保在您的生产代码中使用适当的错误处理替换 fatalError
【讨论】:
【参考方案2】:Swift 2 更新。
现在你必须在 try catch 块中使用它。
do
let responseObject = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String:AnyObject]
catch let error as NSError
print("error: \(error.localizedDescription)")
【讨论】:
@zaid-pathan 我已取消您的编辑,因为它引入了一个问题。如果你删除了 NSError 向下转换,你就不能再在error
上调用 localizedDescription
方法了。请避免进行太多更改代码的编辑。谢谢你。 :)【参考方案3】:
这里jsonResult
会给你NSDictionary
的回复:
let url = NSURL(string: path)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: data, response, error -> Void in
println("Task completed")
if(error != nil)
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if(err != nil)
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
)
task.resume()
【讨论】:
第二个错误中的注释应该是:// If there is an error parsing JSON, this line will never be reached because the code errors out when you try to unwrap a nil value
以上是关于使用 Swift 将 JSON 字符串转换为 NSDictionary的主要内容,如果未能解决你的问题,请参考以下文章
Swift3 JSON字符串转字典和字典转JSON字符串的实现
使用大引号时,将字符串 JSON 转换为 Swift 中的字典
使用 Swift 4 Decodable 将字符串 JSON 响应转换为布尔值