Alamofire 5实操:如何从AFError中获取服务端自定义API错误
Alamofire 5 自定义服务端错误模型解析方案
你当前调整后的方案已经可以实现需求,我们可以进一步优化为更符合Swift类型安全特性的写法,避免双可选参数的冗余判断:
步骤1:定义错误相关模型
首先定义和服务端返回结构匹配的错误模型,以及统一的API错误枚举:
// 服务端错误详情结构,根据实际返回字段调整 struct ErrorDetail: Decodable { // 对应details内的字段 } // 服务端返回的错误主体 struct ServerError: Decodable, Error { let summary: String let details: [ErrorDetail] } // 服务端错误最外层包装 struct ErrorWrapper: Decodable { let errorObject: ServerError } // 统一的API错误枚举,覆盖所有可能的错误场景 enum APIError: Error { /// 网络层面错误(无网络、超时等) case network(AFError) /// 服务端返回的业务错误 case server(ServerError) /// JSON解析错误 case parse(Error) /// 响应无数据 case noData }
步骤2:改造APIClient请求方法
将原来的双可选回调改为Result类型回调,统一处理成功、失败的解析逻辑:
class APIClient { static let sessionManager: Session = { let configuration = URLSessionConfiguration.af.default configuration.timeoutIntervalForRequest = 30 configuration.waitsForConnectivity = true return Session(configuration: configuration, eventMonitors: [APILogger()]) }() @discardableResult private static func performRequest<T:Decodable>(route:APIRouter, decoder: JSONDecoder = JSONDecoder(), completion:@escaping (Result<T, APIError>)->Void) -> DataRequest { return sessionManager.request(route) .validate(statusCode: 200..<300) .validate(contentType: ["application/json"]) .responseData { response in switch response.result { case .success(let data): do { let object = try decoder.decode(T.self, from: data) completion(.success(object)) } catch { completion(.failure(.parse(error))) } case .failure(let afError): guard let data = response.data else { completion(.failure(.network(afError))) return } do { // 解析服务端返回的错误模型 let errorWrapper = try decoder.decode(ErrorWrapper.self, from: data) completion(.failure(.server(errorWrapper.errorObject))) } catch { // 错误解析失败时返回原始网络错误 completion(.failure(.network(afError))) } } } } // 登录接口示例 static func login(username: String, password: String, completion:@escaping (Result<User, APIError>)->Void) { performRequest(route: APIRouter.login(username: username, password: password), completion: completion) } }
步骤3:接口调用示例
调用侧直接通过Result的枚举分支处理不同场景,错误类型明确无需额外判断:
APIClient.login(username: "test", password: "test") { result in switch result { case .success(let user): debugPrint("__________SUCCESS__________") debugPrint(user) case .failure(let error): debugPrint("__________FAILURE__________") switch error { case .server(let serverError): // 直接使用解析好的服务端错误模型处理业务逻辑 debugPrint("业务错误提示:\(serverError.summary)") case .network(let afError): debugPrint("网络异常:\(afError.localizedDescription)") case .parse(let parseError): debugPrint("数据解析失败:\(parseError.localizedDescription)") case .noData: debugPrint("服务器未返回有效数据") } } }
核心说明
之前你获取underlyingError为空的原因是Alamofire的验证失败后,错误响应的原始数据不会存在于underlyingError中,直接从response.data属性即可获取完整的错误响应数据进行解析。
内容的提问来源于stack exchange,提问作者DevinM
相关产品推荐
相关产品推荐

