如何解决URLSession Combine 正确处理 307 重定向
我目前正在使用 URLSession 和 Combine 开发 API。只要 T 符合可解码,我就有一个通用的 fetch 方法类型 T。 API 要么返回 200 并返回带有 Meeting 对象的会议结果,要么返回 307,后者返回没有 Meeting 的 redirectUrl。在映射 FindResult 以获取 findMeeting 中的 MeetingResult 之后,我想检查是否有一个 redirectUrl,如果有然后存储该 redirectUrl 并执行另一个 findMeeting,它应该返回一个 200 和一个 Meeting 对象,然后我可以通过接收器.
A 307,可能会也可能不会发生,很明显,redirectURL 被存储并重用于未来的请求。我想知道当我获得带有重定向 URL 的结果时,如何最好地重新运行提取请求。
final class PostLoader {
func findMeeting(email: String,passcode: String) -> AnyPublisher<Meeting,APIError> {
let request = Endpoint.findMeeting(email: email,passcode: passcode).request
return fetch(request)
.map { (findResult: FindResult) in
findResult.meetingResult
}
.compactMap(\.meeting)
.erasetoAnyPublisher()
}
private func fetch<T: Decodable>(_ request: URLRequest) -> AnyPublisher<T,APIError> {
URLSession.shared.dataTaskPublisher(for: request)
.retry(1)
.tryMap { output in
guard let httpResponse = output.response as? HTTPURLResponse else {
throw APIError.unkNown
}
switch httpResponse.statusCode {
case 200...399:
return output.data
case 400...499:
throw APIError.unauthorized(code: httpResponse.statusCode)
case 500...599:
throw APIError.server(code: httpResponse.statusCode)
default:
throw APIError.unkNown
}
}
.decode(type: T.self,decoder: JSONDecoder())
.mapError { error in
if let error = error as? APIError {
return error
} else if error is DecodingError {
return APIError.decoding(message: "\(error)")
} else {
return APIError.unkNown
}
}
.receive(on: dispatchQueue.main)
.erasetoAnyPublisher()
}
}
A 307 给出的响应为(200 相同的响应,但会议不是 nil 并且 redirectUrl 为 nil):
MeetingResult
- txnid : "abc123"
▿ redirectUrl : Optional<URL>
▿ some : https://redirect-url.com
- _url : https://redirect-url.com
- meeting : nil
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。