在 Swift (2.0) 中正确处理 NSJSONSerialization (try catch)?
Posted
技术标签:
【中文标题】在 Swift (2.0) 中正确处理 NSJSONSerialization (try catch)?【英文标题】:Correct handling of NSJSONSerialization (try catch) in Swift (2.0)? 【发布时间】:2015-07-08 15:03:16 【问题描述】:arowmy init 在 Swift Call can throw, but it is not marked with 'try' and the error is not handled let anyObj = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]
收到一条错误消息。我认为就我而言,我不能使用 try catch 块,因为此时 super 尚未初始化。 “尝试”需要一个抛出的函数。
这是我的功能:
required init(coder aDecoder : NSCoder)
self.name = String(stringInterpolationSegment: aDecoder.decodeObjectForKey("name") as! String!)
self.number = Int(aDecoder.decodeIntegerForKey("number"))
self.img = String(stringInterpolationSegment: aDecoder.decodeObjectForKey("image") as! String!)
self.fieldproperties = []
var tmpArray = [String]()
tmpArray = aDecoder.decodeObjectForKey("properties") as! [String]
let c : Int = tmpArray.count
for var i = 0; i < c; i++
let data : NSData = tmpArray[i].dataUsingEncoding(NSUTF8StringEncoding)!
// Xcode(7) give me error: 'CAll can thorw, but it is not marked with 'try' and the error is not handled'
let anyObj = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]
let label = anyObj["label"] as AnyObject! as! String
let value = anyObj["value"] as AnyObject! as! Int
let uprate = anyObj["uprate"] as AnyObject! as! Int
let sufix = anyObj["sufix"] as AnyObject! as! String
let props = Fieldpropertie(label: label, value: value, uprate: uprate, sufix: sufix)
self.fieldproperties.append(props)
Xcode 的意思是:
let anyObj = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]
但我不知道在这里根据这个文档做正确的想法https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html
【问题讨论】:
请阅读全文,而不仅仅是您认为重要的部分。你已经有了一个“抛出的函数”——NSJSONSerialization.JSONObjectWithData
。
@Rob 是的,我的意思是 Swift 2.0。
投了反对票,因为示例代码对以前的方法和示例没有用处。
@NathanMcKasklei 不明白你的意思。该代码描述了我的问题。
【参考方案1】:
jsonObject
可以出现throw
错误,因此将其放在do
块中,使用try
和catch
引发的任何错误。在 Swift 3 中:
do
let anyObj = try JSONSerialization.jsonObject(with: data) as! [String: Any]
let label = anyObj["label"] as! String
let value = anyObj["value"] as! Int
let uprate = anyObj["uprate"] as! Int
let sufix = anyObj["sufix"] as! String
let props = Fieldpropertie(label: label, value: value, uprate: uprate, sufix: sufix)
// etc.
catch
print("json error: \(error.localizedDescription)")
或者,在 Swift 4 中,您可以通过使 struct
符合 Codable
来简化代码:
struct Fieldpropertie: Codable
let label: String
let value: Int
let uprate: Int
let suffix: String
然后
do
let props = try JSONDecoder().decode(Fieldpropertie.self, from: data)
// use props here; no manual parsing the properties is needed
catch
print("json error: \(error.localizedDescription)")
对于 Swift 2,请参阅 previous revision of this answer。
【讨论】:
哦,谢谢。它工作正常。我不知道为什么我没有这样做;) @SaumilShah,见编辑:catch let error1 as NSError print("json error: (error1.localizedDescription)") 我试过了,但 Xcode 说 create throw....你能分享一下带 throw 的句柄的例子吗? @SaumilShah - 我们可以向您展示如何投掷,但最好只参考The Swift Programming Languages: Error Handling。或者使用reproducible 收到的错误示例创建您自己的问题。 非常感谢您的支持【参考方案2】:JSONSerialization.JSONObject 抛出 ErrorType 而不是 NSError。
所以正确的捕获是
do
let anyObj = try JSONSerialization.JSONObject(with: data, options: []) as! [String:AnyObject]
// use anyObj here
catch let error
print("json error: \(error)")
catch let error
中error
的类型是ErrorType
【讨论】:
根据文档JSONObjectWithData会抛出一个NSError,它符合ErrorType。 是的,这就是文字所说的。编码合约显示 ErrorType。当您在闭包中执行此操作并且不遵守编码合同时,您将得到非常难以理解的错误。当你只捕获 NSError 时,编译器必须假设还有未捕获的情况,这可能会导致上下文出现问题。 localizedDescription 没有为 ErrorType 定义。我在let error as ErrorType
线上有一条警告说测试总是正确的。
你是对的,ErrorType
在let error as ErrorType
中是多余的,并且它没有本地化描述。并且它没有本地化描述。我会在这里修正我的答案。【参考方案3】:
不知道能不能解决你的问题,方法不就是JSONObjectWithData:options:error:
吗?我认为您缺少 error
参数。
【讨论】:
不,在 Swift 2.0 中,您拥有新的try
-catch
机制,JSONObjectWithData
现在不使用 error
参数,而是抛出错误。
@Rob 啊,我明白了。问题是 Swift 1.2,这是我正在使用的,所以我认为这可能是问题所在。以上是关于在 Swift (2.0) 中正确处理 NSJSONSerialization (try catch)?的主要内容,如果未能解决你的问题,请参考以下文章