在类函数中调用Alamofire报错及requested函数泛型使用问题
问题1:报错原因及解决方法
报错原因
- 核心原因是你在Alamofire的
responseJSON回调闭包里使用了try关键字,但只写了do块没有配套的catch块,导致整个回调闭包被推断为可抛出错误的函数类型,但Alamofire要求该回调必须是不可抛出错误的函数类型,二者类型不匹配触发编译报错。 - 额外代码问题:
completion(.success(response))传参错误,你定义的闭包要求接收Data类型,你传了完整的AFDataResponse对象;同时getDishesData?["data"]可选值未做安全解包,容易出现崩溃。
修复后的requested函数代码
class NetworkLayer{ class func requested(_ request:Router,completion:@escaping(Result<Data,Error>) -> Void){ ProgressHUD.show() AF.request(request).responseJSON{ (response) in ProgressHUD.dismiss() // 请求结束需关闭加载动画,原代码遗漏该逻辑 switch response.result{ case .success(let data): do{ guard let getDishesData = data as? [String:Any], let dataContent = getDishesData["data"] else { // 自定义解析错误,也可根据业务需求自定义错误枚举 let parseError = NSError(domain: "NetworkLayer", code: -1, userInfo: [NSLocalizedDescriptionKey: "响应数据格式错误"]) completion(.failure(parseError)) return } let resp = try JSONSerialization.data(withJSONObject: dataContent, options: .prettyPrinted) completion(.success(resp)) // 传入解析后的Data对象,而非完整response } catch { // 捕获JSONSerialization抛出的错误回传给上层 completion(.failure(error)) } case .failure(let error): completion(.failure(error)) } } } }
问题2:泛型处理返回结果实现
你可以基于Decodable协议实现泛型自动解析,无需手动处理JSON序列化,代码复用性更高、适配性更强。
泛型版实现代码
class NetworkLayer{ // 泛型T要求遵守Decodable协议 class func requested<T: Decodable>(_ request:Router, decodeType: T.Type, completion:@escaping(Result<T,Error>) -> Void){ ProgressHUD.show() // 直接调用Alamofire自带的responseDecodable方法,自动解析对应泛型模型 AF.request(request).responseDecodable(of: T.self) { response in ProgressHUD.dismiss() switch response.result { case .success(let model): completion(.success(model)) case .failure(let error): completion(.failure(error)) } } } }
使用示例
首先定义业务模型,遵守Decodable协议:
// 示例:菜品分类模型,字段和接口返回结构对应即可 struct DishCategory: Decodable { let id: String let name: String let image: String } // 调用示例 NetworkLayer.requested(.getAllDishes, decodeType: [DishCategory].self) { result in switch result { case .success(let categories): // 直接拿到解析完成的菜品分类数组,可直接使用 print(categories) case .failure(let error): print(error.localizedDescription) } }
如果接口返回统一外层结构(比如外层固定有code、message、data字段),还可以定义通用基础响应结构体适配所有接口:
struct BaseResponse<T: Decodable>: Decodable { let code: Int let message: String let data: T } // 调用时传入嵌套泛型即可:BaseResponse<[DishCategory]>.self
内容的提问来源于stack exchange,提问作者Faheem
相关产品推荐
相关产品推荐

