用alamofire发送字典数组

我必须通过POST请求发送字典数组。 例如:

materials: [[String, String]] = [ [ "material_id": 1, "qty": 10 ], [ "material_id": 2, "qty": 5 ] ] 

Alamofire.request发送下一篇文章数据:

 materials => array( [0] => array("material_id" => 1), [1] => array("qty" => 10), [2] => array("material_id" => 2), [3] => array("qty" => 5), ) 

我想要收到的表示forms:

 materials => array( [0] => array( "material_id" => 1, "qty" => 10 ), [1] => array( "material_id" => 2, "qty" => 5 ), ) 

你说你想以这种格式在服务器上接收数据:

 materials => array( [0] => array( "material_id" => 1, "qty" => 10 ), [1] => array( "material_id" => 2, "qty" => 5 ), ) 

所以,有一些想法:

  1. 这似乎是一个单词的“材料”,由两个词典arrays组成的字典。 Swift的移植可能如下所示:

     let materials = [ "materials": [ [ "material_id": 1, "qty": 10 ], [ "material_id": 2, "qty": 5 ] ] ] 

    坦率地说,我不太清楚在你的问题中你的例子是什么:你说它是[[String: String]] ,但不会编译,因为它是[[String: Int]] ; 你说你成功地用Alamofire发送它,但是AFAIK,Alamofire只接受[String: AnyObject]的参数; 等等。无论如何,鉴于你所说的你想要在服务器上收到什么,我会认为上述将是适当的结构,以实现这一目标。

  2. 当发送这样的结构时,JSON是最常用的技术。 为此,您.JSON为Alamofire request方法指定encoding参数的.JSON。

  3. 为了回应另一个使用JSON的build议,你说你不想这样做。 不幸的是,Alamofire没有一个方法可以在application/x-www-form-urlencoded请求中application/x-www-form-urlencoded并且这样的复杂结构对于你来说,所以你必须编写自己的:

    这可能看起来像:

     func encodeParameters(object: AnyObject, prefix: String! = nil) -> String { if let dictionary = object as? [String: AnyObject] { let results = map(dictionary) { (key, value) -> String in return self.encodeParameters(value, prefix: prefix != nil ? "\(prefix)[\(key)]" : key) } return "&".join(results) } else if let array = object as? [AnyObject] { let results = map(enumerate(array)) { (index, value) -> String in return self.encodeParameters(value, prefix: prefix != nil ? "\(prefix)[\(index)]" : "\(index)") } return "&".join(results) } else { let escapedValue = escape("\(object)") return prefix != nil ? "\(prefix)=\(escapedValue)" : "\(escapedValue)" } } // This is Alamofire's private `escape` function; IMHO, this should // be public method, so either make public, or just re-implement it. func escape(string: String) -> String { let legalURLCharactersToBeEscaped: CFStringRef = ":/?&=;+!@#$()',*" return CFURLCreateStringByAddingPercentEscapes(nil, string, nil, legalURLCharactersToBeEscaped, CFStringBuiltInEncodings.UTF8.rawValue) } 

    然后你可以创build一个请求并自己提交:

     let request = NSMutableURLRequest(URL: url) request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.HTTPMethod = "POST" request.HTTPBody = encodeParameters(materials).dataUsingEncoding(NSUTF8StringEncoding) Alamofire.request(request) .response { request, response, data, error in println(data) } 

    显然,使用任何response方法适合您的服务器响应的性质(例如responseresponseJSON与…)。

    无论如何,上面生成一个请求正文,如下所示:

     materials[0][material_id]=1&materials[0][qty]=10&materials[1][material_id]=2&materials[1][qty]=5 

    这似乎是由您的问题中请求服务器parsing。

值得注意的是,这个最后一点说明了如何devise嵌套字典/数组结构的application/x-www-form-urlencoded请求。 这在我的主要ISP运行的服务器上工作,但我必须承认,我没有看到正式的RFC中logging的这个约定,所以我会小心这样做。 我个人倾向于将其实现为JSON接口。

问题是在追加方法。 我已经在PHP 5年编码,并忘记了在Swift索引不会自动分配像在PHP中。 所以,我的第一个窃听代码是:

 func getParameters() -> [[String: AnyObject]] { var result = [[String: AnyObject]]() for mmap in mmaps { let material: [String: AnyObject] = [ "material_id": mmap.material.id, "quantity": mmap.qty ] result.append(material) } return result } 

答案很难分配你需要的键:

 func getParameters() -> [String: [String: AnyObject]] { var result = [String: [String: AnyObject]]() let mmaps = self.mmaps.allObjects as [Mmap] for i in 0..<mmaps.count { let mmap = mmaps[i] let material: [String: AnyObject] = [ "material_id": mmap.material.id, "quantity": mmap.qty ] result["\(i)"] = material } return result } 

你可以把你的数组作为JSONstring并发布到服务器端,然后在服务器端parsingJSON,并从中得到你想要的数据,如下所示:

 NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject: yourArry options:NSJSONWritingPrettyPrinted error:&error]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 

希望这可以帮助.. :)