Правильная обработка NSJSONSerialization (попытка catch) в Swift (2.0)?
arowmy init отлично работает в Swift < 2, но в Swift 2 я получаю сообщение об ошибке от Xcode 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]
. Я думаю, что в моем случае я не могу использовать блок catch try, потому что супер не инициализируется в это время. "Попробуйте" нужна функция, которая бросает.
вот моя функция:
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
Ответы
Ответ 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, см. предыдущую версию этого ответа.
Ответ 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)")
}
Тип error
в catch let error
равен ErrorType
Ответ 3
Не знаю, решит ли он вашу проблему, но не метод JSONObjectWithData:options:error:
? Я думаю, что вам не хватает параметра error
.