Subiendo archivo con parámetros usando Alamofire

Estoy intentando subir un archivo usando Alamofire . La carga funciona bien cuando se utiliza un archivo ( NSUrl ), sin embargo, parece que no entiendo cómo usar la opción NSData .

Esto es lo que tengo como prueba:

  var url:NSURL = NSURL.URLWithString("http://localhost:8080/bike.jpeg") var err: NSError? var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err) Alamofire.upload(.POST, "http://localhost:8080/rest/service/upload/test.png", imageData) .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in println(totalBytesWritten) } .responseJSON { (request, response, JSON, error) in println(request) println(response) println(JSON) } 

Estoy obteniendo un código de estado 415?

Además, ¿cómo puedo enviar params adicionales en la carga?

Gracias

EDITAR

No estaba configurando el tipo de contenido correcto:

 var manager = Manager.sharedInstance manager.session.configuration.HTTPAdditionalHeaders = ["Content-Type": "application/octet-stream"] let imageData: NSMutableData = NSMutableData.dataWithData(UIImageJPEGRepresentation(imageTest.image, 30)); Alamofire.upload(.POST, "http://localhost:8080/rest/service/upload?attachmentName=file.jpg", imageData) .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in println(totalBytesWritten) } .responseString { (request, response, JSON, error) in println(request) println(response) println(JSON) } 

Todavía no se puede saber cómo enviar parámetros adicionales junto con la carga.

Aquí hay una función simple que requiere la URL de subida de destino, los parámetros y imageData y devuelve el URLRequestConvertible y NSData que Alamofire.upload necesita para cargar una imagen con parámetros.

 // this function creates the required URLRequestConvertible and NSData we need to use Alamofire.upload func urlRequestWithComponents(urlString:String, parameters:Dictionary, imageData:NSData) -> (URLRequestConvertible, NSData) { // create url request to send var mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!) mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue let boundaryConstant = "myRandomBoundary12345"; let contentType = "multipart/form-data;boundary="+boundaryConstant mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type") // create upload data to send let uploadData = NSMutableData() // add image uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData("Content-Disposition: form-data; name=\"file\"; filename=\"file.png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData(imageData) // add parameters for (key, value) in parameters { uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!) } uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) // return URLRequestConvertible and NSData return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData) } 

Aquí hay un ejemplo de cómo usarlo (vea CREAR Y ENVIAR SOLICITUD):

 // init paramters Dictionary var parameters = [ "task": "task", "variable1": "var" ] // add addtionial parameters parameters["userId"] = "27" parameters["body"] = "This is the body text." // example image data let image = UIImage(named: "177143.jpg") let imageData = UIImagePNGRepresentation(image) // CREATE AND SEND REQUEST ---------- let urlRequest = urlRequestWithComponents("http://example.com/uploadText/", parameters: parameters, imageData: imageData) Alamofire.upload(urlRequest.0, urlRequest.1) .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in println("\(totalBytesWritten) / \(totalBytesExpectedToWrite)") } .responseJSON { (request, response, JSON, error) in println("REQUEST \(request)") println("RESPONSE \(response)") println("JSON \(JSON)") println("ERROR \(error)") } 

Y si necesita el archivo php para la URL de destino (con una carpeta ‘uploads’ en el mismo directorio):

 // get picture variables $file = $_FILES['file']['tmp_name']; $fileName = $_FILES['file']['name']; $fileType = $_FILES['file']['type']; // check extension $allowedExts = array("jpg", "jpeg", "png"); $rootName = reset(explode(".", $fileName)); $extension = end(explode(".", $fileName)); // create new file name $time = time(); $newName = $rootName.$time.'.'.$extension; // temporarily save file $moved = move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/".$newName ); if ($moved) $path = "uploads/".$newName; $body = $_POST['body']; $userId = $_POST['userId']; $time = time(); if ($moved) { $fullUrl = "http://antiblank.com/testPhotoUpload/".$path; $arrayToSend = array('status'=>'success','time'=>$time,'body'=>$body,'userId'=>$userId, "imageURL"=>$fullUrl); } else { $arrayToSend = array('status'=>'FAILED','time'=>$time,'body'=>$body,'userId'=>$userId); } header('Content-Type:application/json'); echo json_encode($arrayToSend); 

