通过Alamofire发送json数组

我想知道是否有可能直接发送一个数组(不包装在字典中)的POST请求。 显然parameters参数应该得到一个映射:[String:AnyObject]? 但是我想能够发送下面的例子json:

 [ "06786984572365", "06644857247565", "06649998782227" ] 

你可以用NSJSONSerialization编码JSON,然后自己构buildNSURLRequest 。 例如,在Swift 2中:

 let request = NSMutableURLRequest(URL: url) request.HTTPMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") let values = ["06786984572365", "06644857247565", "06649998782227"] request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(values, options: []) Alamofire.request(request) .responseJSON { response in // do whatever you want here switch response.result { case .Failure(let error): print(error) // if web service reports error, sometimes the body of the response // includes description of the nature of the problem, eg if let data = response.data, let responseString = String(data: data, encoding: NSUTF8StringEncoding) { print(responseString) } case .Success(let responseObject): print(responseObject) } } 

或者,在Swift 3:

 var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") let values = ["06786984572365", "06644857247565", "06649998782227"] request.httpBody = try! JSONSerialization.data(withJSONObject: values) Alamofire.request(request) .responseJSON { response in // do whatever you want here switch response.result { case .failure(let error): print(error) if let data = response.data, let responseString = String(data: data, encoding: .utf8) { print(responseString) } case .success(let responseObject): print(responseObject) } } 

对于swift 3和Alamofire 4,我使用以下ParametersEncodingArray扩展:

 import Foundation import Alamofire private let arrayParametersKey = "arrayParametersKey" /// Extenstion that allows an array be sent as a request parameters extension Array { /// Convert the receiver array to a `Parameters` object. func asParameters() -> Parameters { return [arrayParametersKey: self] } } /// Convert the parameters into a json array, and it is added as the request body. /// The array must be sent as parameters using its `asParameters` method. public struct ArrayEncoding: ParameterEncoding { /// The options for writing the parameters as JSON data. public let options: JSONSerialization.WritingOptions /// Creates a new instance of the encoding using the given options /// /// - parameter options: The options used to encode the json. Default is `[]` /// /// - returns: The new instance public init(options: JSONSerialization.WritingOptions = []) { self.options = options } public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { var urlRequest = try urlRequest.asURLRequest() guard let parameters = parameters, let array = parameters[arrayParametersKey] else { return urlRequest } do { let data = try JSONSerialization.data(withJSONObject: array, options: options) if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") } urlRequest.httpBody = data } catch { throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) } return urlRequest } } 

基本上,它将数组转换为Dictionary以便被接受为Parameters参数,然后从字典中取回数组,然后将其转换为JSON Data并将其添加为请求主体。

一旦你有了它,你可以这样创build请求:

 let values = ["06786984572365", "06644857247565", "06649998782227"] Alamofire.request(url, method: .post, parameters: values.asParameters(), encoding: ArrayEncoding()) 

