如何使用Moya修改重定向请求的请求体?(iOS, Swift)
用Moya实现修改重定向请求体的功能(基于你的Alamofire方案迁移)
Moya底层依赖Alamofire,因此可以直接复用你已实现的Redirector逻辑,通过自定义Moya的requestClosure拦截请求,配置重定向时的请求体修改规则,同时保持Moya的原有调用风格。以下是具体实现:
1. 修改TopUpService类,新增重定向处理方法
class TopUpService: TopUpServiceProtocol { private let provider: MoyaProvider<TopUpAPI> init() { self.provider = MoyaProvider<TopUpAPI>() } // 保留原有的普通请求方法 func topUp(request: TopUpWithAmountRequest, completion: @escaping (Result<Response, MoyaError>) -> Void) { provider.request(.topUpWithAmount(request: request), completion: completion) } // 新增支持重定向请求体修改的方法 func topUpWithRedirector(request: TopUpWithAmountRequest, completion: @escaping (Result<Response, MoyaError>) -> Void) { // 自定义请求处理闭包,对接Alamofire的Redirector let customRequestClosure: MoyaProvider<TopUpAPI>.RequestClosure = { endpoint, done in do { // 生成Moya定义的原始URLRequest let urlRequest = try endpoint.urlRequest() // 转用Alamofire发起请求,方便配置重定向规则 let afRequest = AF.request(urlRequest) // 复用你已实现的重定向逻辑,注入原请求的amount参数 let redirector = Redirector(behavior: .modify { _, redirectRequest, _ in var modifiedRequest = redirectRequest // 构造重定向所需的请求体参数 let parameters: [String: Any] = [ "Amount": request.amount ] // 序列化参数并设置到重定向请求体 modifiedRequest.httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) // 确保Content-Type头部正确,避免服务器解析失败 modifiedRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") return modifiedRequest }) // 应用重定向规则并处理响应 afRequest.redirect(using: redirector).response { afResponse in switch afResponse.result { case .success(let data): guard let urlResponse = afResponse.response else { done(.failure(.underlying(AFError.responseValidationFailed(reason: .missingResponse), nil))) return } // 将Alamofire响应转换为Moya Response格式,兼容上层调用 let moyaResponse = Response( statusCode: urlResponse.statusCode, data: data, request: afResponse.request, response: urlResponse ) done(.success(moyaResponse)) case .failure(let afError): done(.failure(.underlying(afError, nil))) } } } catch { done(.failure(.underlying(error, nil))) } } // 使用自定义请求闭包创建临时Provider,避免影响全局请求逻辑 let customProvider = MoyaProvider<TopUpAPI>(requestClosure: customRequestClosure) customProvider.request(.topUpWithAmount(request: request), completion: completion) } }
2. 调用代码保持不变
你的原有调用逻辑无需修改,直接调用新增的topUpWithRedirector方法即可:
let request = TopUpWithAmountRequest(amount: Int(amount), redirect: true) view?.showProgressHUD() topUpService.topUpWithRedirector(request: request) { [weak self] result in switch result { case .success(let response): // 处理成功响应逻辑 case .failure(let error): print("--- Error in TopUpAmount: \(error)") self?.view?.showErrorNotification() // 处理失败逻辑 } self?.view?.hideProgressHUD() }
关键注意事项
- 重定向请求需手动设置
Content-Type: application/json头部,确保服务器能正确解析请求体 - 若需要更严谨的错误处理,可将
try? JSONSerialization替换为do-catch捕获序列化异常 - 自定义
requestClosure采用临时Provider的方式,避免影响其他无需重定向处理的请求
内容的提问来源于stack exchange,提问作者mad_lexone
相关产品推荐
相关产品推荐

