Enviar el archivo con los parámetros de uso de Alamofire

Estoy tratando de cargar un archivo con Alamofire. La carga funciona bien cuando se utiliza un Archivo (NSUrl), sin embargo, me parece que no puede averiguar cómo usar la NSData opción?

Esto es lo que yo tengo como una 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 recibiendo un código de estado 415?

También, ¿cómo puedo enviar a través de parámetros adicionales en la carga?

Gracias

EDITAR

Yo no estaba establecer el correcto Tipo de Contenido:

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 puede averiguar cómo enviar parámetros adicionales junto con la carga.

  • El uso de «multipartFormData.appendBodyPart(datos: image1Data, nombre: «archivo», nombre de archivo: «miimagen.png», mimeType: «image/png»)» esta es imp de lo contrario el error «Invalid valor de alrededor de carácter 0»
InformationsquelleAutor user3432352 | 2014-09-30

11 Kommentare

  1. 81

    Aquí es una simple función que requiere el objetivo de subir la url, parámetros, y imageData y devuelve el URLRequestConvertible y NSData que Alamofire.de carga requiere para cargar una imagen con los 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)
    }    

    He aquí un ejemplo de cómo usarlo (consulte creación Y ENVÍO de 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 se necesita el archivo php para la dirección url de destino (con una ‘carga’ de la carpeta 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);
    • Hola,yo ya utilizan este método y funciona bien.Pero en el lado del servidor que la solicitud de cambio de tipo de contenido JSON.después de que este método no funciona.Quiero cargar los datos en json…puede usted por favor me ayudan
    • casi la derecha, uploadData.appendData(«Content-Disposition: form-data; name=\»archivo\»; filename=\»archivo.png\»\r\n».dataUsingEncoding(NSUTF8StringEncoding)!) en esta línea name=\»archivo\» ,de hecho, el archivo es el nombre de la clave que va a tratar con el servidor..como un clip.
    • Minas estaba trabajando antes y ahora me estoy poniendo NSCocoaErrorDomain código de 3840, alguien ha solucionado este problema?
    • gracias por compartir este código. Podrías aconsejar oh cómo modificar esta función, con lo que se puede aceptar NSData o nulo para la imagen de parámetros como los usuarios tienen la opción de si o no para cargar una imagen en mi web llamada de servicio. Podría utilizar anyObject en lugar de NSData en la definición
    • cómo PONER sobre solicitud y actualización de cosas. @antiblank
    • ¿cómo podemos hacer esto incluyendo las cabeceras también?
    • cualquier método disponible en Alamofire como AFNetworking.
    • Creo que esto me salvó un par de días. Una cosa que en mi caso es que tengo que mover el bucle for para los parámetros porque mi servidor necesidad de los parámetros de la primera antes de que se puede manejar el archivo.
    • Alamofire.Método.POST.rawValue en swift 3?
    • En swift 3 debe ser mutableURLRequest.httpMethod = Alamofire.HTTPMethod.post.rawValue
    • Cómo actualizar esta para swift 3 y alamofire4 para crear la necesaria URLRequestConvertible?
    • Cómo pasar los encabezados de @antiblank

  2. 70

    Subir Foto /Archivo con los parámetros de y encabezados personalizados a través de Swift 3 & 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)
            }
        })
      }
    • cualquier organismo puede decirme acerca de estas por debajo de las líneas si vamos a imageData = UIImageJPEGRepresentation(imagen 1) { multipartFormData.append(imageData, aname: «archivo», nombre de archivo: «archivo.png», mimeType: «image/png») } for (clave, valor) en parámetros { multipartFormData.append((valor?.de datos(usando: .utf8))!, aname: clave) }}
    • Esto no funcionará si parameters es [String:Any] porque value.data(using: .utf8))! no es válido para Any Type. ¿Tienen sugerencias de cómo resolver esto ?
  3. 57

    Aquí es una Solución de uso de Alamofire 3.0 basado en antiblanks respuesta:

     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)
                    }
            })
    • ¿Cómo usted va sobre la anulación de esta subida? En otras respuestas veo a la gente diciendo a la realización de la carga para un var, pero cuando hago que el tipo se deduce como (), por lo tanto, no permitiendo que los métodos para sobre ella ? Gracias.
    • Usted puede llamar a cancelar() en la solicitud-Objeto. Algo así como: subir.cancel(). Usted puede asignar la solicitud-Objeto a una variable y llame a cancelar()
    • case .Success(let upload, _, _) upload no se puede encontrar. Me estoy perdiendo algo?
    • es un MultipartFormDataEncodingResult enum. El .Success Case tiene los siguientes parámetros: (request: Request, streamingFromDisk: Bool, streamFileURL: NSURL?) Así upload es una Petición. ¿Agregar import Alamofire?
    • ¿Cómo se puede mantener el progreso con esto?
    • intente algo como: case .Success(let upload, _, _): upload.progress({ (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) -> Void in //HERE YOUR CODE FOR PROGRESSUPDATE }).responseObject { (response: Response<UploadData, NSError>) -> Void in }
    • Mi diccionario de parámetros tiene un valor, que es en sí misma una matriz como vamos params:[«studentList»:[«25″,»26»]] . Cuando escribo esto me estoy poniendo de error como «NSObject no tiene miembro como dataUsingEncoding» . Qué hacer en ese caso?
    • Los datos de imagen en formato JPEG representación, pero MIMEType está mal PNG – imagen «/**png**»
    • multipartFormData.appendBodyPart(datos: imageData, nombre: «archivo», nombre de archivo: «archivo.png», mimeType: «image/png») ¿Puede por favor explicar los parámetros de la appendBodyPart método?
    • no funciona en Alamofire 4.0. Me puedes dar algún enlace o ejemplo de que trabajando en 4.0.

  4. 10

    La mejora de EdFunke la respuesta 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)
                    }
                }
            )
  5. 4

    De varias partes de carga está programada para incluirse con el siguiente (1.3.0) la liberación de Alamofire.
    En el ínterin, el uso de la información en este hilo, he hecho una clase que simplifica la carga de archivos e incluyendo parámetros adicionales (regular «entradas») en la solicitud junto con uno o más archivos.
    Sin suponiendo que los archivos de un determinado tipo 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 )
      }
    
    }

    Sería utilizado como esta:

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

    Check it out o descargar desde esta esencia: https://gist.github.com/ncerezo/b1991f8dfac01cb162c0

    • Hola, hay alguna forma de comprobar que el proceso de carga de éxito o más bien fallo en iOS lado, en el caso de ejemplo? Gracias por responder.
    • Sí, por supuesto. Como ya he mencionado, la uploadFile(petición) método devuelve un objeto de Solicitud, como el Alamofire.método de solicitud, así que usted puede simplemente de la cadena de progreso y/o respuesta de los cierres. Por ejemplo: fileUploader.uploadFile( petición: petición ).respuesta { (request,response,datos,error) en …. }
  6. 3

    El código en @antiblank la respuesta no estaba funcionando para mí. He hecho un par de cambios y ahora funciona:

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

    USO:

    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)

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

    upload.php Código:

    <?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 );  
    
    ?>
    • Sería bueno si el estado lo que el cambio que has hecho. Se trataba de una simple mejora que podría ser una edición a @antiblank la respuesta?
    • Hola milz ,sí pocos cambiar de @antiblank respuesta,el código es que me ayude mucho. Gracias
  7. 2

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

    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)
        }
    • Cuando traté de usar el código que estoy recibiendo error llamado «Uso de sin resolver identificador ‘Router'», creo que el Router es una enumeración que se usa aquí. Podría usted por favor, actualice la respuesta ? Thankz
    • Crear un Router de enumeración o crear manualmente NSURLRequest en lugar de utilizar el Router. github.com/Alamofire/Alamofire
  8. 2

    Mientras que hay otras respuestas que aconsejan cómo manualmente construir varias partes de las solicitudes, es posible que sólo quieren seguir con AFNetworking. Aunque está escrito en Objective-C, usted todavía puede utilizar en su Swift proyectos (ver Swift y Objective-C en el Mismo Proyecto). De todos modos, el código Swift para presentar una solicitud multiparte utilizando AFNetworking es como sigue:

    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 id<AFMultipartFormData> parámetro, formData, por lo que no te gusta el típico editor de código de finalización de la appendPartWithFileData método o de sus parámetros, pero al compilarlo y ejecutarlo, funciona bien.

    • Este es un buen punto, pero creo que el «manual» de la pieza es un poco más pequeño en Alamofire 3. Ver esta respuesta por encima (por debajo): stackoverflow.com/a/34961720/8047 … Gracias
  9. 1

    Usted está recibiendo 415 debido a la falta de la tipo de contenido en su solicitud.
    Abajo hay un total de soution para cargar la imagen 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)")
            }
        }
    }
    }
  10. 0

    A continuación se 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 los Parámetros de Archivo y

    Aquí los Parámetros son de Mango en $_Request

    De los Archivos y manejar en $_File

    Formato en $_File de datos(Matriz , un Diccionario o una Cadena ) dependerá de la Solicitud en swift lado , Aquí lo Vemos de esta línea en el código

    multipartFormData.append(datos, aname: «imgFiles[]» , fileName:
    «( NSUUID().uuidString).jpeg» , mimeType: «image/jpeg»)

    en Php lado aname: «imgFiles[]» da una matriz de nombre, formato , Tipo de

    Por ejemplo

    «nombre»:[«06748B86-478E-421B-8470-6262755AC149.jpeg»,»E70269E9-FB54-4BFD-B807-7E418C81540D.jpeg»], «type»:[«image/jpeg»,»image/jpeg»],
    «tmp_name»:[«/tmp/phpz3UAPq»,»/tmp/phpCAPExG»], «error»:[0,0],
    «size»:[2779495,2067259]}

    El 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);
                }
  11. -2

    Tomé antiblank la respuesta y envuelto todo esto en 1 con la función de controlador de finalización. Pensé que podría ser de utilidad para alguien. Es un poco ‘áspero’, a continuación, antiblank la respuesta de como yo simplemente me estoy tomando una respuesta de la cadena desde el archivo PHP (no JSON).

    Aquí cómo se llaman:

    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í la misma función:

    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";
    }

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea