You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在类函数中调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:06:02