Alamofire + Combine: Get the HTTP response status code

Viewed 862

I am currently using Alamofire which contains Combine support and using it following way:

    let request = AF.request(endpoint)

    ...
    request
            .publishDecodable(type: T.self, decoder: decoder)
            .value()
            .eraseToAnyPublisher()

This will publish result and AFError but from subscriber's .sink, I can't find anywhere to get the HTTP status code. What's the best way to get the status code in subscriber?

3 Answers

If you want the response code, don't erase the DataPublisher using .value(). Instead, use the DataResponse you get from the various publish methods, which includes all of the various response information, including status code. You can then .map it into whatever type you need.

For Swift 5.X and Xcode 12.4 For debugging purposes you can intercept the response right before the Combine publisher (publishDecodable()) and get some of the elements of the URL Response, with :

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
    }

The easy MVVM way:

func fetchChats() -> AnyPublisher<ChatListModel, AFError> {
     let url = URL(string: "Your_URL")!
     AF.request(url, method: .get)
            .validate()
            .publishDecodable(type: ChatListModel.self)
            .value()
            .receive(on: DispatchQueue.main)
            .eraseToAnyPublisher()
}

Later in viewModel

private var subscriptions: Set<AnyCancellable> = []
// some func
      dataManager.fetchChats()
           .sink {[weak self] completion in
            guard let self = self else { return }
            switch completion {
            case .failure(let error):
                switch error.responseCode {
                case 401:
                    //do something with code
                default:
                   print(error.responseCode)
                }
                print("All errors:\(error)")
            case .finished:
                break
            }
        } receiveValue: {[weak self] message in
            guard let self = self else { return }
            self.message = message
        }
        .store(in: &subscriptions)
Related