1

I have to make an API request to upload an image which's whether been taken by the camera or picked from the gallery. The method set in the API is set and in the body/parameters there's only

key:file
value: // 

where the value is the picture itself. (in postman I just upload a picture from my files and it works) and it returns an URL with some other information. The issue is I can't get the request to have a successful response, and I don't know how I can pass the UIImage to Alamofire. This is what I have done

Alamofire.request(baseUrl,
          method: .post,
          parameters: ["file" : expenseImage])
.responseJSON(completionHandler: { response in
                            guard response.result.error == nil else {
                                print("Error subiendo la imagen \n\(response.result.error!)")
                                return
                            }

                            guard let json = response.result.value as? [String: Any] else {
                                if let error = response.result.error {
                                    print("Error: \(error.localizedDescription)")
                                }
                                return
                            }
                            do {
                                let decoder = JSONDecoder()
                                let rawData = try JSONSerialization.data(withJSONObject: json, options: [])
                                let dataObject = try decoder.decode(PutObjectFile.self, from: rawData)
                                finished(dataObject)
                                print(dataObject)

                                print(dataObject.msg.file_info.url)
                            } catch let error {
                                print("Error decoding:\n\(error)")
                            }
                          })

and the error I'm getting in the console is the following:

responseSerializationFailed(reason: Alamofire.AFError
.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

I tried using a random picture url but it doesn't work either

emelagumat
  • 301
  • 2
  • 10

4 Answers4

1

You can upload images using multipart data, Use below code:

let manager = Alamofire.SessionManager.default
    do{
        manager.upload(multipartFormData: { (formData) in
            if let fileData = fileData { // File data
                formData.append(fileData, withName: "FILE_NAME", fileName: "simple.jpeg", mimeType: "image/jpeg")
            }
        }, to: "API_PATH", method: HTTPMethod.post, headers: nil, encodingCompletion: { encoding in
            switch encoding{
            case .success(let req, _, _):
                req.uploadProgress(closure: { (prog) in
                    progress?(prog)
                }).responseJSON { (resObj) in
                    switch resObj.result{
                    case .success:
                        if let resData = resObj.data{
                            do {
                                let res = try JSONSerialization.jsonObject(with: resData)
                                print(res) // Success
                            } catch let err{
                                print(err)
                            }
                        }
                        break
                    case .failure(let err):
                        print(err)
                        break
                    }
                }
                break
            case .failure(let err):
                print(err)
                break
            }
        })
    }catch let err{
        print(err)
    }
Anup Kanjariya
  • 292
  • 1
  • 2
  • 15
  • I get this error `Cannot invoke 'append' with an argument list of type '((CGFloat) -> Data?, withName: String, fileName: String, mimeType: String)'` – emelagumat Mar 29 '19 at 13:08
  • You need to convert UIImage to Data for appending in formData. Have you done that? – Anup Kanjariya Mar 29 '19 at 13:19
  • Now I did and I get this error again ```responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength) ``` – emelagumat Mar 29 '19 at 19:23
1

I had the same problem, I've solved it doing this: Alamofire 5.0.0-beta.5

AF.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(imgData, withName: "file",fileName: "file.jpg", mimeType: "image/jpg")
            },
        to: url).responseJSON
        { response in print(response)
            if let status = response.response?.statusCode {
                                print(status)
                            }
            //to get JSON return value
            if let result = response.value {
                let res = result as! [String: String]
                let newUrl:String = res["url"]!
                            print(newUrl)
            }
        }
QiZhou1512
  • 11
  • 1
  • 1
0

Use Alamofire's upload method to upload your image in multipartFormData. i have updated the code for you. use below code.

Alamofire.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(expenseImage, withName: "file",fileName: "file.jpg", mimeType: "image/jpg")
        },
with: baseUrl)
{ (result) in
    switch result {
    case .success(let upload, _, _):

        upload.uploadProgress(closure: { (progress) in
            print("Upload Progress: \(progress.fractionCompleted)")
        })

        upload.responseJSON { response in
             print(response.result.value)  
        }

    case .failure(let encodingError):
        print(encodingError)  
    }
}
Ajay saini
  • 2,352
  • 1
  • 11
  • 25
0
 {
        let id : String = UserDefaults.standard.string(forKey: "id")!
        print(id)

        self.view.makeToastActivity(.center)

        Alamofire.upload(multipartFormData: { (multipartFormData) in
            multipartFormData.append(UIImageJPEGRepresentation(self.imageView.image!, 0.5)!, withName: "profile_pic", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
            for (key, value) in [“key”: "", ] {
                multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
            }
        }, to:BaseURL + “base_url”)
        { (result) in
            switch result {
            case .success(let upload, _, _):

                upload.uploadProgress(closure: { (Progress) in
                    print("Upload Progress: \(Progress.fractionCompleted)")
                })

                upload.responseJSON { response in

                    if let JSON = response.result.value as? NSDictionary
                    {
                        print("JSON: \(JSON)")

                        let data = JSON["data"] as? NSArray


                        let status = JSON["status"] as? Int

                        if(status == 201)
                        {


                        }
                    }

                    self.view.hideToastActivity()
                }

            case .failure(let encodingError):
                //self.delegate?.showFailAlert()
                print(encodingError)
                self.view.hideToastActivity()
            }

        }
    }
Deviyani Swami
  • 749
  • 8
  • 17