Cargar fotos / archivos con parámetros y encabezados personalizados a través de Swift 3 y 4 y Alamofire 4

 // import Alamofire func uploadWithAlamofire() { let image = UIImage(named: "bodrum")! // define parameters let parameters = [ "hometown": "yalikavak", "living": "istanbul" ] Alamofire.upload(multipartFormData: { multipartFormData in if let imageData = UIImageJPEGRepresentation(image, 1) { multipartFormData.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png") } for (key, value) in parameters { multipartFormData.append((value?.data(using: .utf8))!, withName: key) }}, to: "upload_url", method: .post, headers: ["Authorization": "auth_token"], encodingCompletion: { encodingResult in switch encodingResult { case .success(let upload, _, _): upload.response { [weak self] response in guard let strongSelf = self else { return } debugPrint(response) } case .failure(let encodingError): print("error:\(encodingError)") } }) } 

a través de Swift 2 y Alamofire 3

  // import Alamofire func uploadWithAlamofire() { let image = UIImage(named: "myImage")! // define parameters let parameters = [ "hometown": "yalikavak", "living": "istanbul" ] // Begin upload Alamofire.upload(.POST, "upload_url", // define your headers here headers: ["Authorization": "auth_token"], multipartFormData: { multipartFormData in // import image to request if let imageData = UIImageJPEGRepresentation(image, 1) { multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "myImage.png", mimeType: "image/png") } // import parameters for (key, value) in parameters { multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key) } }, // you can customise Threshold if you wish. This is the alamofire's default value encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.responseJSON { response in debugPrint(response) } case .Failure(let encodingError): print(encodingError) } }) } 

Aquí hay una solución que usa Alamofire 3.0 basada en la respuesta antiblancos:

  let parameters = [ "par1": "value", "par2": "value2"] let URL = "YOUR_URL.php" let image = UIImage(named: "image.png") Alamofire.upload(.POST, URL, multipartFormData: { multipartFormData in if let _image = image { if let imageData = UIImageJPEGRepresentation(_image, 0.5) { multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: "file.png", mimeType: "image/png") } } for (key, value) in parameters { multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key) } }, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.responseObject { (response: Response) -> Void in switch response.result { case .Success: completionHandler?(success: true) case .Failure(let error): completionHandler?(success: false) } } case .Failure(let encodingError): print(encodingError) } }) 

Mejorando la respuesta de EdFunke para Swift 2.2 Alamofire 3.3.1

 Alamofire.upload(.POST, urlString, multipartFormData: { multipartFormData in if let _image = self.profilePic.image { if let imageData = UIImagePNGRepresentation(_image) { multipartFormData.appendBodyPart(data: imageData, name: "user_image", fileName: "file.png", mimeType: "image/png") } } for (key, value) in userInfo { multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key) } }, encodingCompletion: { encodingResult in switch encodingResult { case .Success(let upload, _, _): upload.responseJSON { response in debugPrint(response) } case .Failure(let encodingError): print(encodingError) } } ) 

La carga de varias partes está progtwigda para ser incluida con la próxima versión (1.3.0) de Alamofire. Mientras tanto, usando la información en este hilo, hice una clase que simplifica la carga de archivos e incluye parámetros adicionales (“entradas” regulares) en la solicitud junto con uno o más archivos. Sin asumir que los archivos son de un tipo particular o el uso de enrutadores.

