Swift中如何实现多Router复用相似asURLRequest()方法
实现方案
Swift 中的枚举不支持继承,你可以通过协议+默认实现的方式实现公共逻辑复用,这是Swift中比类继承更推荐的多类型共享逻辑方案。
步骤1:定义基础路由协议
首先定义所有业务路由都遵循的BaseRouter协议,抽离公共属性和自定义回调:
import Alamofire protocol BaseRouter: URLRequestConvertible { // 各业务路由需要自行实现的属性 var method: HTTPMethod { get } var path: String { get } var parameters: Parameters? { get } // 各业务路由自定义调整请求的回调,替换原asURLRequest中的switch分支逻辑 func adjustRequest(_ request: inout URLRequest) throws }
步骤2:给协议添加默认的asURLRequest实现
把所有路由通用的逻辑放到协议扩展中,所有遵循BaseRouter的类型自动获得这个实现,不用重复编写:
extension BaseRouter { // 可选:如果有部分路由需要自定义baseURL,可以把baseURL也做成协议属性,默认返回通用地址 var baseURL: URL { get throws { try K.TestServer.baseURL.asURL() } } func asURLRequest() throws -> URLRequest { var urlRequest = URLRequest(url: try baseURL.appendingPathComponent(path)) // 通用配置:HTTP Method urlRequest.httpMethod = method.rawValue // 通用配置:公共请求头 urlRequest.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.acceptType.rawValue) urlRequest.setValue(ContentType.json.rawValue, forHTTPHeaderField: HTTPHeaderField.contentType.rawValue) // 调用各业务路由的自定义调整逻辑 try adjustRequest(&urlRequest) // 通用配置:参数编码 if let parameters = parameters { do { urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: []) } catch { throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) } } return urlRequest } }
步骤3:改造原有业务路由
原有路由只需要遵循BaseRouter,删掉重复的asURLRequest方法,新增adjustRequest实现自定义逻辑即可:
enum AuthenticationRouter: BaseRouter { case login(username: String, password: String) // MARK: - 实现BaseRouter要求的属性 var method: HTTPMethod { switch self { case .login: return .get } } var path: String { switch self { case .login: return "users/login" } } var parameters: Parameters? { switch self { case .login: return nil } } // MARK: - 实现自定义请求调整逻辑 func adjustRequest(_ request: inout URLRequest) throws { switch self { case .login(let username, let password): // 原有switch分支的自定义逻辑写在这里即可 // 比如给请求头加鉴权信息、修改参数编码方式等 } } }
后续新增其他业务路由时,只需要遵循BaseRouter协议,实现对应的4个要求即可,不用再重复编写公共的asURLRequest逻辑。
内容的提问来源于stack exchange,提问作者DevinM
相关产品推荐
相关产品推荐

