使用Enum功能创建网络抽象API

时间:2017-01-01 00:33:19

标签: swift enums alamofire

我正在遵循我使用Enum的设计,以一种暴露优雅API的方式构建网络请求。基本上,它利用相关值逐步构造发送到Alamofire函数调用的信息(以Enum上的计算属性的形式)。

我遇到的问题是Enum中的每个计算属性实际上都需要与案例的关联值不同的值。

因此,如果我声明端点endpoint1(path: String, param1: String)path属性将仅访问第一个值。不幸的是,鉴于Swift Enums的工作方式,似乎我必须为每个打开的案例公开所有相关值。这会导致未使用的变量,因此必须是错误的。因此,我正在考虑采用这种方法。

作为参考,这是我的代码,它使用Enum案例来形成概念性网络端点。可以像Endpoint1(path: users/, format: "JSON")一样调用。

    public enum Endpoints {

        case Endpoint1(path: Sring, param1Value: String)

        public var method: HttpMethod {
            switch self {

            case .Endpoint1,

                return HttpMethod.GET
            }
        }

        public var path: String {
            switch self {
            case .Endpoint1(let path, let paramValue1):
                return baseURL + path 
            }
        }

        public var parameters: [String : AnyObject] {
            var parameters = ["param1" : "..."]
            switch self {
            case .Endpoint1(let path, let param1Value):
                parameters["param1"] = param1Value
                break
            }
            return parameters
        }

}

所以问题是path属性不需要paramValue1关联值,而parameters属性不需要path关联值。

尽管有点复杂,我实际上喜欢这种以这种方式使用Enum功能的技术。不幸的是,这方面的功能似乎是一个死胡同。有没有办法可以重构这个以适当地使用Swift Enums?

1 个答案:

答案 0 :(得分:1)

EndPoint的定义应该是参数列表而不是值。我将您的代码更新为Swift 3:

public enum Endpoints {

    case endpoint1(path: String, parameters: [String])

    public var method: HttpMethod {
        switch self {
        case .endpoint1:
            return .get
        }
    }

    public func path(_ baseURL: String) -> String {
        switch self {
        case .endpoint1(let path, _):
            return baseURL + path
        }
    }

    public func parameters(_ values: [Any?]) -> [String: Any] {
        var parameters = [String: Any]()
        switch self {
        case .endpoint1(_, let params):
            for (index, param) in params.enumerated() {
                if let v = values[index] {
                    parameters[param] = v
                }
            }
        }
        return parameters
    }

}

let endpoint = Endpoints.endpoint1(path: "/users", parameters: ["sort"])
let params = endpoint.parameters(["desc"])
let path = endpoint.path("http://10.1.1.1")

使用函数而不是ivar来获取路径和参数,以便传入baseURL和参数变体。我希望这可以帮助您决定是否仍然想要使用Enum。