Related
Checkout the code for single image upload but not able to upload the multiple images in an array under same key.
IN BELOW CODE ,
It is working perfect when I am sending one image to the server.
-> I want to find answer for the multiple images in array without using alamofire or other third party library.
func imageUploadRequest(IMAGE_ARRAY: [UIImage] , uploadUrl: NSURL) {
myloader.showLoader(controller: self)
let param = ["title":"ds","category_id":"5","description":"gdfjghjdsfgksd","user_id":"66","color":"red"]
let request = NSMutableURLRequest(url:uploadUrl as URL)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
//let imageData = UIImageJPEGRepresentation(imageView.imageOrientation, 0.1)
for item in IMAGE_ARRAY
{
let imageData = item.jpegData(compressionQuality: 0.01)
if(imageData==nil) { return; }
request.httpBody = createBodyWithParameters(parameters: param as [String : Any], filePathKey: "files[]", cv : imageData! as NSData, boundary: boundary) as Data
}
// myActivityIndicator.startAnimating();
let task = URLSession.shared.dataTask(with: request as URLRequest,
completionHandler: {
(data, response, error) -> Void in
if let data = data {
DispatchQueue.main.async { // Update UI
self.myloader.removeLoader(controller: self)
let decoder = JSONDecoder()
let obj = try! decoder.decode(GetResponse_Otp.self, from: data)
}
}
})
task.resume()
}
func createBodyWithParameters(parameters: [String: Any]?, filePathKey: String?, cv: NSData, boundary: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
let filename = "\(Date().timeIntervalSince1970).jpeg"
let mimetype = "image/png"
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.append(cv as Data)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
// extension for impage uploading
}
You need to change your key name to KEY_NAME[] add array [] in your key and make sure every time the file name is different or you can try this too:
(Date().timeIntervalSince1970).jpeg
to make sure that the name is different everytime.
func imageUploadRequest(ARRAY_OF_IMAGES: [ANY] , uploadUrl: NSURL) {
myloader.showLoader(controller: self)
let param = ["user_id":fetchString(key: "userId"), "career_level":UnwarppingValue(value: btnCarrer.title(for: .normal)),"education":UnwarppingValue(value: btnEducation.title(for: .normal)),"cur_location":txtFldLocation.text!,"cur_position":txtFldCurrentPosition.text!,"cur_employee":txtFldCurrentEmployee.text!,"experience": UnwarppingValue(value: btnExperience.title(for: .normal)),"industry":UnwarppingValue(value: btnIndustry.title(for: .normal))] as [String : Any]
let request = NSMutableURLRequest(url:uploadUrl as URL)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
//let imageData = UIImageJPEGRepresentation(imageView.imageOrientation, 0.1)
for item in IMAGE_ARRAY
{
let imageData = item.jpegData(compressionQuality: 0.01)
if(imageData==nil) { return; }
request.httpBody = createBodyWithParameters(parameters: param as [String : Any], filePathKey: "KEY_NAME[]", cv : imageData! as NSData, boundary: boundary) as Data
}
// myActivityIndicator.startAnimating();
let task = URLSession.shared.dataTask(with: request as URLRequest,
completionHandler: {
(data, response, error) -> Void in
if let data = data {
DispatchQueue.main.async { // Update UI
self.myloader.removeLoader(controller: self)
let decoder = JSONDecoder()
let obj = try! decoder.decode(GetResponse_ProfileOverViewDetails.self, from: data)
guard obj.response?.result == "1" else{
showToast(message: obj.response?.msg ?? "Something Went Wrong", vc: self, normalColor: false)
return
}
if let userPic = obj.response?.data?[0].pic {
saveStringInDefault(value: userPic, key: "userPic")
}else {
saveStringInDefault(value: "", key: "userPic")
}
showToast(message: obj.response?.msg ?? "Something Went Wrong", vc: self, normalColor: false)
}
}
})task.resume()
}
func createBodyWithParameters(parameters: [String: Any]?, filePathKey: String?, cv: NSData, boundary: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString(string: "\(value)\r\n")
}
}
let filename = HERE->(Date().timeIntervalSince1970).jpeg
let mimetype = "image/png"
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(cv as Data)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
// extension for impage uploading
}
Check i edit the code in caps.
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
You could use URLSession to upload a multipart/form-data
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()
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))"
}
}
Data extension
extension NSMutableData {
func appendString(_ string: String) {
if let data = string.data(using: String.Encoding.utf8,
allowLossyConversion: true) {
append(data)
}
}
}
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)!)
}
i am new in ios. i did like that but i am getting response from server "Required MultipartFIle" Parameter 'file' is not present.
1) addUser method i am calling inside my button event.
func addUser(completion: (message: String?, error: String?) -> Void) -> NSURLSessionDataTask {
// create the request method called here
let request = createRequest()
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if error != nil{
print("#----->response",response)
return// 400 Error is printed here
}
do {
if let responseDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("responseDictionary == \(responseDictionary)")
}
} catch {
print(error)
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
}
task.resume()
return task
}
func createRequest () -> NSURLRequest {
let param = [
"clientName" : self.projectClientNameField.text!,
"clientAddress" : self.projectAddressField.text!,
"clientNumber" : self.projectClientContactField.text!,
"projectName" : self.projectNameField.text!,
"projectDesc" : self.projectDetailsField.text!,
"startDate" : "",
"endDate" : "",
]
let boundary = generateBoundaryString()
let url = NSURL(string: "MYURL")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.setValue("*/*", forHTTPHeaderField: "Accept")
request.setValue("100-continue", forHTTPHeaderField: "Expect")
//request.setValue("image/jpeg", forHTTPHeaderField: "Content-Type")
let imageData = UIImagePNGRepresentation(image.image!)
if imageData==nil{
print("#-->imageData",imageData)
}
request.HTTPBody = createBodyWithParameters(param, imageDataKey: imageData!, boundary: boundary)
print("request -->",request)
NSLog("%#", [request]);
return request
}
func createBodyWithParameters(json: [String:AnyObject], imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData()
let key = "project"
body.appendString("--\(boundary)\r\n")
// body.appendString("Content-Type: application/json")
body.appendString("Content-Disposition: form-data; name = \"\(key)\"\r\n\r\n")
var requestBody = NSData()
do {
requestBody = try NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions(rawValue:0))
print("#--->",requestBody)
} catch (let e) {
print(e)
}
body.appendData(requestBody)
let mimetype = "image/png"
let fileName = "suppliers.png"
let name = "file"
//body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"file\"; file=\"\(fileName)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(imageDataKey)
body.appendString("\r\n")
print(body)
body.appendString("--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "------------------------\(NSUUID().UUIDString)"
}
response for server is :
{
error = "Bad Request";
exception = "org.springframework.web.bind.MissingServletRequestParameterException";
message = "Required MultipartFile parameter 'file' is not present";
path = "/project/create";
status = 400;
timestamp = 1468475579881;
}
can anybody please resolve this??
Here is full code to upload images(you can use multiple images)to upload on server.
You can use below method.
You have to just pass paramDictionary and URL.
func createBodyWithParameters(parameters: NSMutableDictionary?,boundary: String) -> NSData {
let body = NSMutableData()
if parameters != nil {
for (key, value) in parameters! {
if(value is String || value is NSString){
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
else if(value is [UIImage]){
var i = 0;
for image in value as! [UIImage]{
let filename = "image\(i).jpg"
let data = UIImageJPEGRepresentation(image,1);
let mimetype = mimeTypeForPath(filename)
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(data!)
body.appendString("\r\n")
i++;
}
}
}
}
body.appendString("--\(boundary)--\r\n")
// NSLog("data %#",NSString(data: body, encoding: NSUTF8StringEncoding)!);
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
func mimeTypeForPath(path: String) -> String {
let pathExtension = path.pathExtension
var stringMimeType = "application/octet-stream";
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension!, nil)?.takeRetainedValue() {
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
stringMimeType = mimetype as NSString as String
}
}
return stringMimeType;
}
func createRequest (param : NSMutableDictionary , strURL : String) -> NSURLRequest {
let boundary = generateBoundaryString()
let url = NSURL(string: strURL)
let request = NSMutableURLRequest(URL: url!)
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = createBodyWithParameters(param, boundary: boundary)
return request
}
It won't work, how to send an image from an iOS Swift app to my PHP server?
#IBAction func upload(sender: UIButton) {
var imageData = UIImageJPEGRepresentation(img.image, 90)
// println(imageData)
let url = NSURL(string:"http://www.i35.club.tw/old_tree/test/uplo.php")
//let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
//var request = NSMutableURLRequest(URL: url, cachePolicy: cachePolicy, timeoutInterval: 10)
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// set Content-Type in HTTP header
let boundaryConstant = "----------V2ymHFg03esomerandomstuffhbqgZCaKO6jy";
let contentType = "multipart/form-data; boundary=" + boundaryConstant
NSURLProtocol.setProperty(contentType, forKey: "Content-Type", inRequest: request)
request.HTTPBody = imageData
// set data
//var dataString = "adkjlkajfdadf"
//let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
//request.HTTPBody = requestBodyData
//
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.addValue("multipart/form-data", forHTTPHeaderField: "Accept")
//
// set content length
//NSURLProtocol.setProperty(requestBodyData.length, forKey: "Content-Length", inRequest: request)
var response: NSURLResponse? = nil
var error: NSError? = nil
let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)
let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
println("API Response: \(results)")
}
//take photo
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {
var selectedImage : UIImage = image
img.image = selectedImage
UIImageWriteToSavedPhotosAlbum(selectedImage, nil, nil, nil)
self.dismissViewControllerAnimated(true, completion: nil)
}
I have taken the photo by user's choice and written code for swift 2 and iOS9
func imageUploadRequest(imageView imageView: UIImageView, uploadUrl: NSURL, param: [String:String]?) {
//let myUrl = NSURL(string: "http://192.168.1.103/upload.photo/index.php");
let request = NSMutableURLRequest(URL:uploadUrl);
request.HTTPMethod = "POST"
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(imageView.image!, 1)
if(imageData==nil) { return; }
request.HTTPBody = createBodyWithParameters(param, filePathKey: "file", imageDataKey: imageData!, boundary: boundary)
//myActivityIndicator.startAnimating();
let task = NSURLSession.sharedSession().dataTaskWithRequest(request,
completionHandler: {
(data, response, error) -> Void in
if let data = data {
// You can print out response object
print("******* response = \(response)")
print(data.length)
// you can use data here
// Print out reponse body
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
print("****** response data = \(responseString!)")
let json = try!NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as? NSDictionary
print("json value \(json)")
//var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err)
dispatch_async(dispatch_get_main_queue(),{
//self.myActivityIndicator.stopAnimating()
//self.imageView.image = nil;
});
} else if let error = error {
print(error.description)
}
})
task.resume()
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
let filename = "user-profile.jpg"
let mimetype = "image/jpg"
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(imageDataKey)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
}// extension for impage uploading
extension NSMutableData {
func appendString(string: String) {
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
appendData(data!)
}
}
--------- following code for the php side
<?php
$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$userId = $_POST["userId"];
$target_dir = "media";
if(!file_exists($target_dir))
{
mkdir($target_dir, 0777, true);
}
$target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir))
{
echo json_encode([
"Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
"Status" => "OK",
"userId" => $_REQUEST["userId"]
]);
} else {
echo json_encode([
"Message" => "Sorry, there was an error uploading your file.",
"Status" => "Error",
"userId" => $_REQUEST["userId"]
]);
}
To upload image with parameters use this code,
// Your method to upload image with parameters to server.
func uploadImageOne(){
var imageData = UIImagePNGRepresentation(imageView.image)
if imageData != nil{
var request = NSMutableURLRequest(URL: NSURL(string:"Enter Your URL")!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var boundary = NSString(format: "---------------------------14737809831466499882746641449")
var contentType = NSString(format: "multipart/form-data; boundary=%#",boundary)
// println("Content Type \(contentType)")
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
var body = NSMutableData.alloc()
// Title
body.appendData(NSString(format: "\r\n--%#\r\n",boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format:"Content-Disposition: form-data; name=\"title\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Hello World".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
// Image
body.appendData(NSString(format: "\r\n--%#\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"img.jpg\"\\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData)
body.appendData(NSString(format: "\r\n--%#\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding)
println("returnString \(returnString)")
}
}
My updated code for Swift 3
func uploadImage() {
let url = URL(string: "YOUR SERVER URL");
let request = NSMutableURLRequest(url: url!);
request.httpMethod = "POST"
let boundary = "Boundary-\(NSUUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var retreivedImage: UIImage? = nil
//Get image
do {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let readData = try Data(contentsOf: URL(string: "file://\(documentsPath)/myImage")!)
retreivedImage = UIImage(data: readData)
addProfilePicView.setImage(retreivedImage, for: .normal)
}
catch {
print("Error while opening image")
return
}
let imageData = UIImageJPEGRepresentation(retreivedImage!, 1)
if (imageData == nil) {
print("UIImageJPEGRepresentation return nil")
return
}
let body = NSMutableData()
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Disposition: form-data; name=\"api_token\"\r\n\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: (UserDefaults.standard.string(forKey: "api_token")! as NSString)).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"testfromios.jpg\"\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(imageData!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
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 what you want in success case
} else if let error = error {
print(error.localizedDescription)
}
})
task.resume()
}
And PHP side code you can take from #VinodJoshi answer.
According to the blogpost of Sergey Kargopolov (http://swiftdeveloperblog.com/image-upload-example/) and his video (https://youtu.be/HqxeyS961Uk) here is my code that worked perfectly in Swift 5.
It will upload a picture to the directory specified in the php script (further down) and it will name the picture according to the imgKey given. In my example, it will upload the imageToUpload of myImageUploadRequest to the directory "wp-content/Images". The param dictionary is not necessarily needed. This could very well be written more efficiently but maybe it is a start for someone :)
func myImageUploadRequest(imageToUpload: UIImage, imgKey: String) {
let myUrl = NSURL(string: "https://yourdomain/uploadPicture.php");
let request = NSMutableURLRequest(url:myUrl! as URL);
request.httpMethod = "POST";
let param = [
"firstName" : "name",
"lastName" : "name",
"userId" : "42"
]
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = imageToUpload.jpegData(compressionQuality: 1)
if imageData == nil {
return
}
request.httpBody = createBodyWithParameters(parameters: param, filePathKey: "file", imageDataKey: imageData! as NSData, boundary: boundary, imgKey: imgKey) as Data
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error!)")
return
}
//print response
//print("response = \(response!)")
// print reponse body
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("response data = \(responseString!)")
}
task.resume()
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String, imgKey: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString(string: "\(value)\r\n")
}
}
let filename = "\(imgKey).jpg"
let mimetype = "image/jpg"
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey as Data)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
}
extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
The server sided php (PHP/7.3.18) code:
<?php
$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$userId = $_POST["userId"];
$target_dir = "wp-content/Images";
if (!file_exists($target_dir)) {
mkdir($target_dir, 0777, true);
}
$target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)) {
echo json_encode([
"Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
"Status" => "OK",
"userId" => $_REQUEST["userId"]
]);
}
else {
echo json_encode([
"Message" => "Sorry, there was an error uploading your file.",
"Status" => "Error",
"userId" => $_REQUEST["userId"]
]);
}
?>
Example console output:
response data = {
"Message":"The file 9B862D73-9F0B-4DD3-8FBB-452AEF2FE1CF.jpg has been uploaded.",
"Status":"OK",
"userId":"17"}
I have made function for Block method which is easy to use and this is class function so you can use anywhere in your project for example make
MVCServer.swift
NSObject class and
import Alamofire
and then write this function in this class
func postImageRequestWithURL(withUrl strURL: String,withParam postParam: Dictionary<String, Any>,withImages imageArray:NSMutableArray,completion:#escaping (_ isSuccess: Bool, _ response:NSDictionary) -> Void)
{
Alamofire.upload(multipartFormData: { (MultipartFormData) in
// Here is your Image Array
for (imageDic) in imageArray
{
let imageDic = imageDic as! NSDictionary
for (key,valus) in imageDic
{
MultipartFormData.append(valus as! Data, withName:key as! String,fileName: "file.jpg", mimeType: "image/jpg")
}
}
// Here is your Post paramaters
for (key, value) in postParam
{
MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, usingThreshold: UInt64.init(), to: strURL, method: .post) { (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
if response.response?.statusCode == 200
{
let json = response.result.value as? NSDictionary
completion(true,json!);
}
else
{
completion(false,[:]);
}
}
case .failure(let encodingError):
print(encodingError)
completion(false,[:]);
}
}
}
Now Call this Function
var ImageArray : NSMutableArray!
// Here is your post parameter
var parameters: [String:Any] = ["user_master_id" : “56”,
"first_name": “Jignesh”,
"last_name" : “Mayani”,
"email": “TestEmail#gmail.com”]
// Here is your image is in DATA formate don’t send as UIImage formate
let ImageDic = ["profile_image" : imageData!]
// Here you can pass multiple image in array i am passing just one
ImageArray = NSMutableArray(array: [ImageDic as NSDictionary])
MVCServer().postImageRequestWithURL(withUrl: "write Your URL here", withParam: parameters, withImages: ImageArray) { (isSuccess, response) in
// Your Will Get Response here
}
I would recommend to take a look at: https://github.com/sraj/Swift-SRWebClient
Sample function that worked for me:
func uploadImage(image:UIImage) {
let imageData:NSData = UIImageJPEGRepresentation(image, 100)
SRWebClient.POST("http://www.example.com/upload/")
.data(imageData, fieldName:"photo", data: ["foo":"bar","baz":"qux"])
.send({(response:AnyObject!, status:Int) -> Void in
// process success response
},failure:{(error:NSError!) -> Void in
// process failure response
})
}
You’ll notice that the above code is a slightly adjusted version of the snippets on the Swift-SRWebClient Github page. I’ve replaced NSData.dataWithData with UIImageJPEGRepresentation as the former is deprecated.
Also, don’t forget to drag SRWebClient.swift into your project folder, otherwise this won’t work :)
#IBAction func upload(sender: UIButton) {
var imageData = UIImageJPEGRepresentation(img.image, 90)
var url = NSURL(string: "http://www.i35.club.tw/old_tree/test/uplo.php")
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(imageData))
var response: NSURLResponse? = nil
var error: NSError? = nil
let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
let results = NSString(data: reply!, encoding: NSUTF8StringEncoding)
println("API Response: \(results)")
}
Refer this link
This is great, I've been trying to pass an image using REST for a while and coouldn't format it just right and kept getting timeout errors. Using createBodyWithParameters I was able to make it work.
Here's the Swift 3 version of the code:
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: UIImage, boundary: String) -> Data {
var body = Data();
if parameters != nil {
for (key, value) in parameters! {
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(value)\r\n".data(using: String.Encoding.utf8)!)
}
}
let filename = "user-profile.jpg"
let mimetype = "image/jpg"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(UIImageJPEGRepresentation(imageDataKey, 1)!)
//body.appendData(imageDataKey)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
return body
}
Just look on that simple explanation:
Form data and multipart uploads with URLRequest
Also, to keep code up to date you can replace NSMutableData on Data. So your final code will be looks like:
func createHttpBody(parameters: [String: String]? = nil, _ boundary: String, data: Data, mimeType: String, filename: String) -> Data {
var body = Data()
let boundaryPrefix = "--\(boundary)\r\n"
if let parameters = parameters {
for (key, value) in parameters {
body.append(boundaryPrefix)
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
}
}
body.append(boundaryPrefix)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(mimeType)\r\n\r\n")
body.append(data)
body.append("\r\n")
body.append("--".appending(boundary.appending("--")))
return body
}
And updated extension for Data to use append method:
extension Data {
mutating func append(_ string: String) {
if let data = string.data(using: .utf8) {
append(data)
}
}
}
Also you can check this video tutorial and check source code for that tutorial.
In swift 4.1 and Xcode 9.4.1
See my Code in this blog for Upload image to server in Swift
https://markingios.blogspot.com/2018/09/upload-image-to-server-in-swift.html
Call this function like : uploadImage()
func uploadImage(){
let imageData = UIImageJPEGRepresentation(yourImage!, 1.0)//Replace your image
if imageData != nil{
var request = URLRequest(url: NSURL(string:urlString)! as URL)//Send your URL here
print(request)
request.httpMethod = "POST"
let boundary = NSString(format: "---------------------------14737809831466499882746641449")
let contentType = NSString(format: "multipart/form-data; boundary=%#",boundary)
// println("Content Type \(contentType)")
request.addValue(contentType as String, forHTTPHeaderField: "Content-Type")
var body = Data()
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data;name=\"title\"\r\n\r\n").data
(using:String.Encoding.utf8.rawValue)!)
body.append("Hello".data(using: String.Encoding.utf8, allowLossyConversion: true)!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data;name=\"uploaded_file\";filename=\"image.jpg\"\\r\n").data
(using:String.Encoding.utf8.rawValue)!) //Here replace your image name and file name
body.append(NSString(format: "Content-Type: image/jpeg\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(imageData!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
request.httpBody = body
let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil
else { // check for fundamental networking error
print("error=\(String(describing: error))")
SharedClass.sharedInstance.alert(view: self, message: "\(String(describing: error!.localizedDescription))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 500 {
SharedClass.sharedInstance.alert(view: self, message: "Server Error")
} else if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
//This can print your response in string formate
let responseString = String(data: data, encoding: .utf8)
// let dictionary = data
// print("dictionary = \(dictionary)")
print("responseString = \(String(describing: responseString!))")
do {
self.response3 = (try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject])!
print(self.response3)
if (((self.response3["Response"] as? [String : Any])?["status"]) as! String == "SUCCESS") {
let message = (self.response3["Response"] as? [String : Any])?["message"] as? String
SharedClass.sharedInstance.alert(view:self, message: message)
} else {
let message = (self.response3["Response"] as? [String : Any])?["message"] as? String
SharedClass.sharedInstance.alert(view:self, message: message)
}
} catch let error as NSError {
print(error)
print(error.localizedDescription)
}
}
task.resume()
}
}
request.httpMethod = "POST" is important for upload long string or blob
func imageUpload(imageData:String){
var request:NSMutableURLRequest!
let param:String = "image=\(imageData)" // image data should be here
request = NSMutableURLRequest(url: URL(string: "www.pickmyoffers.com")!)// use your upload php file link and parameter "example.com/upload.php?image=\(imageData)"
request.httpMethod = "POST"
request.httpBody = param.data(using: String.Encoding.utf8)
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {data,response,error in
if error != nil {
print("error=\(error)")
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(responseString!)
}
task.resume()
}
It won't work, how to send an image from an iOS Swift app to my PHP server?
#IBAction func upload(sender: UIButton) {
var imageData = UIImageJPEGRepresentation(img.image, 90)
// println(imageData)
let url = NSURL(string:"http://www.i35.club.tw/old_tree/test/uplo.php")
//let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
//var request = NSMutableURLRequest(URL: url, cachePolicy: cachePolicy, timeoutInterval: 10)
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// set Content-Type in HTTP header
let boundaryConstant = "----------V2ymHFg03esomerandomstuffhbqgZCaKO6jy";
let contentType = "multipart/form-data; boundary=" + boundaryConstant
NSURLProtocol.setProperty(contentType, forKey: "Content-Type", inRequest: request)
request.HTTPBody = imageData
// set data
//var dataString = "adkjlkajfdadf"
//let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
//request.HTTPBody = requestBodyData
//
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.addValue("multipart/form-data", forHTTPHeaderField: "Accept")
//
// set content length
//NSURLProtocol.setProperty(requestBodyData.length, forKey: "Content-Length", inRequest: request)
var response: NSURLResponse? = nil
var error: NSError? = nil
let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)
let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
println("API Response: \(results)")
}
//take photo
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image: UIImage!, editingInfo: NSDictionary!) {
var selectedImage : UIImage = image
img.image = selectedImage
UIImageWriteToSavedPhotosAlbum(selectedImage, nil, nil, nil)
self.dismissViewControllerAnimated(true, completion: nil)
}
I have taken the photo by user's choice and written code for swift 2 and iOS9
func imageUploadRequest(imageView imageView: UIImageView, uploadUrl: NSURL, param: [String:String]?) {
//let myUrl = NSURL(string: "http://192.168.1.103/upload.photo/index.php");
let request = NSMutableURLRequest(URL:uploadUrl);
request.HTTPMethod = "POST"
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(imageView.image!, 1)
if(imageData==nil) { return; }
request.HTTPBody = createBodyWithParameters(param, filePathKey: "file", imageDataKey: imageData!, boundary: boundary)
//myActivityIndicator.startAnimating();
let task = NSURLSession.sharedSession().dataTaskWithRequest(request,
completionHandler: {
(data, response, error) -> Void in
if let data = data {
// You can print out response object
print("******* response = \(response)")
print(data.length)
// you can use data here
// Print out reponse body
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
print("****** response data = \(responseString!)")
let json = try!NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as? NSDictionary
print("json value \(json)")
//var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err)
dispatch_async(dispatch_get_main_queue(),{
//self.myActivityIndicator.stopAnimating()
//self.imageView.image = nil;
});
} else if let error = error {
print(error.description)
}
})
task.resume()
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString("\(value)\r\n")
}
}
let filename = "user-profile.jpg"
let mimetype = "image/jpg"
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.appendData(imageDataKey)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
}// extension for impage uploading
extension NSMutableData {
func appendString(string: String) {
let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
appendData(data!)
}
}
--------- following code for the php side
<?php
$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$userId = $_POST["userId"];
$target_dir = "media";
if(!file_exists($target_dir))
{
mkdir($target_dir, 0777, true);
}
$target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir))
{
echo json_encode([
"Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
"Status" => "OK",
"userId" => $_REQUEST["userId"]
]);
} else {
echo json_encode([
"Message" => "Sorry, there was an error uploading your file.",
"Status" => "Error",
"userId" => $_REQUEST["userId"]
]);
}
To upload image with parameters use this code,
// Your method to upload image with parameters to server.
func uploadImageOne(){
var imageData = UIImagePNGRepresentation(imageView.image)
if imageData != nil{
var request = NSMutableURLRequest(URL: NSURL(string:"Enter Your URL")!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var boundary = NSString(format: "---------------------------14737809831466499882746641449")
var contentType = NSString(format: "multipart/form-data; boundary=%#",boundary)
// println("Content Type \(contentType)")
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
var body = NSMutableData.alloc()
// Title
body.appendData(NSString(format: "\r\n--%#\r\n",boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format:"Content-Disposition: form-data; name=\"title\"\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Hello World".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
// Image
body.appendData(NSString(format: "\r\n--%#\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"img.jpg\"\\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData)
body.appendData(NSString(format: "\r\n--%#\r\n", boundary).dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding)
println("returnString \(returnString)")
}
}
My updated code for Swift 3
func uploadImage() {
let url = URL(string: "YOUR SERVER URL");
let request = NSMutableURLRequest(url: url!);
request.httpMethod = "POST"
let boundary = "Boundary-\(NSUUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var retreivedImage: UIImage? = nil
//Get image
do {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let readData = try Data(contentsOf: URL(string: "file://\(documentsPath)/myImage")!)
retreivedImage = UIImage(data: readData)
addProfilePicView.setImage(retreivedImage, for: .normal)
}
catch {
print("Error while opening image")
return
}
let imageData = UIImageJPEGRepresentation(retreivedImage!, 1)
if (imageData == nil) {
print("UIImageJPEGRepresentation return nil")
return
}
let body = NSMutableData()
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Disposition: form-data; name=\"api_token\"\r\n\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: (UserDefaults.standard.string(forKey: "api_token")! as NSString)).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data; name=\"profile_img\"; filename=\"testfromios.jpg\"\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(imageData!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
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 what you want in success case
} else if let error = error {
print(error.localizedDescription)
}
})
task.resume()
}
And PHP side code you can take from #VinodJoshi answer.
According to the blogpost of Sergey Kargopolov (http://swiftdeveloperblog.com/image-upload-example/) and his video (https://youtu.be/HqxeyS961Uk) here is my code that worked perfectly in Swift 5.
It will upload a picture to the directory specified in the php script (further down) and it will name the picture according to the imgKey given. In my example, it will upload the imageToUpload of myImageUploadRequest to the directory "wp-content/Images". The param dictionary is not necessarily needed. This could very well be written more efficiently but maybe it is a start for someone :)
func myImageUploadRequest(imageToUpload: UIImage, imgKey: String) {
let myUrl = NSURL(string: "https://yourdomain/uploadPicture.php");
let request = NSMutableURLRequest(url:myUrl! as URL);
request.httpMethod = "POST";
let param = [
"firstName" : "name",
"lastName" : "name",
"userId" : "42"
]
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = imageToUpload.jpegData(compressionQuality: 1)
if imageData == nil {
return
}
request.httpBody = createBodyWithParameters(parameters: param, filePathKey: "file", imageDataKey: imageData! as NSData, boundary: boundary, imgKey: imgKey) as Data
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error!)")
return
}
//print response
//print("response = \(response!)")
// print reponse body
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("response data = \(responseString!)")
}
task.resume()
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String, imgKey: String) -> NSData {
let body = NSMutableData();
if parameters != nil {
for (key, value) in parameters! {
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString(string: "\(value)\r\n")
}
}
let filename = "\(imgKey).jpg"
let mimetype = "image/jpg"
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey as Data)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
}
extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
The server sided php (PHP/7.3.18) code:
<?php
$firstName = $_POST["firstName"];
$lastName = $_POST["lastName"];
$userId = $_POST["userId"];
$target_dir = "wp-content/Images";
if (!file_exists($target_dir)) {
mkdir($target_dir, 0777, true);
}
$target_dir = $target_dir . "/" . basename($_FILES["file"]["name"]);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_dir)) {
echo json_encode([
"Message" => "The file ". basename( $_FILES["file"]["name"]). " has been uploaded.",
"Status" => "OK",
"userId" => $_REQUEST["userId"]
]);
}
else {
echo json_encode([
"Message" => "Sorry, there was an error uploading your file.",
"Status" => "Error",
"userId" => $_REQUEST["userId"]
]);
}
?>
Example console output:
response data = {
"Message":"The file 9B862D73-9F0B-4DD3-8FBB-452AEF2FE1CF.jpg has been uploaded.",
"Status":"OK",
"userId":"17"}
I have made function for Block method which is easy to use and this is class function so you can use anywhere in your project for example make
MVCServer.swift
NSObject class and
import Alamofire
and then write this function in this class
func postImageRequestWithURL(withUrl strURL: String,withParam postParam: Dictionary<String, Any>,withImages imageArray:NSMutableArray,completion:#escaping (_ isSuccess: Bool, _ response:NSDictionary) -> Void)
{
Alamofire.upload(multipartFormData: { (MultipartFormData) in
// Here is your Image Array
for (imageDic) in imageArray
{
let imageDic = imageDic as! NSDictionary
for (key,valus) in imageDic
{
MultipartFormData.append(valus as! Data, withName:key as! String,fileName: "file.jpg", mimeType: "image/jpg")
}
}
// Here is your Post paramaters
for (key, value) in postParam
{
MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, usingThreshold: UInt64.init(), to: strURL, method: .post) { (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
if response.response?.statusCode == 200
{
let json = response.result.value as? NSDictionary
completion(true,json!);
}
else
{
completion(false,[:]);
}
}
case .failure(let encodingError):
print(encodingError)
completion(false,[:]);
}
}
}
Now Call this Function
var ImageArray : NSMutableArray!
// Here is your post parameter
var parameters: [String:Any] = ["user_master_id" : “56”,
"first_name": “Jignesh”,
"last_name" : “Mayani”,
"email": “TestEmail#gmail.com”]
// Here is your image is in DATA formate don’t send as UIImage formate
let ImageDic = ["profile_image" : imageData!]
// Here you can pass multiple image in array i am passing just one
ImageArray = NSMutableArray(array: [ImageDic as NSDictionary])
MVCServer().postImageRequestWithURL(withUrl: "write Your URL here", withParam: parameters, withImages: ImageArray) { (isSuccess, response) in
// Your Will Get Response here
}
I would recommend to take a look at: https://github.com/sraj/Swift-SRWebClient
Sample function that worked for me:
func uploadImage(image:UIImage) {
let imageData:NSData = UIImageJPEGRepresentation(image, 100)
SRWebClient.POST("http://www.example.com/upload/")
.data(imageData, fieldName:"photo", data: ["foo":"bar","baz":"qux"])
.send({(response:AnyObject!, status:Int) -> Void in
// process success response
},failure:{(error:NSError!) -> Void in
// process failure response
})
}
You’ll notice that the above code is a slightly adjusted version of the snippets on the Swift-SRWebClient Github page. I’ve replaced NSData.dataWithData with UIImageJPEGRepresentation as the former is deprecated.
Also, don’t forget to drag SRWebClient.swift into your project folder, otherwise this won’t work :)
#IBAction func upload(sender: UIButton) {
var imageData = UIImageJPEGRepresentation(img.image, 90)
var url = NSURL(string: "http://www.i35.club.tw/old_tree/test/uplo.php")
var request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = NSData.dataWithData(UIImagePNGRepresentation(imageData))
var response: NSURLResponse? = nil
var error: NSError? = nil
let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
let results = NSString(data: reply!, encoding: NSUTF8StringEncoding)
println("API Response: \(results)")
}
Refer this link
This is great, I've been trying to pass an image using REST for a while and coouldn't format it just right and kept getting timeout errors. Using createBodyWithParameters I was able to make it work.
Here's the Swift 3 version of the code:
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: UIImage, boundary: String) -> Data {
var body = Data();
if parameters != nil {
for (key, value) in parameters! {
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(value)\r\n".data(using: String.Encoding.utf8)!)
}
}
let filename = "user-profile.jpg"
let mimetype = "image/jpg"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(UIImageJPEGRepresentation(imageDataKey, 1)!)
//body.appendData(imageDataKey)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
return body
}
Just look on that simple explanation:
Form data and multipart uploads with URLRequest
Also, to keep code up to date you can replace NSMutableData on Data. So your final code will be looks like:
func createHttpBody(parameters: [String: String]? = nil, _ boundary: String, data: Data, mimeType: String, filename: String) -> Data {
var body = Data()
let boundaryPrefix = "--\(boundary)\r\n"
if let parameters = parameters {
for (key, value) in parameters {
body.append(boundaryPrefix)
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
}
}
body.append(boundaryPrefix)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(mimeType)\r\n\r\n")
body.append(data)
body.append("\r\n")
body.append("--".appending(boundary.appending("--")))
return body
}
And updated extension for Data to use append method:
extension Data {
mutating func append(_ string: String) {
if let data = string.data(using: .utf8) {
append(data)
}
}
}
Also you can check this video tutorial and check source code for that tutorial.
In swift 4.1 and Xcode 9.4.1
See my Code in this blog for Upload image to server in Swift
https://markingios.blogspot.com/2018/09/upload-image-to-server-in-swift.html
Call this function like : uploadImage()
func uploadImage(){
let imageData = UIImageJPEGRepresentation(yourImage!, 1.0)//Replace your image
if imageData != nil{
var request = URLRequest(url: NSURL(string:urlString)! as URL)//Send your URL here
print(request)
request.httpMethod = "POST"
let boundary = NSString(format: "---------------------------14737809831466499882746641449")
let contentType = NSString(format: "multipart/form-data; boundary=%#",boundary)
// println("Content Type \(contentType)")
request.addValue(contentType as String, forHTTPHeaderField: "Content-Type")
var body = Data()
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data;name=\"title\"\r\n\r\n").data
(using:String.Encoding.utf8.rawValue)!)
body.append("Hello".data(using: String.Encoding.utf8, allowLossyConversion: true)!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data;name=\"uploaded_file\";filename=\"image.jpg\"\\r\n").data
(using:String.Encoding.utf8.rawValue)!) //Here replace your image name and file name
body.append(NSString(format: "Content-Type: image/jpeg\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(imageData!)
body.append(NSString(format: "\r\n--%#\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
request.httpBody = body
let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil
else { // check for fundamental networking error
print("error=\(String(describing: error))")
SharedClass.sharedInstance.alert(view: self, message: "\(String(describing: error!.localizedDescription))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 500 {
SharedClass.sharedInstance.alert(view: self, message: "Server Error")
} else if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
//This can print your response in string formate
let responseString = String(data: data, encoding: .utf8)
// let dictionary = data
// print("dictionary = \(dictionary)")
print("responseString = \(String(describing: responseString!))")
do {
self.response3 = (try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject])!
print(self.response3)
if (((self.response3["Response"] as? [String : Any])?["status"]) as! String == "SUCCESS") {
let message = (self.response3["Response"] as? [String : Any])?["message"] as? String
SharedClass.sharedInstance.alert(view:self, message: message)
} else {
let message = (self.response3["Response"] as? [String : Any])?["message"] as? String
SharedClass.sharedInstance.alert(view:self, message: message)
}
} catch let error as NSError {
print(error)
print(error.localizedDescription)
}
}
task.resume()
}
}
request.httpMethod = "POST" is important for upload long string or blob
func imageUpload(imageData:String){
var request:NSMutableURLRequest!
let param:String = "image=\(imageData)" // image data should be here
request = NSMutableURLRequest(url: URL(string: "www.pickmyoffers.com")!)// use your upload php file link and parameter "example.com/upload.php?image=\(imageData)"
request.httpMethod = "POST"
request.httpBody = param.data(using: String.Encoding.utf8)
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {data,response,error in
if error != nil {
print("error=\(error)")
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(responseString!)
}
task.resume()
}