简体   繁体   English

Swift Combine:如何指定tryMap(_:)的错误类型?

[英]Swift Combine: How to specify the Error type of tryMap(_:)?

In the Combine framework, we can throw a generic Error protocol type while using tryMap .在 Combine 框架中,我们可以在使用tryMap抛出一个通用的Error协议类型。

However, how can we be more specific about the Error type?但是,我们如何才能更具体地了解Error类型?

For example,例如,

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)
}

How to specify the Error type of this publisher ?如何指定此publisherError类型? I'd like to use URLError instead of Error .我想使用URLError而不是Error

I found the method setFailureType(to:) in the Combine framework.我在Combine框架中找到了setFailureType(to:)方法。 However, it is not available to tryMap(_:) .但是,它不适用于tryMap(_:)

setFailureType(to:) is only to force the failure type of a publisher with failure type Never . setFailureType(to:)只是强制失败类型为Never的发布者的失败类型。 tryMap always uses Error as the error type because any Error could be thrown in the closure body, so you need to use mapError to force the URLError type: 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)
    }
})

You can also accomplish this with flatMap .您也可以使用flatMap完成此操作。 This will allow you to specify both the Output and Error type at once, like so:这将允许您同时指定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()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM