Upload image with multipart form-data only in Swift 4.2
Please check my solution which is taken parameters and images.I have tested with PHP, .net, java.
class func request(withImages path:APIMethods, method:URLMethod, token : String?, headers:[String:String]?, parameters: [String:Any]?,imageNames : [String], images:[Data], completion: @escaping(Any?, Error?, Bool)->Void) { if !Reachability.isConnectedToNetwork() { DispatchQueue.main.async { showAlert(message: AppMessages.connectionFailed.rawValue) } dissmissHud() return } var stringUrl = "\(APIManager.url)\(APIMethods.preFix.rawValue)\(path.rawValue)" if method == .get, let lastPath = parameters?.values.first as? String { stringUrl += lastPath }else{ stringUrl += token ?? "" } // generate boundary string using a unique per-app string let boundary = UUID().uuidString let config = URLSessionConfiguration.default let session = URLSession(configuration: config) print("\n\ncomplete Url :-------------- ",stringUrl," \n\n-------------: complete Url") guard let url = URL(string: stringUrl) else { return } var request = URLRequest(url: url) request.httpMethod = method.rawValue if headers != nil{ print("\n\nHeaders :-------------- ",headers as Any,"\n\n --------------: Headers") for (key, value) in headers! { request.setValue(value, forHTTPHeaderField: key) } } // 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 request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") var data = Data() if parameters != nil{ for(key, value) in parameters!{ // Add the reqtype field and its value to the raw http request data data.append("\r\n--\(boundary)\r\n".data(using: .utf8)!) data.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!) data.append("\(value)".data(using: .utf8)!) } } for (index,imageData) in images.enumerated() { // 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=\"\(imageNames[index])\"; filename=\"\(imageNames[index])\"\r\n".data(using: .utf8)!) data.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!) data.append(imageData) } // End the raw http request data, note that there is 2 extra dash ("-") at the end, this is to indicate the end of the data 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: request, from: data, completionHandler: { data, response, error in if let checkResponse = response as? HTTPURLResponse{ if checkResponse.statusCode == 200{ guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: [JSONSerialization.ReadingOptions.allowFragments]) else { completion(nil, error, false) return } let jsonString = String(data: data, encoding: .utf8)! print("\n\n---------------------------\n\n"+jsonString+"\n\n---------------------------\n\n") print(json) completion(json, nil, true) }else{ guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) else { completion(nil, error, false) return } let jsonString = String(data: data, encoding: .utf8)! print("\n\n---------------------------\n\n"+jsonString+"\n\n---------------------------\n\n") print(json) completion(json, nil, false) } }else{ guard let data = data, let json = try? JSONSerialization.jsonObject(with: data, options: []) else { completion(nil, error, false) return } completion(json, nil, false) } }).resume()}extension Data { /// Append string to Data /// /// Rather than littering my code with calls to `data(using: .utf8)` to convert `String` values to `Data`, this wraps it in a nice convenient little extension to Data. This defaults to converting using UTF-8. /// /// - parameter string: The string to be added to the `Data`. mutating func append(_ string: String, using encoding: String.Encoding = .utf8) { if let data = string.data(using: encoding) { append(data) } }}