swift - 使用 URLSession 和 Combine 处理 HTTP 状态代码

标签 swift urlsession combine

我正在尝试处理来自 DataTaskPublisher 的响应读取其响应状态代码。

当状态码大于 299 时,我想返回一个 ServiceError类型为失败。在我见过的每个例子中,我都使用了 .mapError.catch ...在这种特定情况下,来自 .flatMap ,我真的不知道如何处理发布者响应以返回错误而不是TResponse ...

    return URLSession.DataTaskPublisher(request: urlRequest, session: .shared)
        .mapError{error in return ServiceError.request}
        .flatMap{ data, response -> AnyPublisher<TResponse, ServiceError> in

            if let httpResponse = response as? HTTPURLResponse,
                (200...299).contains(httpResponse.statusCode){

                return Just(data)
                    .decode(type: TResponse.self, decoder: JSONDecoder())
                    .mapError{error in return ServiceError.decode}
                    .eraseToAnyPublisher()
            }else{
                //???? HOW TO HANDLE THE ERROR?
            }
        }
        .receive(on: RunLoop.main)
        .eraseToAnyPublisher()

最佳答案

enum ServiceErrors: Error { 
    case internalError(_ statusCode: Int)
    case serverError(_ statusCode: Int)
}
    
return URLSession.shared.dataTaskPublisher(for: urlRequest)
            .tryMap { data, response in
                guard let httpResponse = response as? HTTPURLResponse,
                    200..<300 ~= httpResponse.statusCode else {
                        switch (response as! HTTPURLResponse).statusCode {
                        case (400...499):
                            throw ServiceErrors.internalError((response as! HTTPURLResponse).statusCode)
                        default:
                            throw ServiceErrors.serverError((response as! HTTPURLResponse).statusCode)
                        }
                }
                return data
            }
            .mapError { $0 as! ServiceErrors }
            .decode(type: T.self, decoder: JSONDecoder())
            .receive(on: RunLoop.main)
            .eraseToAnyPublisher()
注意:我靠this链接以制作我的错误处理程序。

关于swift - 使用 URLSession 和 Combine 处理 HTTP 状态代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59461539/

相关文章:

Swift Combine - @Published 属性数组

ios - SwiftUI 结合 Debounce TextField

iOS 13 公测版 2 - Combine.Future "dyld: Symbol not found"

ios - swift 中的 filterUsingPredicate 给出错误 "Void is not convertible to NSArray"

ios - 支付成功后快速获取stripe charge id

ios - NSUrlsession RequestCachePolicy 返回 304 而不是 200

ios - 在 Swift 中调用 API 时出现问题

swift - 为什么我们的 URLSession 对象是变量而不是常量

更改 View Controller 时的 iOS 有线卡住问题

swift - 当 Swift 中的 textView 必须适合整个屏幕时,如何正确调整它的大小?