Swift Combine: 如何指定tryMap(_:)的Error类型?
Swift Combine: How to specify the Error type of tryMap(_:)?
在 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)
}
如何指定这个publisher
的Error
类型?我想使用 URLError
而不是 Error
.
我在Combine
框架中找到了方法setFailureType(to:)
。但是,它不适用于 tryMap(_:)
。
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)
}
})
您也可以使用 flatMap
完成此操作。这将允许您同时指定 Output
和 Error
类型,如下所示:
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()
}
在 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)
}
如何指定这个publisher
的Error
类型?我想使用 URLError
而不是 Error
.
我在Combine
框架中找到了方法setFailureType(to:)
。但是,它不适用于 tryMap(_:)
。
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)
}
})
您也可以使用 flatMap
完成此操作。这将允许您同时指定 Output
和 Error
类型,如下所示:
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()
}