Swift Swith enum can';t继承方法,这是防止为每个枚举重写相同函数的最佳方法

Swift Swith enum can';t继承方法,这是防止为每个枚举重写相同函数的最佳方法,swift,Swift,因此,我正在使用路由器设计模式编写我的网络代码。我正在为我的应用程序的不同组件编写一个新的路由器(我应该这样做吗?我试图限制我的对象的代码行)。这是我的路由器号码。如果我使用的是一个类,我可以定义一次方法来填充HTTPMethod之类的变量,并在必要时重写它们。有没有一种方法可以通过枚举实现这一点?它是否值得实现,或者我是否应该重复相同的代码。除了httpMethod,还有一些其他地方,比如URL构造,我认为这可能会有所帮助。 我想我可以用协议做点什么,但不确定我是否在浪费时间 enum PRR

因此,我正在使用路由器设计模式编写我的网络代码。我正在为我的应用程序的不同组件编写一个新的路由器(我应该这样做吗?我试图限制我的对象的代码行)。这是我的路由器号码。如果我使用的是一个类,我可以定义一次方法来填充HTTPMethod之类的变量,并在必要时重写它们。有没有一种方法可以通过枚举实现这一点?它是否值得实现,或者我是否应该重复相同的代码。除了httpMethod,还有一些其他地方,比如URL构造,我认为这可能会有所帮助。 我想我可以用协议做点什么,但不确定我是否在浪费时间

enum PRRouter: URLRequestConvertible {
    static let baseURLString = "http://localhost:8000/"

    case get(Int)
    case create([String : Any])
    case delete(Int)

    func asURLRequest() throws -> URLRequest {
        var method: HTTPMethod{
            switch self {
                case .get:
                    return .get
                case .create:
                    return .post
                case.delete:
                    return .delete
            }
        }

    let params : ([String : Any]?) = {
        switch self {
            case .get, .delete:
                return nil
            case .create(let newTodo):
                return newTodo
        }

    }()

    let url : URL = {
        let relativePath: String?
        switch self{
            case .get(let number):
                relativePath =  "test/\(number)"
            case .create:
                relativePath = "test/"
            case .delete:
                relativePath = "test/"

        }
        var url = URL(string: PRRouter.baseURLString)!
        if let relativePath = relativePath {
            url = url.appendingPathComponent(relativePath)
        }
        return url
     }()

     var urlRequest = URLRequest(url:url)
     urlRequest.httpMethod = method.rawValue
     let encoding = JSONEncoding.default
     return try encoding.encode(urlRequest, with: params)
    }

使枚举符合具有默认实现的协议

protocol P {
    func f()
}

extension P {
    func f() { print("default implementation") }
}

enum E: P {
    case Foo
}

let e = E.Foo

e.f()

我在自己的项目中也做了类似的事情。下面是一个基于您的代码的示例,以帮助您入门:

protocol APIProtocol {
    var path: String { get }
    var method: HTTPMethods { get }
    var bodyParameters: [String: Any?]? { get }
}

enum HTTPMethods: String {
    case get = "GET"
    case post = "POST"
}

enum PRRouter: APIProtocol {
    case get(Int)
    case create([String : Any])
    case delete(Int)

    var path: String {
        switch self {
        case let .get(number):
            return "test/\(number)"
        default:
            return "test"
        }
    }

    var method: HTTPMethods {
        return .get
    }

    var bodyParameters: [String : Any?]? {
        return nil
    }
}

extension APIProtocol {
    func execute(completion: @escaping ((Data?) -> Void)) -> URLSessionDataTask? {
        guard let url = URL(string: "http://localhost:8000/\(path)") else { return nil }
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = method.rawValue
        if let bodyParameters = bodyParameters {
            urlRequest.httpBody = try? JSONSerialization.data(withJSONObject: bodyParameters, options: [.prettyPrinted])
        }
        let task = URLSession.shared.dataTask(with: urlRequest) { (data, urlResponse, error) in
            completion(data)
        }
        task.resume()
        return task
    }
}
最后,您可以这样使用它:

let dataTask = PRRouter.get(2).execute { (data) in
    //
}

您可以通过更改execute函数中的completion块以返回反序列化对象来进一步扩展此功能。

谢谢,这正是我想要的!