2016-07-07 2 views
2

My IOS приложение получает ответ JSON от сервераАнализировать JSON ответ с SwiftyJSON без аварии

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 

Иногда сервер выключен или может быть ошибки в JSON, так что не будет таких значений (сообщение, someInt) и Я хочу справиться с этим без краха приложения - что я могу сделать?

ответ

2

Очень просто, вероятно, вы уже знаете, вы могли бы защитить свой код:

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

Попробуйте этот подход:

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

Я думаю, что проблема где-то раньше ('вар JSON = JSON (данные: данные)') слишком –

+0

'NSString (данные: _ , encoding: _) 'принимает необязательные значения, yo должен проверять' data' раньше (поскольку NSURLSession возвращает необязательные данные). Тогда вы не можете предположить, что responseString не является нулевым. Это может привести к сбоям –

3

С SwiftyJSON, неопциональные добытчиками заканчиваются Value, а факультативные геттеры - нет.

Таким образом, чтобы проверить, если значение здесь вы можете использовать опциональный связывание с if let:

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

Или с 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

Not SwiftyJSON, но хороший пример того, как обращаться с ошибками: http://stackoverflow.com/a/31808605/2227743 – Moritz

+0

Хороший способ защитить код. +1 –

0

Лучше всего было бы, чтобы справиться с использованием попробовать поймать

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

Если вы столкнулись с какой-либо ошибкой, вы получите сообщение в консоль, таким образом предотвращая приложение от сбой

+0

Да, но нет: OP не использует NSJSONSerialization, они используют SwiftyJSON. – Moritz

+0

Спасибо, но мне действительно нужно решение для SwiftyJSON! – moonvader

1

Позвольте мне опубликовать мой ответ тоже =)

первую очередь можно реализовать небольшое расширение для отказа JSON инициализаторе:

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

Вы можете поместить его в глобальный объем с SwiftyJSON импортирован и забыл про форсирование разворачивать ваши данные, прежде чем использовать его в JSON. Те же инициализаторы ошибок могут быть записаны для других типов данных, если вы их используете. Его только для более короткого и читаемого кода в будущем. Со многими путями или в некоторых случаях, например, когда вы ждете от JSON каких-либо отдельных поля, это расширение может сделать ваш код выглядит очень легко и читаемым:

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

Затем вам нужно проверить ноль в пути, что вам нужно (фактически объясняется в предыдущих ответах). Возможно, вы ищете полностью достоверные данные, поэтому следует использовать, если пусть цепь:

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 
      } 
     } 
    } 
Смежные вопросы