Moya / Alamofire - 具有相同键的URL编码参数

时间:2015-08-10 02:02:21

标签: ios swift alamofire

我使用Moya Swift框架构建在Alamofire之上的网络层。

目前,我尝试使用具有相同密钥的URL编码参数发送请求。

即。 http://some-site/request?param=v1&param=v2&param=v3

我已经尝试将这些参数分组到Set或NSSet或Array中,但没有任何方法可以帮助您达到预期的效果。

["param": ["v1", "v2", "v3"]];

["param": Set(arrayLiteral: "v1", "v2", "v3")]

任何帮助都会受到Moya或Alamofire本人的赞赏。

编辑:以下是一些提供基本想法的示例代码:

Api路由器设置

import Moya

// MARK:- Enum Declaration

enum ApiRouter {
    case XAuth(login: String, password: String)
    case SomeRequest(params: [String])
}

// MARK:- Moya Path

extension ApiRouter: MoyaPath {
    var path: String {
        switch self {
        case .XAuth:
            return "/authorization"
        case .SomeRequest:
            return "/some-request"
        }
    }
}

// MARK:- Moya Target

extension ApiRouter: MoyaTarget {
    private var base: String {
        return "http://some-site"
    }
    var baseURL: NSURL {
        return NSURL(string: base)!
    }

    var parameters: [String: AnyObject] {
        switch self {
        case .XAuth(let login, let password):
            return [
                "email": login,
                "password": password
            ]
        case .SomeRequest(let params):
            return [
                "params": params
            ]
    }

    var method: Moya.Method {
        switch self {
        case .XAuth:
            return .POST
        case .SomeRequest,
            return .GET
        }
    }

    var sampleData: NSData {
        switch self {
        case .XAuth:
            return "{}".dataUsingEncoding(NSUTF8StringEncoding)
        case .ServiceRequests:
            return "{}".dataUsingEncoding(NSUTF8StringEncoding)
        }
    }
}

Api提供商设置

    let endpointsClosure = { (target: ApiRouter) -> Endpoint<ApiRouter> in
    let endpoint = Endpoint<ApiRouter>(
        URL: target.baseURL.URLByAppendingPathComponent(target.path).absoluteString!,
        sampleResponse: EndpointSampleResponse.Success(200, { target.sampleData }),
        method: target.method,
        parameters: target.parameters,
        parameterEncoding: parameterEncoding(target)
    )
    switch target {
    case .XAuth:
        return endpoint
    default:
        let token = "some-token"
        return endpoint.endpointByAddingHTTPHeaderFields(["Authorization": "Bearer: \(token)"])
    }
}

func parameterEncoding(target: ApiRouter) -> Moya.ParameterEncoding {
    switch target {
    case .XAuth:
        return .JSON
    case .SomeRequest:
        return .URL
    }
}

let apiProvider = MoyaProvider(endpointsClosure: endpointsClosure)

apiProvider.request(ApiRouter.SomeRequest(params: ["v1", "v2", "v3"], completion: { (data, statusCode, response, error) in
    /* ... */
})

感谢。

3 个答案:

答案 0 :(得分:7)

所以我找到了一个实际上非常简单明了的解决方案。 阅读Alamofire的文档我发现了这个:

  

由于没有关于如何编码集合类型的已发布规范,Alamofire遵循将[]附加到数组值的键(foo [] = 1&amp; foo [] = 2)的约定,并附加由嵌套字典值的方括号(foo [bar] = baz)。

因此,对于这种情况,有自定义 ParameterEncoding 选项,该选项需要关闭,您可以在其中实际指定您希望如何形成参数的实现。

Here使用相同的答案也是同样的问题。

答案 1 :(得分:4)

Moya是一个好主意,但实际上我觉得通过一些思考,我们可以使用Swift构建一个网络抽象层而不需要太多代码。

我们的目标是:

  • 灵活性,能够有效地编辑或添加新端点
  • 可读性,能够很好地了解我们的API如何工作
  • 代码安全,带有类型化参数,以允许我们期望从Xcode获得的所有预编译良好性(完成,验证)。
  • 轻松调试,意味着能够在Web请求之前和之后插入日志

以下是我在dummy project上的最终结果:

.profile

答案 2 :(得分:0)

您可以使用格式简单地创建String并将其作为请求URL传递:

http://some-site/request?param=v1&param=v2&param=v3

String url: String = String(format: "http://some-site/request?param=%@&param=%@&param=%@", v1, v2, v3)

希望这有帮助!