使用 SwiftyJSON 解析 JSON 响应而不会崩溃
Posted
技术标签:
【中文标题】使用 SwiftyJSON 解析 JSON 响应而不会崩溃【英文标题】:Parse JSON response with SwiftyJSON without crash 【发布时间】:2016-07-07 10:26:41 【问题描述】:我的 ios 应用正在从服务器获取 JSON 响应
let myURL = NSURL(string: SERVER_URL);
let request = NSMutableURLRequest(URL:myURL!);
request.HTTPMethod = "POST";
let postString = ""
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data, response, error in
if error != nil
print("error=\(error)")
return
dispatch_async(dispatch_get_main_queue(),
var json = JSON(data: data!)
let someInt = json["someInt"].int
let message = json["message"].stringValue
有时服务器已关闭或 JSON 中可能存在错误,因此不会有此类值(消息、someInt),我想在不导致应用崩溃的情况下处理它 - 我该怎么办?
【问题讨论】:
【参考方案1】:使用 SwiftyJSON,非可选的 getter 以 Value
结尾,而可选的 getter 则不是。
所以要测试该值是否在这里,您可以使用可选绑定 if let
:
if let someInt = json["someInt"].int,
message = json["message"].string
// someInt and message are available here
else
// someInt and message are not available
或者guard
:
guard let someInt = json["someInt"].int,
message = json["message"].string else
// error, someInt and message are not available
return
// someInt and message are available here
【讨论】:
不是 SwiftyJSON,而是如何处理错误的一个很好的例子:***.com/a/31808605/2227743【参考方案2】:很简单,您可能已经知道了,您可以使用以下方法保护您的代码:
if let someInt = json["someInt"].int
// do whatever you want with someInt
if let message = json["message"].string
// do whatever you want with message
试试这个方法:
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data, response, error in
if let data = data,
jsonString = NSString(data: data, encoding: NSUTF8StringEncoding)
where error == nil
var json = JSON(data: data!)
// use some protection as explained before..
else
print("error=\(error!.localizedDescription)")
task.resume()
【讨论】:
我认为问题出在之前的某个地方(var json = JSON(data: data!)
)
NSString(data:_, encoding:_)
接受非可选值,你应该在之前验证data
(因为 NSURLSession 返回一个可选数据)。那么你不能假设 responseString 不为空。这可能会导致崩溃【参考方案3】:
让我也发布我的答案 =)
首先你可以为失败的 JSON 初始化器实现小的扩展:
extension JSON
init?(_ data: NSData?)
if let data = data
self.init(data: data)
else
return nil
您可以将它放在全局范围内并导入SwiftyJSON
,而忘记在JSON
中使用之前强制解包数据。如果您使用它们,可以为其他数据类型编写相同的失败初始化程序。它只是为了将来更短且可读的代码。对于许多路由或在某些情况下,例如当您从 json 中等待某些单个字段时,此扩展可以使您的代码看起来非常简单易读:
guard let singleMessage = JSON(data: data)?["message"].string else return
然后你需要以你需要的方式检查 nil (实际上在之前的答案中解释过)。可能您正在搜索完全有效的数据,所以使用 if-let 链:
let myURL = NSURL(string: SERVER_URL);
let request = NSMutableURLRequest(URL:myURL!);
request.HTTPMethod = "POST";
let postString = ""
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data, response, error in
if error != nil
print("error=\(error)")
return
dispatch_async(dispatch_get_main_queue())
if let json = JSON(data: data),
someInt = json["someInt"].int,
message = json["message"].string,
// ...
// all data here, do what you want
else
print("error=\(error)")
return
【讨论】:
【参考方案4】:最好是使用 try catch 来处理
request.HTTPBody = postdata.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
(data, response, error) in
dispatch_async(dispatch_get_main_queue(),
var jsondata: AnyObject?
do
let jsondata = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
print(jsondata)
// your code here
catch
print("Some Error Found")
)
task.resume()
如果您遇到任何错误,您将在控制台中收到一条消息,从而防止应用程序崩溃
【讨论】:
是但不是:OP 没有使用 NSJSONSerialization,他们使用的是 SwiftyJSON。 谢谢,但我真的需要 SwiftyJSON 的解决方案!以上是关于使用 SwiftyJSON 解析 JSON 响应而不会崩溃的主要内容,如果未能解决你的问题,请参考以下文章
我应该如何使用 Alamofire 和 SwiftyJSON 解析来自 API 的 JSON 响应?