【问题标题】:Swift Combine: How to specify the Error type of tryMap(_:)?Swift Combine:如何指定 tryMap(_:) 的错误类型?
【发布时间】:2019-11-24 14:46:39
【问题描述】:

在Combine 框架中,我们可以在使用tryMap 时抛出一个通用的Error 协议类型。

但是,我们如何才能更具体地了解Error 类型?

例如,

let publisher = urlSession.dataTaskPublisher(for: request).tryMap { (data, response) -> (Data, HTTPURLResponse) in
      guard let response = response as? HTTPURLResponse else {
        throw URLError(.cannotParseResponse)
      }
      return (data, response)
}

如何指定这个publisherError类型?我想使用URLError 而不是Error

我在Combine 框架中找到了方法setFailureType(to:)。但是,tryMap(_:) 无法使用。

【问题讨论】:

    标签: ios swift xcode macos combine


    【解决方案1】:

    setFailureType(to:) 只是强制失败类型为Never 的发布者的失败类型。 tryMap 总是使用Error 作为错误类型,因为任何Error 都可能被抛出到闭包体中,所以你需要使用mapError 来强制URLError 类型:

    let map_error = publisher.mapError({ error -> URLError in
        switch (error) {
        case let url_error as URLError:
            return url_error
        default:
            return URLError(.unknown)
        }
    })
    

    【讨论】:

    • 很好的解释,但为什么在这里error.self 而不仅仅是error?纯粹的风格,但这可能更直接mapError { $0 as? URLError ?? URLError(.unknown) }
    • 很好,我有一个以前的解决方案,开关检查类型而不是使用case let,这确实需要error.self。做出改变却忘记改变它。是的,如果您只检查一种类型,您的表单会更简洁。
    【解决方案2】:

    您也可以使用flatMap 完成此操作。这将允许您同时指定 OutputError 类型,如下所示:

    struct SomeResponseType {
        let data: Data
        let response: HTTPURLResponse
    }
    
    let publisher = urlSession.dataTaskPublisher(for: request)
        .flatMap { (data, response) -> AnyPublisher<SomeResponseType, URLError > in
          guard let response = response as? HTTPURLResponse else {
            return Fail(error: URLError(.cannotParseResponse))
                .eraseToAnyPublisher()
          }
          return Just(SomeResponseType(data: data, response: response)
              .setFailureType(to: URLError)
              .eraseToAnyPublisher()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 2021-12-06
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      相关资源
      最近更新 更多