下面是一个使用路由器对Thingtypes的数组进行编码的示例,使用Ogra进行JSON编码:

 import Foundation import Alamofire import Orga class Thing { ... } enum Router: URLRequestConvertible { static let baseURLString = "http://www.example.com" case UploadThings([Thing]) private var method: Alamofire.Method { switch self { case .UploadThings: return .POST } } private var path: String { switch self { case .UploadThings: return "upload/things" } } var URLRequest: NSMutableURLRequest { let r = NSMutableURLRequest(URL: NSURL(string: Router.baseURLString)!.URLByAppendingPathComponent(path)) r.HTTPMethod = method.rawValue switch self { case .UploadThings(let things): let custom: (URLRequestConvertible, [String:AnyObject]?) -> (NSMutableURLRequest, NSError?) = { (convertible, parameters) in var mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest do { let jsonObject = things.encode().JSONObject() let data = try NSJSONSerialization.dataWithJSONObject(jsonObject, options: NSJSONWritingOptions.PrettyPrinted) mutableRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") mutableRequest.HTTPBody = data return (mutableRequest, nil) } catch let error as NSError { return (mutableRequest, error) } } return ParameterEncoding.Custom(custom).encode(r, parameters: nil).0 default: return r } } } 

Swift 2.0
这个代码在post对象数组下面。这个代码在swift 2.0上testing

 func POST(RequestURL: String,postData:[AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () { print("POST : \(RequestURL)") let request = NSMutableURLRequest(URL: NSURL(string:RequestURL)!) request.HTTPMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") var error: NSError? do { request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(postData!, options:[]) } catch { print("JSON serialization failed: \(error)") } Alamofire.request(request) .responseString{ response in switch response.result { case .Success: print(response.response?.statusCode) print(response.description) if response.response?.statusCode == 200 { successHandler(response.result.value!) }else{ failureHandler("\(response.description)") } case .Failure(let error): failureHandler("\(error)") } } } 

@manueGE的答案是正确的。 根据alamofire github的指示,我有类似的方法:`

 struct JSONDocumentArrayEncoding: ParameterEncoding { private let array: [Any] init(array:[Any]) { self.array = array } func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { var urlRequest = urlRequest.urlRequest let data = try JSONSerialization.data(withJSONObject: array, options: []) if urlRequest!.value(forHTTPHeaderField: "Content-Type") == nil { urlRequest!.setValue("application/json", forHTTPHeaderField: "Content-Type") } urlRequest!.httpBody = data return urlRequest! } } 

`然后通过定制一个请求来调用它,而不是使用默认的参数。 基本上放弃参数,因为它是一个字典。

 let headers = getHeaders() var urlRequest = URLRequest(url: URL(string: (ServerURL + Api))!) urlRequest.httpMethod = "post" urlRequest.allHTTPHeaderFields = headers let jsonArrayencoding = JSONDocumentArrayEncoding(array: documents) let jsonAryEncodedRequest = try? jsonArrayencoding.encode(urlRequest, with: nil) request = customAlamofireManager.request(jsonAryEncodedRequest!) request?.validate{request, response, data in return .success } .responseJSON { /*[unowned self] */(response) -> Void in ... } 

另外,处理数据错误的方法是非常有帮助的。

有两种方法可以发送发送JSON内容作为参数。

  1. 您可以将json作为string发送,您的Web服务将在服务器上parsing它。

      d["completionDetail"] = "[{"YearOfCompletion":"14/03/2017","Completed":true}]" 
  2. 你可以在你的json( YearOfCompletionCompleted )中以顺序数组的forms传递每个值。 您的Web服务将以相同的顺序插入数据。 这个语法看起来像

     d["YearOfCompletion[0]"] = "1998" d["YearOfCompletion[1]"] = "1997" d["YearOfCompletion[2]"] = "1996" d["Completed[0]"] = "true" d["Completed[1]"] = "false" d["Completed[2]"] = "true" 

我一直在用字典使用下面的web服务调用函数,来触发Alamofire请求Swift3.0

 func wsDataRequest(url:String, parameters:Dictionary<String, Any>) { debugPrint("Request:", url, parameters as NSDictionary, separator: "\n") //check for internete collection, if not availabale, don;t move forword if Rechability.connectedToNetwork() == false {SVProgressHUD.showError(withStatus: NSLocalizedString("No Network available! Please check your connection and try again later.", comment: "")); return} // self.request = Alamofire.request(url, method: .post, parameters: parameters) if let request = self.request as? DataRequest { request.responseString { response in var serializedData : Any? = nil var message = NSLocalizedString("Success!", comment: "")//MUST BE CHANGED TO RELEVANT RESPONSES //check content availability and produce serializable response if response.result.isSuccess == true { do { serializedData = try JSONSerialization.jsonObject(with: response.data!, options: JSONSerialization.ReadingOptions.allowFragments) //print(serializedData as! NSDictionary) //debugPrint(message, "Response Dictionary:", serializedData ?? "Data could not be serialized", separator: "\n") }catch{ message = NSLocalizedString("Webservice Response error!", comment: "") var string = String.init(data: response.data!, encoding: .utf8) as String! //TO check when html coms as prefix of JSON, this is hack mush be fixed on web end. do { if let index = string?.characters.index(of: "{") { if let s = string?.substring(from: index) { if let data = s.data(using: String.Encoding.utf8) { serializedData = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) debugPrint(message, "Courtesy SUME:", serializedData ?? "Data could not be serialized", separator: "\n") } } } }catch{debugPrint(message, error.localizedDescription, "Respone String:", string ?? "No respone value.", separator: "\n")} //let index: Int = text.distance(from: text.startIndex, to: range.lowerBound) debugPrint(message, error.localizedDescription, "Respone String:", string ?? "No respone value.", separator: "\n") } //call finised response in all cases self.delegate?.finished(succes: response.result.isSuccess, and: serializedData, message: message) }else{ if self.retryCounter < 1 {//this happens really frequntly so in that case this fn being called again as a retry self.wsDataRequest(url: url, parameters: parameters) }else{ message = response.error?.localizedDescription ?? (NSLocalizedString("No network", comment: "")+"!") SVProgressHUD.showError(withStatus: message);//this will show errror and hide Hud debugPrint(message) //call finised response in all cases self.delay(2.0, closure: {self.delegate?.finished(succes: response.result.isSuccess, and: serializedData, message:message)}) } self.retryCounter += 1 } } } } 

我认为基于Alamofire文档,你可以编写代码如下:

 let values = ["06786984572365", "06644857247565", "06649998782227"] Alamofire.request(.POST, url, parameters: values, encoding:.JSON) .authenticate(user: userid, password: password) .responseJSON { (request, response, responseObject, error) in // do whatever you want here if responseObject == nil { println(error) } else { println(responseObject) } }