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
相关产品推荐
相关产品推荐

