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

Swift:如何用枚举/Switch处理不同类型参数?重构重复请求代码

重构重复的网络请求方法

你的问题核心是消除因解析目标类型不同导致的代码重复,下面提供两种贴合你需求的实现方案:

方案一:泛型实现(最简洁高效)

利用Swift泛型抽象出通用请求逻辑,一个方法即可支持所有Decodable类型的解析,完全消除代码重复:

// 通用泛型请求方法
func fetch<T: Decodable>(url: URLConvertible, parameters: CategoryParams, completion: @escaping (T?) -> Void) {
    AF.request(url, method: .get, parameters: parameters, headers: headers)
        .responseDecodable(of: T.self) { res in
            DispatchQueue.main.async {
                switch res.result {
                case .success(let value):
                    completion(value)
                case .failure(let error):
                    print(error)
                    completion(nil)
                }
            }
        }
}

// 调用示例 - 获取商品数据
fetch(url: productURL, parameters: categoryParams) { (products: ProductsResponse?) in
    guard let products = products else { return }
    // 处理ProductsResponse逻辑
}

// 调用示例 - 获取其他类型数据
fetch(url: userURL, parameters: userParams) { (users: UsersResponse?) in
    guard let users = users else { return }
    // 处理UsersResponse逻辑
}

优势

  • 完全复用请求逻辑,新增Decodable类型无需修改方法
  • 类型安全,编译器自动校验解析类型
  • 去掉了原代码中的强制解包,避免崩溃风险

方案二:枚举限定类型(符合你提到的枚举思路)

如果需要严格限定仅允许指定的几种响应类型(避免传入无关类型),可以用枚举封装类型信息:

步骤1:定义枚举关联响应类型

// 枚举列出所有允许的响应类型,关联对应的URL和解析类型
enum APIRequestTarget {
    case products(CategoryParams)
    case users(UserParams)
    case orders(OrderParams)
    
    // 返回目标URL
    var url: URLConvertible {
        switch self {
        case .products: return productURL
        case .users: return userURL
        case .orders: return orderURL
        }
    }
    
    // 返回对应的解析类型
    var decodableType: Decodable.Type {
        switch self {
        case .products: return ProductsResponse.self
        case .users: return UsersResponse.self
        case .orders: return OrdersResponse.self
        }
    }
    
    // 返回请求参数
    var parameters: Encodable {
        switch self {
        case .products(let params): return params
        case .users(let params): return params
        case .orders(let params): return params
        }
    }
}

// 定义统一的结果枚举
enum APIResponseResult {
    case products(ProductsResponse)
    case users(UsersResponse)
    case orders(OrdersResponse)
}

步骤2:重构请求方法

func fetch(target: APIRequestTarget, completion: @escaping (APIResponseResult?) -> Void) {
    AF.request(target.url, method: .get, parameters: target.parameters, headers: headers)
        .responseDecodable(of: target.decodableType) { res in
            DispatchQueue.main.async {
                switch res.result {
                case .success(let value):
                    // 将解析结果转换为统一枚举类型
                    switch target {
                    case .products:
                        completion(.products(value as! ProductsResponse))
                    case .users:
                        completion(.users(value as! UsersResponse))
                    case .orders:
                        completion(.orders(value as! OrdersResponse))
                    }
                case .failure(let error):
                    print(error)
                    completion(nil)
                }
            }
        }
}

// 调用示例
fetch(target: .products(categoryParams)) { result in
    guard let result = result else { return }
    switch result {
    case .products(let products):
        // 处理商品数据
    default: break
    }
}

优势

  • 严格限定允许的请求类型,避免误用
  • 所有URL、参数、解析类型集中管理,便于维护

内容的提问来源于stack exchange,提问作者U.Guldemir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:50:47