0

I have an App where I take a picture from the camera and it has to be send to a server (PHP), the problem is, that when I upload the picture, the server only receives a tmp file instead. How can I solve this? I thank your answers in advance. My code is the following:

Take Photo Button

    @IBAction func tomarFoto(_ sender: Any) {
    indicadorActividad.startAnimating()
    let image = UIImagePickerController()
    image.delegate = self

    image.sourceType = UIImagePickerControllerSourceType.camera

    image.allowsEditing = true

    self.present(image, animated: true){
    }
}

Change size of picture

@IBAction func tomarFoto(_ sender: Any) {
    indicadorActividad.startAnimating()
    let image = UIImagePickerController()
    image.delegate = self

    image.sourceType = UIImagePickerControllerSourceType.camera

    image.allowsEditing = true

    self.present(image, animated: true){
    }
}

ImagePicker

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {

        imageView.image = resizedImage(image: image, newWidth: 300, newHeight: 300)
        } else {
        //Algo
        }
        //Detenemos el indicador y se cierra la ventana de la camara/galeria
        self.indicadorActividad.stopAnimating()
        self.dismiss(animated: true, completion: nil)
        }


func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    picker.dismiss(animated: true, completion: nil)
    }

The following function takes the picture and Uploads it to the PHP server, I think the error might be here. Upload to server

func subirFotoRequest(){
    let url = URL(string: "http://192.168.0.155/BolsaTrabajo/imagen.php")

    let request = NSMutableURLRequest(url: url!)
    request.httpMethod = "POST"

    let boundary = generateBoundaryString()

    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    if (imageView.image == nil)
    {
        return
    }

    let image_data = UIImagePNGRepresentation(imageView.image!)

    if(image_data == nil)
    {
        return
    }

    let body = NSMutableData()
    indicadorActividad.startAnimating()

    let fname = "test.png"
    let mimetype = "image/png"


    body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Disposition:form-data; name=\"test\"\r\n\r\n".data(using: String.Encoding.utf8)!)
    body.append("hi\r\n".data(using: String.Encoding.utf8)!)

    body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Disposition:form-data; name=\"file\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
    body.append(image_data!)
    body.append("\r\n".data(using: String.Encoding.utf8)!)

    body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)

    request.httpBody = body as Data
    let session = URLSession.shared

    let task = URLSession.shared.dataTask(with: request as URLRequest) {            (
        data, response, error) in

        guard let _:Data = data, let _:URLResponse = response  , error == nil else {
            print("error")
            return
        }

        let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)

        print(dataString)
        //self.indicadorActividad.stopAnimating()



        do {
        DispatchQueue.main.async(execute: {
            self.indicadorActividad.stopAnimating()

            self.imageView.image = nil;
            });
        }
        catch{
            //Errores
        }


    }
    task.resume()       
}    

func generateBoundaryString() -> String
{
    return "Boundary-\(UUID().uuidString)"
}

And the final block of code is my PHP script. PHP File [UPDATED]

PHP file now uploads the picture in the respective format, the only problem is, it overrides my previous picture. How can I prevent this from happen? I was thinking probably by setting a name that will change for every picture in my swift class. Code updated is the following Previous code is commented:

//$ruta =  "Imagenes/";
  //if($_FILES["file"]["name"] !== ""){
    //  mkdir($ruta, 0777, true);
     // move_uploaded_file($_FILES["file"]["name"], $ruta.'/'. 
  //basename($_FILES["file"]["name"]));
   // echo "subido";
   //}


$fichero_subido = $dir_subida . basename($_FILES['file']['name']);

echo '<pre>';

   if(move_uploaded_file($_FILES['file']['tmp_name'], $fichero_subido)){
    echo "El fichero es válido y se subó con éxito \n";
   }
      else{
          echo "Posible ataque de subida de ficheros\n";
      }

  echo 'Más información de depuración: ';

print_r($_FILES);   
Daniel C.
  • 151
  • 1
  • 2
  • 10
  • PHP server stores uploaded data into a temporary file, you need to save it to somewhere permanent. So, the description _the server only receives a tmp file_ seems quite normal and your server and your Swift code is working well. What's the problem with the _tmp file_? – OOPer Jul 23 '17 at 21:10
  • I was expecting the PHP file to save an image. So I can put the image in a webpage. How can I save it permanently?? – Daniel C. Jul 23 '17 at 21:22
  • 1
    Your php code has one line moving the uploaded file keeping its `tmp_name`. Please see [POST method uploads](http://php.net/manual/en/features.file-upload.post-method.php) or related articles and update your PHP code. It depends on your server side configuration. – OOPer Jul 23 '17 at 21:35
  • I edited that line of code, changed the tmp_name for 'type', it does not show any warning but I cannot find the picture in the folder – Daniel C. Jul 23 '17 at 23:09
  • it says "[MC] Reading from public effective user settings. Optional()" – Daniel C. Jul 23 '17 at 23:10
  • Why and how do you use `'type'`? Show your PHP code. And ignore `[MC]...`. – OOPer Jul 24 '17 at 00:32
  • It's the same code, now I changed 'type' for 'name' – Daniel C. Jul 24 '17 at 01:21
  • Check the sample code in the link I have shown, it's not the same code as yours. Why do you think only changing _the tmp_name for 'type'_ would make your code work? Edit your question and show your latest code. – OOPer Jul 24 '17 at 01:27
  • Ok, I will edit my code and edit the question as well – Daniel C. Jul 24 '17 at 01:36
  • I want to thank you for taking your time helping me out, it was a struggling I had for weeks (starting with the "unable to move file uploaded" error). Now the PHP stores the image, but it overrides the previos one, I need help to solve this. I was thinking modifying the name "test.jpg" in my swift code for a generated string that changes every time it is run. – Daniel C. Jul 24 '17 at 02:31
  • Seems you have made up your PHP code fit for your server, congratulations. And your updated question, it may be a little modification, but depends on your requirement. Your app may have thousands of users and each user may upload thousands of images, no? My recommendation: **Post your A to this Q by yourself.** (Some explanation about your updated code -- for example, what is `$dir_subida`? -- would be appreciated.) **And start a new thread with as much explanation about the requirements for the saved file name.** (They can be completely random? ...) Updates cannot get good attentions. – OOPer Jul 24 '17 at 03:09
  • Yes, I will. dir_subida is the directory where the file will be stored, I forgot to translate from Spanish to English, my bad hahaha. And yes, the webpage will host thousands of users and a lot of photos are expected. – Daniel C. Jul 24 '17 at 03:15

0 Answers0