Enviar parameters POST con MultipartFormData utilizando Alamofire, en iOS Swift

Estoy usando Alamofire, por primera vez. Estoy usando la última versión de Alamofire 1.3.1. Quiero enviar una image, un video y algunos parameters POST en una llamada API. Estoy usando datos de formularios multiparte. El module mutipart está funcionando. Me enfrento a un problema para enviar params adicionales de POST. A continuación se muestra mi código. "params" es el dictionary que contiene parameters extra? ¿Cómo puedo anexar estos parameters POST en la request? Por favor ayuda

  var fullUrl :String = Constants.BASE_URL + "/api/CompleteChallenge" var params = [ "authKey": Constants.AuthKey, "idUserChallenge": "16", "comment": "", "photo": imagePath, "video": videoPath, "latitude": "1", "longitude": "1", "location": "india" ] let imagePathUrl = NSURL(fileURLWithPath: imagePath!) let videoPathUrl = NSURL(fileURLWithPath: videoPath!) Alamofire.upload( .POST, URLString: fullUrl, // http://httpbin.org/post multipartFormData: { multipartFormData in multipartFormData.appendBodyPart(fileURL: imagePathUrl!, name: "photo") multipartFormData.appendBodyPart(fileURL: videoPathUrl!, name: "video") }, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.responseJSON { request, response, JSON, error in } } case .Failure(let encodingError): } } ) 

Encontré la solución 🙂 finalmente.

Podemos agregar datos en la request como datos multiparte.

A continuación se muestra mi código.

  Alamofire.upload( .POST, URLString: fullUrl, // http://httpbin.org/post multipartFormData: { multipartFormData in multipartFormData.appendBodyPart(fileURL: imagePathUrl!, name: "photo") multipartFormData.appendBodyPart(fileURL: videoPathUrl!, name: "video") multipartFormData.appendBodyPart(data: Constants.AuthKey.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"authKey") multipartFormData.appendBodyPart(data: "\(16)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"idUserChallenge") multipartFormData.appendBodyPart(data: "comment".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"comment") multipartFormData.appendBodyPart(data:"\(0.00)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"latitude") multipartFormData.appendBodyPart(data:"\(0.00)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"longitude") multipartFormData.appendBodyPart(data:"India".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"location") }, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.responseJSON { request, response, JSON, error in } case .Failure(let encodingError): } } ) 

¡En Alamofire 4 es importante agregar los datos del cuerpo antes de agregar los datos del file!

 let parameters = [String: String]() [...] self.manager.upload( multipartFormData: { multipartFormData in for (key, value) in parameters { multipartFormData.append(value.data(using: .utf8)!, withName: key) } multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg") }, to: path, [...] 

Así es como resuelvo mi problema

 let parameters = [ "station_id" : "1000", "title": "Murat Akdeniz", "body": "xxxxxx"] let imgData = UIImageJPEGRepresentation(UIImage(named: "1.png")!,1) Alamofire.upload( multipartFormData: { MultipartFormData in // multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg") for (key, value) in parameters { MultipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key) } MultipartFormData.append(UIImageJPEGRepresentation(UIImage(named: "1.png")!, 1)!, withName: "photos[1]", fileName: "swift_file.jpeg", mimeType: "image/jpeg") MultipartFormData.append(UIImageJPEGRepresentation(UIImage(named: "1.png")!, 1)!, withName: "photos[2]", fileName: "swift_file.jpeg", mimeType: "image/jpeg") }, to: "http://platform.twitone.com/station/add-feedback") { (result) in switch result { case .success(let upload, _, _): upload.responseJSON { response in print(response.result.value) } case .failure(let encodingError): break print(encodingError) } } 

Swift 3 / Alamofire 4.0 (Apéndice a la respuesta aceptada )

Para agregar a multipartFormData en Swift 3 / Alamofire 4.0, use el siguiente método de MultipartFormData :

 public func append(_ data: Data, withName name: String) { /* ... */ } 

Y, para convertir String a Data , los data(using:) método de String . P.ej,

 multipartFormData.append("comment".data(using: .utf8)!, withName: "comment") 

Como en Swift 3.x para cargar imágenes con parameters, podemos usar el método de carga de alamofire a continuación:

 static func uploadImageData(inputUrl:String,parameters:[String:Any],imageName: String,imageFile : UIImage,completion:@escaping(_:Any)->Void) { let imageData = UIImageJPEGRepresentation(imageFile , 0.5) Alamofire.upload(multipartFormData: { (multipartFormData) in multipartFormData.append(imageData!, withName: imageName, fileName: "swift_file\(arc4random_uniform(100)).jpeg", mimeType: "image/jpeg") for key in parameters.keys{ let name = String(key) if let val = parameters[name!] as? String{ multipartFormData.append(val.data(using: .utf8)!, withName: name!) } } }, to:inputUrl) { (result) in switch result { case .success(let upload, _, _): upload.uploadProgress(closure: { (Progress) in }) upload.responseJSON { response in if let JSON = response.result.value { completion(JSON) }else{ completion(nilValue) } } case .failure(let encodingError): completion(nilValue) } } } 

Nota: -Adicionalmente, si nuestro parámetro es una matriz de pares de keys, entonces podemos usar

  var arrayOfKeyPairs = [[String:Any]]() let JSON = try? JSONSerialization.data(withJSONObject: arrayOfKeyPairs, options: [.prettyPrinted]) let jsonPrasatation = String(data: JSON!, encoding: .utf8) 

para alamofire 4 usa esto …

  Alamofire.upload(multipartFormData: { (multipartFormData) in multipartFormData.append(fileUrl, withName: "video") //fileUrl is your file path in iOS device and withName is parameter name }, to:"http://to_your_url_path") { (result) in switch result { case .success(let upload, _ , _): upload.uploadProgress(closure: { (progress) in print("uploding") }) upload.responseJSON { response in print("done") } case .failure(let encodingError): print("failed") print(encodingError) } }