【问题标题】: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
        }
        

        【讨论】:

          猜你喜欢
          • 2015-05-21
          • 2016-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-09
          • 2019-04-06
          • 1970-01-01
          • 2021-01-28
          相关资源
          最近更新 更多