example ios swift alamofire

ios - example - Subir archivo con parámetros usando Alamofire



alamofire swift 4 (11)

Estoy intentando cargar un archivo usando Alamofire . La carga funciona bien cuando se usa un archivo ( NSUrl ), sin embargo, ¿no puedo entender 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) }

¿Recibo un código de estado 415?

Además, ¿cómo puedo enviar parámetros 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 puedo entender cómo enviar parámetros adicionales junto con la carga.


A continuación se encuentran swift y el código 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<Any>? = 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í los parámetros se manejan en $ _Request

Y los archivos se manejan en $ _File

El formato en $ _Datos de archivo (matriz, diccionario o cadena) dependerá de la solicitud en el lado rápido, aquí vea esta línea en el código

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

en el lado Php 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], "size": [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); }


Aquí hay una función simple que requiere la URL, parámetros e imageData de carga de destino y devuelve el URLRequestConvertible y NSData que Alamofire.upload requiere 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<String, String>, 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);


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

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<UploadData, NSError>) -> Void in switch response.result { case .Success: completionHandler?(success: true) case .Failure(let error): completionHandler?(success: false) } } case .Failure(let encodingError): print(encodingError) } })


Cargue 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) } }) }


El código en la respuesta de @ antiblank no estaba funcionando para mí. He realizado 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 ); ?>


La carga multiparte está programada para incluirse con la próxima versión (1.3.0) de Alamofire. Mientras tanto, utilizando la información de este hilo, he creado 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 suponer 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: <input type="file" name="myFile"/> 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: <input type="hidden" name="folderName" value="sample"/> 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


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) } } )


Obtendrá 415 debido a que falta el tipo de contenido en su solicitud. A continuación se muestra una muestra completa 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)") } } } }


Si bien hay otras respuestas que aconsejan cómo construir manualmente solicitudes multiparte, es posible que solo desee seguir con AFNetworking. Aunque está escrito en Objective-C, aún puede usarlo en sus proyectos Swift (consulte Swift y Objective-C en el mismo proyecto ). De todos modos, el código Swift para enviar una solicitud multiparte usando 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<AFMultipartFormData> , formData , por lo que no disfruta la finalización típica del código del editor del método appendPartWithFileData o sus parámetros, pero cuando lo compila y lo ejecuta, funciona bien.


Tomé la respuesta de antiblank y envolví todo esto en 1 función con el controlador de finalización. Pensé que podría ser útil para alguien. Es un poco más áspero 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<String, String>, 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"; }


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) }