Подтвердить что ты не робот

Правильная обработка 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

4b9b3361

Ответ 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.