2015-07-08 14 views
29

Arowmy init działa dobrze w Swift < 2, ale w Swift 2 dostaję komunikat o błędzie z Xcode Call can throw, but it is not marked with 'try' and the error is not handled o let anyObj = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]. Myślę, że w moim przypadku nie mogę użyć bloku catch catch, ponieważ super nie jest zainicjowany w tym momencie. "Spróbuj" potrzebuje funkcji, która rzuca.Prawidłowa obsługa NSJSONSerialization (try catch) w Swift (2.0)?

tu jest mój funkcji:

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 oznaczać, że: let anyObj = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]

ale nie mam pojęcia do zrobienia prawo myśleć według tego dokumentu https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html

+0

Proszę przeczytać pełne treści artykułów, a nie tylko części, które uważasz za ważne. Masz już "funkcję, która wyrzuca" - 'NSJSONSerialization.JSONObjectWithData'. –

+1

@Rob tak mam na myśli Swift 2.0. –

+0

Uznano, ponieważ przykładowy kod nie jest użytecznym odniesieniem do poprzednich metod i przykładów. –

Odpowiedz

63

jsonObject może throw błędy, więc umieścić go w do bloku, użyj try i catch jakieś błędy rzucone. W 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)") 
} 

Lub, Swift 4, można uprościć swój kod przez Dokonywanie struct zgodne Codable:

struct Fieldpropertie: Codable { 
    let label: String 
    let value: Int 
    let uprate: Int 
    let suffix: String 
} 

Następnie

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)") 
} 

Dla Swift 2, zobacz previous revision of this answer.

+0

Och dzięki. To działa dobrze. Nie wiem, dlaczego tego nie zrobiłem;) –

+0

Jak wydrukować error.localizedDescription w Catch? –

+0

@SaumilShah, patrz edycja: catch let error1 jako NSError { print ("błąd json: \ (error1.localizedDescription)") } – Stephan

-3

Nie wiem jeśli to rozwiąże Twój problem, ale czy nie jest to metoda JSONObjectWithData:options:error:? Myślę, że brakuje Ci parametru error.

+1

Nie, w Swift 2.0, gdzie masz nowy mechanizm 'try' -'catch',' JSONObjectWithData' teraz nie używa parametru 'error', ale zamiast niego wyświetla błąd. – Rob

+0

@Rob Ahh, Rozumiem. Pytanie dotyczyło Swift 1.2, którego używam, więc pomyślałem, że to może być problem. – trevorj

5

JSONSerialization.JSONObject rzuca ErrorType, a nie NSError.

więc prawidłowa połów jest

do { 
    let anyObj = try JSONSerialization.JSONObject(with: data, options: []) as! [String:AnyObject] 
    // use anyObj here 
} catch let error { 
    print("json error: \(error)") 
} 

Rodzaj error w catch let error jest ErrorType

+1

Zgodnie z dokumentacją JSONObjectWithData zgłasza NSError, który jest zgodny z ErrorType. – Marcio

+0

Tak, tak mówi tekst. Zakodowana umowa mówi ErrorType. Kiedy robisz to w zamknięciach i nie przestrzegasz zakodowanej umowy, dostaniesz błędy, które naprawdę trudno zrozumieć. Kiedy przechwycisz tylko NSError, kompilator musi założyć, że pozostały niezałatane przypadki, które mogą powodować kłopoty w kontekście. –

+1

localizedDescription nie jest zdefiniowany dla ErrorType. I mam ostrzeżenie na linii 'let error as ErrorType' mówiąc, że test jest zawsze prawdziwy. – Marcio