Upload image with multipart form-data iOS in Swift
My version that 100% works. Maybe it will help you.
let url = "http://server/upload"let img = UIImage(contentsOfFile: fullPath)let data: NSData = UIImageJPEGRepresentation(img, 1)sendFile(url, fileName:"one.jpg", data:data, completionHandler: completionHandler:{ (result:Bool, isNoInternetConnection:Bool) -> Void in // ... NSLog("Complete: \(result)") })func sendFile( urlPath:String, fileName:String, data:NSData, completionHandler: (NSURLResponse!, NSData!, NSError!) -> Void){ var url: NSURL = NSURL(string: urlPath)! var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url) request1.HTTPMethod = "POST" let boundary = generateBoundary() let fullData = photoDataToFormData(data,boundary:boundary,fileName:fileName) request1.setValue("multipart/form-data; boundary=" + boundary, forHTTPHeaderField: "Content-Type") // REQUIRED! request1.setValue(String(fullData.length), forHTTPHeaderField: "Content-Length") request1.HTTPBody = fullData request1.HTTPShouldHandleCookies = false let queue:NSOperationQueue = NSOperationQueue() NSURLConnection.sendAsynchronousRequest( request1, queue: queue, completionHandler:completionHandler)}// this is a very verbose version of that function// you can shorten it, but i left it as-is for clarity// and as an examplefunc photoDataToFormData(data:NSData,boundary:String,fileName:String) -> NSData { var fullData = NSMutableData() // 1 - Boundary should start with -- let lineOne = "--" + boundary + "\r\n" fullData.appendData(lineOne.dataUsingEncoding( NSUTF8StringEncoding, allowLossyConversion: false)!) // 2 let lineTwo = "Content-Disposition: form-data; name=\"image\"; filename=\"" + fileName + "\"\r\n" NSLog(lineTwo) fullData.appendData(lineTwo.dataUsingEncoding( NSUTF8StringEncoding, allowLossyConversion: false)!) // 3 let lineThree = "Content-Type: image/jpeg\r\n\r\n" fullData.appendData(lineThree.dataUsingEncoding( NSUTF8StringEncoding, allowLossyConversion: false)!) // 4 fullData.appendData(data) // 5 let lineFive = "\r\n" fullData.appendData(lineFive.dataUsingEncoding( NSUTF8StringEncoding, allowLossyConversion: false)!) // 6 - The end. Notice -- at the start and at the end let lineSix = "--" + boundary + "--\r\n" fullData.appendData(lineSix.dataUsingEncoding( NSUTF8StringEncoding, allowLossyConversion: false)!) return fullData}
No Need to use any library for upload images using multipart request.
Swift 4.2
func uploadImage(paramName: String, fileName: String, image: UIImage) { let url = URL(string: "http://api-host-name/v1/api/uploadfile/single") // generate boundary string using a unique per-app string let boundary = UUID().uuidString let session = URLSession.shared // Set the URLRequest to POST and to the specified URL var urlRequest = URLRequest(url: url!) urlRequest.httpMethod = "POST" // Set Content-Type Header to multipart/form-data, this is equivalent to submitting form data with file upload in a web browser // And the boundary is also set here urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") var data = Data() // Add the image data to the raw http request data data.append("\r\n--\(boundary)\r\n".data(using: .utf8)!) data.append("Content-Disposition: form-data; name=\"\(paramName)\"; filename=\"\(fileName)\"\r\n".data(using: .utf8)!) data.append("Content-Type: image/png\r\n\r\n".data(using: .utf8)!) data.append(image.pngData()!) data.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!) // Send a POST request to the URL, with the data we created earlier session.uploadTask(with: urlRequest, from: data, completionHandler: { responseData, response, error in if error == nil { let jsonData = try? JSONSerialization.jsonObject(with: responseData!, options: .allowFragments) if let json = jsonData as? [String: Any] { print(json) } } }).resume()}
If you have any header to add, you can add it via urlRequest.setValue
method.
public func UPLOADIMG(url: String,parameters: Dictionary<String,AnyObject>?,filename:String,image:UIImage, success:((NSDictionary) -> Void)!, failed:((NSDictionary) -> Void)!, errord:((NSError) -> Void)!) { var TWITTERFON_FORM_BOUNDARY:String = "AaB03x" let url = NSURL(string: url)! var request:NSMutableURLRequest = NSMutableURLRequest(URL: url, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 10) var MPboundary:String = "--\(TWITTERFON_FORM_BOUNDARY)" var endMPboundary:String = "\(MPboundary)--" //convert UIImage to NSData var data:NSData = UIImagePNGRepresentation(image) var body:NSMutableString = NSMutableString(); // with other params if parameters != nil { for (key, value) in parameters! { body.appendFormat("\(MPboundary)\r\n") body.appendFormat("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n") body.appendFormat("\(value)\r\n") } } // set upload image, name is the key of image body.appendFormat("%@\r\n",MPboundary) body.appendFormat("Content-Disposition: form-data; name=\"\(filename)\"; filename=\"pen111.png\"\r\n") body.appendFormat("Content-Type: image/png\r\n\r\n") var end:String = "\r\n\(endMPboundary)" var myRequestData:NSMutableData = NSMutableData(); myRequestData.appendData(body.dataUsingEncoding(NSUTF8StringEncoding)!) myRequestData.appendData(data) myRequestData.appendData(end.dataUsingEncoding(NSUTF8StringEncoding)!) var content:String = "multipart/form-data; boundary=\(TWITTERFON_FORM_BOUNDARY)" request.setValue(content, forHTTPHeaderField: "Content-Type") request.setValue("\(myRequestData.length)", forHTTPHeaderField: "Content-Length") request.HTTPBody = myRequestData request.HTTPMethod = "POST" // var conn:NSURLConnection = NSURLConnection(request: request, delegate: self)! let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { data, response, error in if error != nil { println(error) errord(error) return } var parseError: NSError? let responseObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) if let responseDictionary = responseObject as? NSDictionary { success(responseDictionary) } else { } }) task.resume()}