【问题标题】:Swift combine handling HTTP status code errorsSwift 结合处理 HTTP 状态码错误
【发布时间】: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
}

【问题讨论】:

    标签: swift combine


    【解决方案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()
    

    }

    【讨论】:

      猜你喜欢
      • 2012-09-25
      • 2020-07-05
      • 2020-07-14
      • 2015-08-27
      • 2022-06-21
      • 1970-01-01
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多