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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:57:03