FileUploader.swift:

 import Foundation import Alamofire private struct FileUploadInfo { var name:String var mimeType:String var fileName:String var url:NSURL? var data:NSData? init( name: String, withFileURL url: NSURL, withMimeType mimeType: String? = nil ) { self.name = name self.url = url self.fileName = name self.mimeType = "application/octet-stream" if mimeType != nil { self.mimeType = mimeType! } if let _name = url.lastPathComponent { fileName = _name } if mimeType == nil, let _extension = url.pathExtension { switch _extension.lowercaseString { case "jpeg", "jpg": self.mimeType = "image/jpeg" case "png": self.mimeType = "image/png" default: self.mimeType = "application/octet-stream" } } } init( name: String, withData data: NSData, withMimeType mimeType: String ) { self.name = name self.data = data self.fileName = name self.mimeType = mimeType } } class FileUploader { private var parameters = [String:String]() private var files = [FileUploadInfo]() private var headers = [String:String]() func setValue( value: String, forParameter parameter: String ) { parameters[parameter] = value } func setValue( value: String, forHeader header: String ) { headers[header] = value } func addParametersFrom( #map: [String:String] ) { for (key,value) in map { parameters[key] = value } } func addHeadersFrom( #map: [String:String] ) { for (key,value) in map { headers[key] = value } } func addFileURL( url: NSURL, withName name: String, withMimeType mimeType:String? = nil ) { files.append( FileUploadInfo( name: name, withFileURL: url, withMimeType: mimeType ) ) } func addFileData( data: NSData, withName name: String, withMimeType mimeType:String = "application/octet-stream" ) { files.append( FileUploadInfo( name: name, withData: data, withMimeType: mimeType ) ) } func uploadFile( request sourceRequest: NSURLRequest ) -> Request? { var request = sourceRequest.mutableCopy() as! NSMutableURLRequest let boundary = "FileUploader-boundary-\(arc4random())-\(arc4random())" request.setValue( "multipart/form-data;boundary=\(boundary)", forHTTPHeaderField: "Content-Type") let data = NSMutableData() for (name, value) in headers { request.setValue(value, forHTTPHeaderField: name) } // Amazon S3 (probably others) wont take parameters after files, so we put them first for (key, value) in parameters { data.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) data.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!) } for fileUploadInfo in files { data.appendData( "\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)! ) data.appendData( "Content-Disposition: form-data; name=\"\(fileUploadInfo.name)\"; filename=\"\(fileUploadInfo.fileName)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) data.appendData( "Content-Type: \(fileUploadInfo.mimeType)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) if fileUploadInfo.data != nil { data.appendData( fileUploadInfo.data! ) } else if fileUploadInfo.url != nil, let fileData = NSData(contentsOfURL: fileUploadInfo.url!) { data.appendData( fileData ) } else { // ToDo: report error return nil } } data.appendData("\r\n--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) return Alamofire.upload( request, data ) } } 

Se usaría así:

 // This example uploads a file called example.png found in the app resources let fileURL = NSBundle.mainBundle().URLForResource("example", withExtension: "png") let fileUploader = FileUploader() // we can add multiple files // this would be equivalent to:  fileUploader.addFileURL(fileURL!, withName: "myFile") // we can add NSData objects directly let data = UIImage(named: "sample") fileUploader.addFileData( UIImageJPEGRepresentation(data,0.8), withName: "mySecondFile", withMimeType: "image/jpeg" ) // we can also add multiple aditional parameters // this would be equivalent to:  fileUploader.setValue( "sample", forParameter: "folderName" ) // put your server URL here var request = NSMutableURLRequest( URL: NSURL(string: "http://myserver.com/uploadFile" )! ) request.HTTPMethod = "POST" fileUploader.uploadFile(request: request) 

Compruébelo o descárguelo de esta esencia: https://gist.github.com/ncerezo/b1991f8dfac01cb162c0

El código en la respuesta de @ antiblank no funcionaba para mí. Hice algunos cambios y está funcionando ahora:

 func urlRequestWithComponents(urlString:String, parameters:NSDictionary) -> (URLRequestConvertible, NSData) { // create url request to send var mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!) mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue //let boundaryConstant = "myRandomBoundary12345" let boundaryConstant = "NET-POST-boundary-\(arc4random())-\(arc4random())" let contentType = "multipart/form-data;boundary="+boundaryConstant mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type") // create upload data to send let uploadData = NSMutableData() // add parameters for (key, value) in parameters { uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) if value is NetData { // add image var postData = value as NetData //uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(postData.filename)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) // append content disposition var filenameClause = " filename=\"\(postData.filename)\"" let contentDispositionString = "Content-Disposition: form-data; name=\"\(key)\";\(filenameClause)\r\n" let contentDispositionData = contentDispositionString.dataUsingEncoding(NSUTF8StringEncoding) uploadData.appendData(contentDispositionData!) // append content type //uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) // mark this. let contentTypeString = "Content-Type: \(postData.mimeType.getString())\r\n\r\n" let contentTypeData = contentTypeString.dataUsingEncoding(NSUTF8StringEncoding) uploadData.appendData(contentTypeData!) uploadData.appendData(postData.data) }else{ uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!) } } uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) // return URLRequestConvertible and NSData return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData) } 

UTILIZAR:

 let docDir:AnyObject = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] let imagePath = docDir + "/myPic.jpg" var imageData = NSData(contentsOfFile: imagePath, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: nil) var parameters = [ "pic" :NetData(nsData: imageData!, filename: "customName.jpg"), "otherParm" :"Value" ] let urlRequest = self.urlRequestWithComponents("http://www.example.com/upload.php", parameters: parameters) 

El NetData de https://github.com/nghialv/Net/blob/master/Net/NetData.swift

Código upload.php:

 < ?php // In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead // of $_FILES. $uploaddir = 'uploads/'; // PS: custom filed name : pic $uploadfile = $uploaddir . basename($_FILES['pic']['name']); if (move_uploaded_file($_FILES['pic']['tmp_name'], $uploadfile)) { $array = array ("code" => "1", "message" => "successfully"); } else { $array = array ("code" => "0", "message" => "Possible file upload attack!".$_FILES['pic']['name']); } echo json_encode ( $array ); ?> 

Versión más corta basada en respuestas @antiblank y @VincentYan.

Clase

 class Photo { class func upload(image: UIImage, filename: String) -> Request { let route = Router.CreatePhoto() var request = route.URLRequest.mutableCopy() as NSMutableURLRequest let boundary = "NET-POST-boundary-\(arc4random())-\(arc4random())" request.setValue("multipart/form-data;boundary="+boundary, forHTTPHeaderField: "Content-Type") let parameters = NSMutableData() for s in ["\r\n--\(boundary)\r\n", "Content-Disposition: form-data; name=\"photos[photo]\";" + " filename=\"\(filename)\"\r\n", "Content-Type: image/png\r\n\r\n"] { parameters.appendData(s.dataUsingEncoding(NSUTF8StringEncoding)!) } parameters.appendData(UIImageJPEGRepresentation(image, 1)) parameters.appendData("\r\n--\(boundary)--\r\n" .dataUsingEncoding(NSUTF8StringEncoding)!) return Alamofire.upload(request, parameters) } } 

Uso

 let rep = (asset as ALAsset).defaultRepresentation() let ref = rep.fullResolutionImage().takeUnretainedValue() Photo.upload(UIImage(CGImage: ref)!, filename: rep.filename()) .progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in println(totalBytesWritten) } .responseJSON { (request, response, JSON, error) in println(JSON) } 

Si bien hay otras respuestas que aconsejan cómo crear manualmente solicitudes de varias partes, es posible que desee seguir con AFNetworking. Aunque está escrito en Objective-C, puede usarlo en sus proyectos Swift (vea Swift y Objective-C en el mismo proyecto ). De todos modos, el código Swift para enviar una solicitud multiparte utilizando AFNetworking es el siguiente:

 let data = UIImagePNGRepresentation(image) let manager = AFHTTPSessionManager() manager.POST(uploadURLString, parameters: nil, constructingBodyWithBlock: { formData in formData.appendPartWithFileData(data, name: "image", fileName: "test.png", mimeType: "image/png") }, success: { operation, responseObject in println(responseObject) }) { operation, error in println(error) } 

Xcode molesto tiene problemas para reconocer este parámetro id , formData , por lo que no disfruta de la finalización del código del editor típico del método appendPartWithFileData o sus parámetros, pero cuando lo comstack y lo ejecuta, funciona bien.

Obtiene 415 por perder el tipo de contenido en su solicitud. A continuación se muestra una cantidad total de carga de imágenes en Swift 2 y AlamoFire

 import UIKit import Alamofire class ViewController: UIViewController { @IBOutlet var imageView: UIImageView! @IBOutlet var btnUpload: UIButton! override func viewDidLoad() { super.viewDidLoad() } func successDataHandler(responseData:String){ print ("IMAGE UPLOAD SUCCESSFUL !!!") } func failureDataHandler(errorData:String){ print (" !!! IMAGE UPLOAD FAILURE !!! ") } @IBAction func actionUpload(sender: AnyObject) { let URL = "http://m8coreapibeta.azurewebsites.net/api/cards/SaveImages" let postDataProlife:[String:AnyObject] = ["CardId":(dataCardDetail?.userId)!,"ImageType":1,"ImageData":imageView.image!] uplaodImageData(URL, postData: postDataProlife, successHandler: successDataHandler, failureHandler: failureDataHandler) } func uplaodImageData(RequestURL: String,postData:[String:AnyObject]?,successHandler: (String) -> (),failureHandler: (String) -> ()) -> () { let headerData:[String : String] = ["Content-Type":"application/json"] Alamofire.request(.POST,RequestURL, parameters: postData, encoding: .URLEncodedInURL, headers: headerData).responseString{ response in switch response.result { case .Success: print(response.response?.statusCode) successHandler(response.result.value!) case .Failure(let error): failureHandler("\(error)") } } } } 

A continuación se muestran los códigos Swift y Php

Código Swift -> Apple Swift versión 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1) Objetivo: x86_64-apple-macosx10.9

  class func upload(jsonObject: AnyObject , files : Array? = nil , completionHandler : CompletionBlock? = nil ,failureHandler : FailureBlock? = nil ) { Alamofire.upload(multipartFormData: { (multipartFormData) in if let filesO = files { for i in (filesO.enumerated()) { let image = UIImage(named: "\(i.element)") let data = UIImageJPEGRepresentation(image!, 1)! multipartFormData.append(data, withName: "imgFiles[]" , fileName: "\( NSUUID().uuidString).jpeg" , mimeType: "image/jpeg") // imgFiles[] give array in Php Side // imgFiles will give string in PHP String } } for (key, value) in jsonObject as! [String : String] { multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key) }} }, to:baseURL) 

Código PHP para obtener parámetros y archivos

Aquí se manejan los parámetros en $ _Request

Y los archivos se manejan en $ _File

El formato en $ _File data (Array, Dictionary o String) dependerá de Request en swift side, Here Ver esta línea en código

multipartFormData.append (data, withName: “imgFiles []”, fileName: “(NSUUID (). uuidString) .jpeg”, mimeType: “image / jpeg”)

en Php side withName: “imgFiles []” da una matriz de nombre, formato, Tipo

P.ej

“nombre”: [“06748B86-478E-421B-8470-6262755AC149.jpeg”, “E70269E9-FB54-4BFD-B807-7E418C81540D.jpeg”], “tipo”: [“image / jpeg”, “image / jpeg” ], “tmp_name”: [“/ tmp / phpz3UAPq”, “/ tmp / phpCAPExG”], “error”: [0,0], “tamaño”: [2779495,2067259]}

Código PHP

  if (isset($_FILES['imgFiles']) and strlen($orderId) > 0) { foreach ($_FILES['imgFiles']['tmp_name'] as $key => $tmp_name) { $file_name = $key . $_FILES['imgFiles']['name'][$key]; $file_size = $_FILES['imgFiles']['size'][$key]; $file_tmp = $_FILES['imgFiles']['tmp_name'][$key]; $file_type = $_FILES['imgFiles']['type'][$key]; if (is_dir("$desired_dir/" . $file_name) == false) { //move_uploaded_file($file_tmp, "user_data/" . $file_name); move_uploaded_file($file_tmp, $desired_dir . "/" . $file_name); } else { //rename the file if another one exist $new_dir = $desired_dir . "/" . $file_name . time(); rename($file_tmp, $new_dir); } 

Tomé la respuesta de antiblank y envolví todo esto en 1 función con controlador de finalización. Pensé que podría ser útil para alguien. Es un poco más “rudo” que la respuesta de antiblank ya que simplemente estoy tomando una respuesta de cadena del archivo PHP (no JSON).

Así es como lo llamas:

 let imageData = UIImagePNGRepresentation(myImageView.image) uploadImage("http://www.example.com/image_upload.php", imageData: imageData, subdir: "images", filename: "imageID.png") { (req, res, str, err) -> Void in // do whatever you want to to for error handling and handeling success } 

Aquí está la función en sí:

 func uploadImage(urlToPHPFile: String, imageData: NSData, subdir: String, filename: String, completionHandler:(request:NSURLRequest, response:NSURLResponse?, responseString:String?, error: NSError?) -> ()) { func urlRequestWithComponents(urlString:String, parameters:Dictionary, imageData:NSData) -> (URLRequestConvertible, NSData) { // create url request to send var mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!) mutableURLRequest.HTTPMethod = Method.POST.rawValue let boundaryConstant = "myRandomBoundary12345"; let contentType = "multipart/form-data;boundary="+boundaryConstant mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type") // create upload data to send let uploadData = NSMutableData() // add image uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData("Content-Disposition: form-data; name=\"file\"; filename=\"file.png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData(imageData) // add parameters for (key, value) in parameters { uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!) } uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) // return URLRequestConvertible and NSData return (ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData) } let parameters = [ "subdir" : subdir, "filename": filename ] let urlRequest = urlRequestWithComponents(urlToPHPFile, parameters, imageData) AlamoFire.upload(urlRequest.0, urlRequest.1) .responseString(completionHandler: { [weak self] (req, res, str, err) -> Void in if let strongSelf = self { completionHandler(request: req, response: res, responseString: str, error: err) } } ) } 

Y aquí está el archivo php.

 $subdir = $_POST['subdir']; $filename = $_POST["filename"]; $targetPath = $subdir.'/'.$filename; $moved = move_uploaded_file($_FILES["file"]["tmp_name"], $targetPath ); if ($moved) { echo "OK"; } else { echo "Error: file not uploaded"; }