【发布时间】:2021-11-22 23:25:02
【问题描述】:
我正在使用 openweathermap api。输入错误的api键或输入错误的经纬度坐标时,出现如下错误。我用我自己的方法向用户展示了这个错误,但我想用更好的方法来做。我不喜欢我自己的代码。我想学得更好。 :)
JSON 错误:
{"cod":"400","message":"wrong latitude"}
T型:
struct Forecast: Codable {
let daily: [Daily]
}
struct Daily: Codable {
let dt: Date
let temp: Temp
let humidity: Int
let weather: [Weather]
let clouds: Int
let pop: Double
}
struct Temp: Codable {
let min: Double
let max: Double
}
struct Weather: Codable {
let id: Int
let main: String
let description: String
let icon: String
}
我的代码:
功能 1:
如果在第一个函数中输入了错误的纬度或经度,我会捕捉到错误,因为它无法解码传入的数据。
由于无法解码 json 发送的错误,我编写了一个不同的函数 (getApiError(url: url) { }),并在该函数中解码来自 json 的错误。
func getForecast<T: Decodable>(api url: String, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys, completion: @escaping(Result<T, ApiError>) -> Void) {
guard let url = URL(string: url) else {
completion(.failure(.error("Hatalı URL")))
return
}
let request = URLRequest(url: url)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = dateDecodingStrategy
decoder.keyDecodingStrategy = keyDecodingStrategy
URLSession.shared.dataTaskPublisher(for: request)
.map({ $0.data })
.decode(type: T.self, decoder: decoder)
.receive(on: DispatchQueue.main)
.sink { taskCompletion in
switch taskCompletion {
case .finished:
return
case .failure(_):
here -> self.getApiError(url: url) { (result: Result<ApiErrorMessage, ApiError>) in
switch result {
case .success(let item):
completion(.failure(.error("Api Key Hatası. \(item.cod)\n\(item.message)")))
case .failure(_):
completion(.failure(.error("Kod çözme hatası.")))
}
}
}
} receiveValue: { decodeData in
completion(.success(decodeData))
}
.store(in: &anyCancellable)
}
功能 2:
在这个函数中,我从 json 解码错误。你认为我这样做对吗?我不确定。
func getApiError(url request: URL, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys, completion: @escaping(Result<ApiErrorMessage, ApiError>) -> Void) {
let request = URLRequest(url: request)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = dateDecodingStrategy
decoder.keyDecodingStrategy = keyDecodingStrategy
URLSession.shared.dataTaskPublisher(for: request)
.map({ $0.data })
.decode(type: ApiErrorMessage.self, decoder: decoder)
.receive(on: DispatchQueue.main)
.sink { taskCompletion in
switch taskCompletion {
case .finished:
return
case .failure(let decodingError):
completion(.failure(.error("Kod çözme hatası. \(decodingError.localizedDescription)")))
}
} receiveValue: { decodeData in
completion(.success(decodeData))
}
.store(in: &anyCancellable)
}
【问题讨论】:
-
那个叫'T.self'的家伙是哪里来的?
-
没人知道T家伙处理什么样的数据。
-
@ElTomato 我编辑了我的问题
-
您要访问哪个 openweathermap api?作为响应的一部分,我只是看不到
Forecastjson 的位置。
标签: json swift error-handling