如何解决Swift Combine-如何引发错误并停止执行
我有一个HTTP请求发布者,当返回401错误时,我想停止执行并显示登录屏幕。
这是我的代码的一部分:
cancellable = fetcher.hello(helloRequest: HelloRequest(name: self.name))
.print("fetcher.hello")
.catch { _ in
// TODO: how to handle errors with request?
Just(HelloResponse.placeHolder)
}
.flatMap { response -> AnyPublisher<HelloResponse,Never> in
if response.imageUrl == nil || response.imageUrl == "" {
// If there's no image to download just return the response
return Just(response).eraseToAnyPublisher()
}
else {
// Chain together request and download image
return fetcher.downloadImage(url: response.imageUrl!)
.print("fetcher.hello.downloadImage")
.catch { _ in
// If there was an error downloading the image,replace it with a placeholder
Just(UIImage(named: "placeholder_square")!)
}
.map {
// Add image to response
HelloResponse(message: response.message,visitCount: response.visitCount,imageUrl: response.imageUrl,image: $0)
}
.eraseToAnyPublisher()
}
}
.sink(receiveCompletion: { _ in },receiveValue: { self.response = $0.self })
因此,一部分问题是下面的flatMap,如果需要,它将下载图像。输出类型为AnyPublisher
解决方法
使用New Dev关于setFailureType的建议,现在我可以使用它了。当我最初让flatMap返回AnyPublisher
cancellable = fetcher.hello(helloRequest: HelloRequest(name: self.name))
.print("fetcher.hello")
.flatMap { response -> AnyPublisher<HelloResponse,Error> in
if response.imageUrl == nil || response.imageUrl == "" {
// If there's no image to download just return the response
return Just(response)
.setFailureType(to: Error.self) // This allows us to set a failure type (Just is Never) so that it will match AnyPublisher<HelloResponse,Error>
.eraseToAnyPublisher()
}
else {
// Chain together request and download image
return fetcher.downloadImage(url: response.imageUrl!)
.print("fetcher.hello.downloadImage")
.catch { _ in
// If there was an error downloading the image,replace it with a placeholder
Just(UIImage(named: "placeholder_square")!)
.setFailureType(to: Error.self) // This allows us to set a failure type (Just is Never) so that it will match AnyPublisher<HelloResponse,Error>
}
.map {
// Add image to response
HelloResponse(message: response.message,visitCount: response.visitCount,imageUrl: response.imageUrl,image: $0)
}
.eraseToAnyPublisher()
}
}
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print("Request error: \(String(describing: error))")
}
},receiveValue: {
self.response = $0.self
})
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。