2016-07-07 13 views
2

Meine iOS-App wird immer JSON Antwort vom ServerParse JSON-Antwort mit SwiftyJSON ohne Absturz

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 

Manchmal Server ausgefallen ist oder es können Fehler in JSON sein, so wird es keine solche Werte sein (Meldung, someInt) und Ich will damit ohne App-Absturz umgehen - was kann ich tun?

Antwort

2

Sehr einfach, wahrscheinlich schon wissen Sie es, Sie Ihren Code mit schützen könnte:

if let someInt = json["someInt"].int { 
    // do whatever you want with someInt 
} 
if let message = json["message"].string { 
    // do whatever you want with message 
} 

Versuchen Sie diesen Ansatz:

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() 
+0

ich glaube, das Problem ist, irgendwo vor ('var json = JSON (Daten: Daten)') zu –

+0

'NSString (Daten: _ , encoding: _) 'akzeptiert nicht-optionale Werte, yo sollte die' data' vorher validieren (da NSURLSession optional Daten zurückgibt). Dann können Sie nicht davon ausgehen, dass responseString nicht null ist. Dies könnte zu Abstürzen führen –

3

Mit SwiftyJSON, nicht optionale Getter enden mit Value, und optionale Getters nicht.

So zu testen, ob der Wert hier ist, dass Sie optional Bindung mit if let verwenden können:

if let someInt = json["someInt"].int, 
    message = json["message"].string { 
     // someInt and message are available here 
} else { 
    // someInt and message are not available 
} 

Oder mit 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 
+0

Nicht SwiftyJSON aber ein gutes Beispiel für die Behandlung von Fehlern: http://StackOverflow.com/a/31808605/2227743 – Moritz

+0

Schöne Weise, Code zu schützen. +1 –

0

Die besten

try catch verwenden würde zu handhaben
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() 

Wenn Sie einen Fehler finden, erhalten Sie eine Nachricht in die Konsole, so dass die Anwendung verhindert

Absturz
+0

Ja, aber nein: OP verwendet NSJSONSerialization nicht, sie verwenden SwiftyJSON. – Moritz

+0

Vielen Dank, aber ich brauche wirklich eine Lösung für SwiftyJSON! – moonvader

1

Lassen Sie mich meine Antwort schreiben zu =)

allererst Sie kleine Erweiterung für das Scheitern JSON initializer implementieren können:

extension JSON { 
    init?(_ data: NSData?) { 
     if let data = data { 
      self.init(data: data) 
     } else { 
      return nil 
     } 
    } 
} 

Sie können es ausdrückte in globaler Geltungsbereich mit SwiftyJSON importiert und vergessen Sie zu zwingen, Ihre Daten auszupacken, bevor Sie es in JSON verwenden. Dieselben Fehlerinitialisierer können für andere Datentypen geschrieben werden, wenn Sie sie verwenden. Es ist nur für einen etwas kürzeren und lesbaren Code in der Zukunft. Mit vielen Strecken oder in einigen Fällen, zum Beispiel wenn Sie von json warten einige einzelne Felder, kann diese Erweiterung Code machen extrem einfach und lesbar aussieht:

guard let singleMessage = JSON(data: data)?["message"].string else {return} 

Dann müssen Sie für null überprüfen in Art und Weise, die Sie benötigen (Tatsächlich in früheren Antworten erklärt). Wahrscheinlich Suchen Sie voll gültige Daten, so verwenden, wenn-let-Kette:

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