【问题标题】:Alamofire + Combine: Get the HTTP response status codeAlamofire + Combine:获取 HTTP 响应状态码
【发布时间】:2021-03-15 21:06:37
【问题描述】:
我目前正在使用包含组合支持的 Alamofire,并以下列方式使用它:
let request = AF.request(endpoint)
...
request
.publishDecodable(type: T.self, decoder: decoder)
.value()
.eraseToAnyPublisher()
这将发布结果和AFError,但从订阅者的.sink,我找不到任何地方可以获取 HTTP 状态代码。在订阅者中获取状态码的最佳方式是什么?
【问题讨论】:
标签:
ios
swift
alamofire
combine
【解决方案1】:
如果您需要响应代码,请不要使用 .value() 擦除 DataPublisher。相反,请使用您从各种 publish 方法中获得的 DataResponse,其中包括所有各种响应信息,包括状态代码。然后您可以将其.map 转换为您需要的任何类型。
【解决方案2】:
适用于 Swift 5.X 和 Xcode 12.4
出于调试目的,您可以在组合发布者 (publishDecodable()) 之前拦截响应并获取 URL 响应的一些元素,使用:
session.request(signedRequest)
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
}
【解决方案3】:
func fetchChats() -> AnyPublisher<DataResponse<ChatListModel, NetworkError>, Never> {
let url = URL(string: "Your_URL")!
AF.request(url,
method: .get)
.validate()
.publishDecodable(type: ChatListModel.self)
.map { response in
response.mapError { error in
let backendError = response.data.flatMap { try? JSONDecoder().decode(BackendError.self, from: $0)}
return NetworkError(initialError: error, backendError: backendError)
}
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
稍后在 viewModel 中
dataManager.fetchChats()
.sink { (dataResponse) in
if dataResponse.error != nil {
if error.initialError.responseCode == 401{
//do what you like with it
}
} else {
self.message = dataResponse.value!
}
.store(in: &cancellableSet)
别忘了自己犯错误:
import Foundation
import Alamofire
struct NetworkError: Error {
let initialError: AFError
let backendError: BackendError?
}
struct BackendError: Codable, Error {
var status: String
var message: String
}