【发布时间】:2021-01-08 06:45:12
【问题描述】:
我正在寻求有关 Swift 项目的帮助。我正在构建一个从 API 中提取航空天气数据的应用程序,这种情况很常见:
用户想要来自机场气象站 KDAB 的数据 - 当前报告显示:
- 风 10 节
- 2500 英尺的散云
- 可见性 10 SM
- 小雨
用户想要来自机场气象站 KJAX 的数据 - 当前报告显示:
- 风 16 节
- 阵风 24 节
- 破云 1400 英尺
- 1900 英尺的散云
- 几云 2400 英尺
在这个简单的示例中,您可能会注意到在此报告期间没有为 KJAX 提供阵风数据,也没有为 KDAB 指定“特殊天气”(即雨、霾、雾)。我的应用需要能够处理“nil”或未提供数据,而不仅仅是告诉我有 valueNotFound 或索引超出范围。
这里是 API 文档:https://avwx.docs.apiary.io/#reference/0/metar/get-metar-report
这是我的代码:
import Foundation
struct WeatherManager {
let weatherURL = "https://avwx.rest/api/metar/"
func fetchWeather (stationICAO: String) {
let urlString = "\(weatherURL)\(stationICAO)?token=OVi45FiTDo1LmyodShfOfoizNe5m9wyuO6Mkc95AN-c"
performRequest(urlString: urlString)
}
func performRequest (urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
return
}
if let safeData = data {
self.parseJSON(weatherData: safeData)
}
}
task.resume()
print(urlString)
}
}
func parseJSON(weatherData: Data) {
do {
let decoder = JSONDecoder()
let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
let lowCloudsType = decodedData.clouds[0].type
let midCloudsType = decodedData.clouds[1].type
let highCloudsType = decodedData.clouds[2].type
let lowCloudsAlt = decodedData.clouds[0].altitude
let midCloudsAlt = decodedData.clouds[1].altitude
let highCloudsAlt = decodedData.clouds[2].altitude
let reportingStationVar = decodedData.station
let windGustValue = decodedData.wind_gust.value
let windSpeedValue = decodedData.wind_speed.value
let windDirectionValue = decodedData.wind_direction.value
let visibilityValue = decodedData.visibility.value
let flightRulesValue = decodedData.flight_rules
let weather = WeatherModel(lowestCloudsType: lowCloudsType, lowestCloudsAlt: lowCloudsAlt, middleCloudsType: midCloudsType, middleCloudsAlt: midCloudsAlt, highestCloudsType: highCloudsType, highestCloudsAlt: highCloudsAlt, reportingStation: reportingStationVar, windGust: windGustValue, windSpeed: windSpeedValue, windDirection: windDirectionValue, visibility: visibilityValue, flightRules: flightRulesValue)
print(weather.flightConditions)
} catch {
print(error)
}
}
}
import Foundation
struct WeatherModel {
let lowestCloudsType: String
let lowestCloudsAlt: Int
let middleCloudsType: String
let middleCloudsAlt: Int
let highestCloudsType: String
let highestCloudsAlt: Int
let reportingStation: String
let windGust: Int
let windSpeed: Int
let windDirection: Int
let visibility: Int
let flightRules: String
var flightConditions: String {
switch flightRules {
case "VFR":
return "green"
case "MVFR":
return "blue"
case "IFR":
return "red"
case "LIFR":
return "purple"
default:
return "gray"
}
}
}
最后一个:
import Foundation
struct WeatherData: Decodable {
let clouds: [Clouds]
let flight_rules: String
let remarks: String
let wind_speed: WindSpeed
let wind_gust: WindGust
let wind_direction: WindDirection
let visibility: Visibility
let station: String
}
struct Clouds: Decodable {
let type: String
let altitude: Int
}
struct WindSpeed: Decodable {
let value: Int
}
struct WindGust: Decodable {
let value: Int
}
struct WindDirection: Decodable {
let value: Int
}
struct Visibility: Decodable {
let value: Int
}
根据我玩的游戏,当我进入一个没有我需要能够向用户报告的所有给定信息的电台时,我会收到以下错误气象服务。
2020-09-22 02:47:58.930421-0400 AvWx Pro[66612:4483807] libMobileGestalt MobileGestaltCache.c:38: No persisted cache on this platform.
KDAB
https://avwx.rest/api/metar/KDAB?token=(mySecretToken)
2020-09-22 02:48:02.943231-0400 AvWx Pro[66612:4483809] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
valueNotFound(Swift.KeyedDecodingContainer<AvWx_Pro.WindGust.(unknown context at $1053fb3b8).CodingKeys>,
Swift.DecodingError.Context(codingPath:
[CodingKeys(stringValue: "wind_gust", intValue: nil)],
debugDescription: "Cannot get keyed decoding container
-- found null value instead.", underlyingError: nil))
当我使用的机场没有报告所有三个可能的云层时,另一个错误:
2020-09-22 03:06:02.398628-0400 AvWx Pro[66736:4497432] libMobileGestalt MobileGestaltCache.c:38: No persisted cache on this platform.
KJAX
https://avwx.rest/api/metar/KJAX?token=(mySecretKey)
2020-09-22 03:06:07.955064-0400 AvWx Pro[66736:4497429] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
Fatal error: Index out of range: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1200.2.22.2/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
2020-09-22 03:06:08.908826-0400 AvWx Pro[66736:4497429] Fatal error: Index out of range: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1200.2.22.2/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
(lldb)
我现在已经花了几个小时尝试了我在网上找到的各种解决方案,包括使用选项和强制展开、使用 guard let、使用 if let 以及其他一些解决方案。我现在很迷茫。
我是这个平台的新手(作为海报),非常感谢任何人提供的任何见解!提前感谢您的帮助。
【问题讨论】:
-
如果可能的话,把演示项目发给我?我会帮你解决这个问题。
-
这正是 Swift 选项的用途