1

As I am new to iOS, am stuck here for a while, I need to upload the image to a server with key and value as ("file": image), find the image as attached in postman.

I have tried almost every suggestion here How to upload images to a server in iOS with Swift?, Upload image to server - Swift 3

Here I have tried something but not getting output response because of the key not passed in the request

let url = URL(string: uploadurl);
let request = NSMutableURLRequest(url: url!);
request.httpMethod = "POST"
let boundary = "Boundary-\(NSUUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(image, 1)
if (imageData == nil) {
    print("UIImageJPEGRepresentation return nil")
    return
}
let body = NSMutableData()
//here I need to pass the data as ["file":image]
body.append(imageData!)
request.httpBody = body as Data
let task =  URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if let data = data {
        // do
        let json =  try!JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
        print("json value \(json)")
    } else if let error = error {
        print(error.localizedDescription)
    }
})
task.resume()

Please suggest me, how to pass the these image in body as ["file": image].

Thanks in advance

pbodsk
  • 6,787
  • 3
  • 21
  • 51
Swift_prasad
  • 65
  • 1
  • 11
  • You are not showing the most important part of your code, so we cannot say what is wrong. Please show your full code and the server response with it, in addition to how your server receives `file`. – OOPer May 07 '19 at 05:47
  • https://drive.google.com/open?id=1xmLZHEnID22LS2P4H6hFcLIhM-bF4-mh , please find the screen shot, this is what i expected, thanks for the response – Swift_prasad May 07 '19 at 05:54
  • You should better include as much info as you can, as text into the text of your question, to get better responses sooner. You know you can edit your own question. – OOPer May 07 '19 at 06:35
  • @Swift_prasad You should check out this post : https://stackoverflow.com/questions/26335656/how-to-upload-images-to-a-server-in-ios-with-swift – VRAwesome May 07 '19 at 06:41
  • @Swift_prasad I can suggest that it is better to use `Alamofire` for multipart. https://stackoverflow.com/questions/40519829/upload-image-to-server-using-alamofire – VRAwesome May 07 '19 at 06:44
  • @VRAwesome thanks for the response, am using alamofire as you suggested, here is my code . Alamofire.upload(multipartFormData: { multipartFormData in multipartFormData.append(imgData, withName: "file") }, can u suggest me where i can pass the values as ["file":image] – Swift_prasad May 07 '19 at 06:54
  • `withName:` is your `key`, `fileName:` is your filename what you want to keep on your server and `imageData` you can append. – VRAwesome May 07 '19 at 07:07

2 Answers2

1

You could use URLSession to upload a multipart/form-data

  1. The upload

The function to upload the image

    // build request URL

    guard let requestURL = URL(string: "YOURURL") else {
        return
    }

    // prepare request
    var request = URLRequest(url: requestURL)
    request.allHTTPHeaderFields = header
    request.httpMethod = MethodHttp.post.rawValue

    let boundary = generateBoundaryString()

    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    // built data from img
    if let imageData = image.jpegData(compressionQuality: 1) {
        request.httpBody = createBodyWithParameters(parameters: param, filePathKey: "file", imageDataKey: imageData, boundary: boundary)
    }

    let task =  URLSession.shared.dataTask(with: request,
                                           completionHandler: { (data, _, error) -> Void in

                                            if let data = data {

                                                debugPrint("image uploaded successfully \(data)")

                                            } else if let error = error {
                                                debugPrint(error.localizedDescription)
                                            }
    })
    task.resume()
  1. The body

the function that will create the request body

 func createBodyWithParameters(parameters: [String: String],

                                          filePathKey: String,
                                          imageDataKey: Data,
                                          boundary: String) -> Data {

                let body = NSMutableData()
                let mimetype = "image/*"

                body.append("--\(boundary)\r\n".data(using: .utf8) ?? Data())
                body.append("Content-Disposition: form-data; name=\"\(filePathKey)\"; filename=\"\(filePathKey)\"\r\n".data(using: .utf8) ?? Data())
                body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: .utf8) ?? Data())
                body.append(imageDataKey)
                body.append("\r\n".data(using: .utf8) ?? Data())

                body.append("--\(boundary)--\r\n".data(using: .utf8) ?? Data())



          return body as Data
        }

        private func generateBoundaryString() -> String {
            return "Boundary-\(Int.random(in: 1000 ... 9999))"
        }

    }
  1. Data extension

    extension NSMutableData {
    
    func appendString(_ string: String) {
           if let data = string.data(using: String.Encoding.utf8, 
              allowLossyConversion: true) {
                 append(data)
            }
         }
     }
    
Marwen Doukh
  • 1,946
  • 17
  • 26
1

Try this. Save the file in documentDirectory. Add the file in body with boundary which is a random string. Then add the key of the file as name=\"file\"

if !fileName.isEmpty {
    let pathComponents = [NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!, fileName]
    outputFileURL = NSURL.fileURL(withPathComponents: pathComponents) //get the image file from documentDirectory

    //add file to body (name=\"file\")
    body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Disposition: form-data; name=\"file\"; filename=\"image.jpeg\"\r\n".data(using: String.Encoding.utf8)!)
    body.append("Content-Type: image/*\r\n\r\n".data(using: String.Encoding.utf8)!)
    do {
        try body.append(Data(contentsOf: outputFileURL!))
    } catch {
        print(error)
    }
    body.append("\r\n".data(using: String.Encoding.utf8)!)
    body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)

}
Arnab
  • 4,216
  • 2
  • 28
  • 50
  • I have copied image in project named(IMG_1302.JPG), and as your guidness i have copied the code as below........... body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!) body.append("Content-Disposition: form-data; name=\"file\"; filename=\"IMG_1302.JPG\"\r\n".data(using: String.Encoding.utf8)!) body.append("Content-Type: image/*\r\n\r\n".data(using: String.Encoding.utf8)!) body.append("\r\n".data(using: String.Encoding.utf8)!) body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!).. but still am unable to get the response – Swift_prasad May 07 '19 at 08:48
  • please post if you're getting any errors. else i think you should debug with your backend devs if you're doing anything wrong. – Arnab May 07 '19 at 09:52