Почему охрана не защищает меня от нуля

Я делаю какой-то разбор JSON с помощью WeatherAPI. Чтобы я не столкнулся с nullPointer (возможно, страница не в сети или что-то в этом роде), я прикрыл свой синтаксический анализ охранником, потому что думал, что он защитит меня от разворачивания необязательного значения.

guard
     let loadedWeather = (json["weather"] as! [[String:AnyObject]])[0]["description"] as? String,
     let loadedTemperatur = (json["main"] as! [String:AnyObject])["temp"] as? Float,
     let loadedWindSpeed = (json["wind"] as! [String:AnyObject])["speed"] as? Float
else {
     print("Weather JSON-Parsing failed")
     return
}

Я неправильно понял функцию охраны? Если да, то как я могу решить эту проблему? На самом деле страница находится в автономном режиме или что-то в этом роде и возвращает страницу ошибки JSON с другими тегами, такими как «погода», «основной» и т. д. не включают в себя. Я надеялся, что в этом случае мой охранник приведет меня внутрь моего else заявления, чтобы я мог справиться с этим делом.

Большое спасибо.


person kuemme01    schedule 03.10.2016    source источник


Ответы (3)


Вы неправильно используете синтаксис для защиты - используйте его следующим образом:

guard let weatherArray = json["weather"] as? [[String:AnyObject]], let mainDict = json["main"] as? [String:AnyObject], let windDict = json["wind"] as? [String:AnyObject] else {
    return
}
guard let dict = weatherArray.first else {
    return
}
 guard let description = dict["description"] as? String, let temp = mainDict["temp"] as? Float, let speed = windDict["speed"] as? Float else {
    return
}

Хотя я бы рекомендовал вам следовать синтаксису if let, описанному Дэмиеном.

person Jacob King    schedule 03.10.2016

Вы должны искать условную развертку: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

if let weather = json["weather"] {
// weather is define here, you can use it
}
person Damien Bannerot    schedule 03.10.2016

Изменять

 as! [[String:AnyObject]]

to

 as? [[String:AnyObject]]

Вы пытаетесь принудительно передать свои данные json (как!), поэтому, даже если вы используете защиту, вы все равно получите сбой в этом месте, если он равен нулю.

Редактировать: Вы сказали, что это все еще форсирует! так что, возможно, попробуйте разделить свой код так. Это также должно сделать его более читаемым и простым для вас, чтобы получить другую информацию из dicts/массивов ответа json. Что-то вроде этого должно работать

/// Get json data
guard
   let loadedWeather = json["weather"] as? [[String:AnyObject]],
   let loadedTemperatur = json["main"] as? [String:AnyObject],
   let loadedWindSpeed = json["wind"] as? [String:AnyObject]
   else {
     print("Weather JSON-Parsing failed")
     return
}

/// Get info from json data
guard 
   let weatherDescription = loadedWeather[0]["description"] as? String,
   let temperature = loadedTemperatur["temp"] as? Float,
   let windSpeed = loadedWindSpeed["speed"] as? Float
   else {
     print("Weather JSON-Parsing failed")
     return
}

 /// do something with weather description, temperature, windSpeed

Может быть, даже лучше попытаться разделить эти операторы защиты для каждой строки отдельно, чтобы в случае сбоя одного из них весь блок не закрывался. В этом случае лучше использовать if let, потому что вы не хотите выходить раньше. Только не начинайте пирамиды гибели с утверждений if let.

/// Weather
if let loadedWeather = json["weather"] as? [[String:AnyObject]],
   let weatherDescription = loadedWeather[0]["description"] as? String {
      // do something with weather description
}

/// Temperature
if let loadedTemperatur = json["main"] as? [String:AnyObject],
   let temperature = loadedTemperatur["temp"] as? Float {
     // do something with temperature
}

/// Wind speed
if let loadedWindSpeed = json["wind"] as? [String:AnyObject],
   let windSpeed = loadedWindSpeed["speed"] as? Float {
     // do something with windspeed
}

Надеюсь это поможет.

person crashoverride777    schedule 03.10.2016
comment
Компилятор Swift заставляет меня делать как! - person kuemme01; 03.10.2016
comment
сборка не удалась с помощью as? - person kuemme01; 03.10.2016
comment
Вы должны попытаться разделить свой код вместо того, чтобы делать это массивное заявление. Позвольте мне обновить мой ответ, дайте мне несколько минут. - person crashoverride777; 04.10.2016
comment
Я обновил свой ответ. Это также должно облегчить чтение вашего кода. - person crashoverride777; 04.10.2016