用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 ), )
所以,有一些想法:
-
这似乎是一个单词的“材料”,由两个词典arrays组成的字典。 Swift的移植可能如下所示:
let materials = [ "materials": [ [ "material_id": 1, "qty": 10 ], [ "material_id": 2, "qty": 5 ] ] ]
坦率地说,我不太清楚在你的问题中你的例子是什么:你说它是
[[String: String]]
,但不会编译,因为它是[[String: Int]]
; 你说你成功地用Alamofire发送它,但是AFAIK,Alamofire只接受[String: AnyObject]
的参数; 等等。无论如何,鉴于你所说的你想要在服务器上收到什么,我会认为上述将是适当的结构,以实现这一目标。 -
当发送这样的结构时,JSON是最常用的技术。 为此,您
.JSON
为Alamofirerequest
方法指定encoding
参数的.JSON。 -
为了回应另一个使用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
方法适合您的服务器响应的性质(例如response
与responseJSON
与…)。无论如何,上面生成一个请求正文,如下所示:
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];
希望这可以帮助.. :)