Swift 结合处理 HTTP 状态码错误
Posted
技术标签:
【中文标题】Swift 结合处理 HTTP 状态码错误【英文标题】:Swift combine handling HTTP status code errors 【发布时间】:2020-03-31 14:36:13 【问题描述】:我正在阅读这篇文章:https://www.raywenderlich.com/4161005-mvvm-with-combine-tutorial-for-ios Ray Wenderlich 关于如何使用 combine。他们有一个从 API 获取数据但不处理 HTTP 状态代码的示例。我想添加它,但到目前为止我无法添加。
根据这个答案,您可以添加tryMap
,但随后 XCode 开始显示错误,例如:Generic parameter 'T' could not be inferred
。
代码下方:
extension WeatherFetcher: WeatherFetchable
func weeklyWeatherForecast(
forCity city: String
) -> AnyPublisher<WeeklyForecastResponse, WeatherError>
return forecast(with: makeWeeklyForecastComponents(withCity: city))
private func forecast<T>(
with components: URLComponents
) -> AnyPublisher<T, WeatherError> where T: Decodable
guard let url = components.url else
let error = WeatherError.network(description: "Couldn't create URL")
return Fail(error: error).eraseToAnyPublisher()
return session.dataTaskPublisher(for: URLRequest(url: url))
.mapError error in
.network(description: error.localizedDescription)
.flatMap(maxPublishers: .max(1)) pair in
decode(pair.data)
.eraseToAnyPublisher()
我正在尝试添加
.tryMap data, response in
guard let httpResponse = response as? HTTPURLResponse,
200..<300 ~= httpResponse.statusCode else
switch (response as! HTTPURLResponse).statusCode
case (400...499):
throw ServiceErrors.internalError((response as! HTTPURLResponse).statusCode)
default:
throw ServiceErrors.serverError((response as! HTTPURLResponse).statusCode)
return data
【问题讨论】:
【参考方案1】:我认为您可以简单地将 flatMap
块替换为 tryMap
。而不是从tryMap
返回数据,它应该被解码为T。所以return data
行应该是return try JSONDecoder().decode(T.self, from: data)
private func forecast<T>(with components: URLComponents) -> AnyPublisher<T, WeatherError> where T: Decodable
guard let url = components.url else
let error = WeatherError.network(description: "Couldn't create URL")
return Fail(error: error).eraseToAnyPublisher()
return session.dataTaskPublisher(for: URLRequest(url: url))
.tryMap data, response in
guard let httpResponse = response as? HTTPURLResponse,
200..<300 ~= httpResponse.statusCode else
switch (response as! HTTPURLResponse).statusCode
case (400...499):
throw ServiceErrors.internalError((response as! HTTPURLResponse).statusCode)
default:
throw ServiceErrors.serverError((response as! HTTPURLResponse).statusCode)
return try JSONDecoder().decode(T.self, from: data)
.mapError error in
WeatherError() // some kind of error
.eraseToAnyPublisher()
【讨论】:
以上是关于Swift 结合处理 HTTP 状态码错误的主要内容,如果未能解决你的问题,请参考以下文章