Moya / Alamofire – 具有相同密钥的URL编码参数

我使用Moya Swift框架构build在Alamofire之上的networking层。

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

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

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

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

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

任何帮助将不胜感激与莫亚或与阿拉莫菲尔本身。

编辑:这里是一些示例代码给基本的想法:

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 /* ... */ }) 

谢谢。

所以我find了一个非常简单明了的解决scheme。 阅读Alamofire的文档,我发现这个:

由于没有发布如何对集合types进行编码的规范,所以Alamofire遵循将[]添加到数组值(foo [] = 1&foo [] = 2)的关键字的约定,并将方括号包围的关键字附加到嵌套字典值(foo [bar] = baz)。

所以,对于这种情况,有CustomEncoding(自定义 参数编码)选项,它可以实际指定你想要如何形成参数的实现。

这是同样的问题,相同的答案。

Moya是一个好主意,但是我觉得我们可以用一些想法来构build一个使用Swift的networking抽象层,而不需要太多的代码。

我们的目标是:

  • 灵活性,能够有效地编辑或添加新的端点
  • 可读性,对我们的API如何工作一目了然
  • 代码安全性,带有types化的参数以允许我们从Xcode期望的所有预编译的优点(完成,validation)。
  • 易于debugging,意味着可以在Web请求之前和之后插入日志

下面是我在一个虚拟项目上的结果 :

 public class API { public static let baseURL: String = "http://colourlovers.com/api" public enum Endpoints { case Colors(String) case Palettes(String) case Patterns(String) public var method: Alamofire.Method { switch self { case .Colors, .Palettes, .Patterns: return Alamofire.Method.GET } } public var path: String { switch self { case .Colors: return baseURL+"/colors" case .Palettes: return baseURL+"/palettes" case .Patterns: return baseURL+"/patterns" } } public var parameters: [String : AnyObject] { var parameters = ["format":"json"] switch self { case .Colors(let keywords): parameters["keywords"] = keywords break case .Palettes(let keywords): parameters["keywords"] = keywords break case .Patterns(let keywords): parameters["keywords"] = keywords break } return parameters } } public static func request( endpoint: API.Endpoints, completionHandler: Response<AnyObject, NSError> -> Void) -> Request { let request = Manager.sharedInstance.request( endpoint.method, endpoint.path, parameters: endpoint.parameters, encoding: .URL, headers: nil ).responseJSON { response in if (response.result.error) != nil { DDLogError("\n<----\n" + response.result.error!.description) completionHandler(response) } else { DDLogInfo("\n<----\n" + response.response!.description) completionHandler(response) } } DDLogInfo("\n---->\n" + request.description) return request } } 

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

HTTP://一些网站/请求PARAM = V1&PARAM = v2和PARAM = V3

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

希望这可以帮助!