Swith 枚举不能继承方法,这是防止为每个枚举重写相同函数的最佳方法



因此,我正在使用路由器设计模式编写网络代码。我正在为应用程序的不同组件编写一个新路由器(我应该这样做吗?我尝试限制我的对象行)。我的路由器枚举。如果我使用的是类,我可以定义一种方法来填充诸如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
    //
}

您可以通过更改执行函数中的完成块来进一步扩展此问题。

最新更新