Related
I need to send POST request to the server and these are the parameters
let params : NSDictionary = ["userid":"\(userID)","sessionid":"\(sessionID)","site_id": "\(siteIDParam)", "latitude":"\(currentlatitude)", "longitude":"\(currentlongitude)", "action": "1", "comments":commentTextView.text ?? ""]
But the problem is I need to send image as byte array and i am using the following code (Swift 3)
func uploadImageRequest(image: UIImage? , urlString: String, imageName : String ,param: [String: AnyObject]? , completion:#escaping(_ success:Bool , _ object : AnyObject?) -> ())
{
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
if (image == nil)
{
return
}
let image_data = UIImageJPEGRepresentation(image!, 0.5)
if(image_data == nil)
{
return
}
let body = NSMutableData()
let fname = "photo.png"
let mimetype = "image/*"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"\(imageName)\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(image_data!)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
if param != nil {
for (key, value) in param! {
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
}
}
request.httpBody = body as Data
_ = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
if let data = data {
// Json Response
let json = try? JSONSerialization.jsonObject(with: data, options: [])
// response.
if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
completion(true, json as AnyObject?)
} else {
completion(false, json as AnyObject?)
}
} else {
completion(false, error?.localizedDescription as AnyObject?)
}
}.resume()
}
The image is not converted properly I guess so that the response get failed when triggered and I am getting the following error
Message = "No HTTP resource was found that matches the request URI
This API works fine in Android device but it cant be achievied in iOS. I have searched all the links and I couldnt get a proper solution for this. I have also tried using Alamofire but still I got the same error.
You have to set the NSAllowsArbitraryLoads key to YES under NSAppTransportSecurity dictionary in your .plist file.
You can do this easily using alamofire, use the following code to do these things done.
let multipartHeaders = ["Content-Type":"multipart/form-data"]
let paramString: String = "parameters in json string..."
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(paramString.data(using: .utf8)!, withName: "json")
multipartFormData.append(<imageDataHere>, withName: "myimage", fileName: "myImage.jpeg", mimeType: "image
jpeg")
}, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to: url, method: .post, headers:
multipartHeader) { (encodingResult) in
switch encodingResult {
case .success(let request, _, _):
request.responseJSON(completionHandler: { (response) in
print(response)
})
case .failure(let error):
print(error.localizedDescription)
}
}
This piece of code helped me solve my problem. I just send my image as a file and remaining parameters as a string without appending it to my multipart body.
let imageData = UIImageJPEGRepresentation(userImage, 0.2)!
let docDir = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let imageURL = docDir.appendingPathComponent("tmp.jpg")
try! imageData.write(to: imageURL)
let multipartHeaders = ["Content-Type":"multipart/form-data"]
let paramString: String = "userid=\(userId)&action=1"
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageURL, withName: "profilepic")
}, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to: URL(string: ATTENDANCE_URL+paramString)!, method: .post, headers:
multipartHeaders) { (encodingResult) in
switch encodingResult {
case .success(let request, _, _):
request.responseJSON(completionHandler: { (response) in
print(response.result.value)
let value = response.result.value as! [String: Any]
})
case .failure(let error):
print(error.localizedDescription)
}
}
Below is my code referring this question answer
func createRequest(ResumeID: String, CandidateID: String, MediaName: String, FileExtension : String, MediaType : String) throws -> URLRequest {
let parameters = NSDictionary(objects: [ResumeID, CandidateID, MediaName, FileExtension,MediaType], forKeys: ["ResumeID" as NSCopying, "CandidateID" as NSCopying, "MediaName" as NSCopying, "FileExtension" as NSCopying, "MediaType" as NSCopying])
let boundary = generateBoundaryString()
let url = URL(string: "http://192.168.1.29/ColorsKit_New_Svr/WTCSvr.svc/WTCService?Id=6&SPName=Usp_RTN_IU_CandidateSubmissionResume")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let path1 = Bundle.main.path(forResource: "dummy-pdf_2", ofType: "pdf")!
request.httpBody = try createBody(with: parameters as? [String : String], filePathKey: "MediaContent", paths: [path1], boundary: boundary)
return request
}
private func createBody(with parameters: [String: String]?, filePathKey: String, paths: [String], boundary: String) throws -> Data {
var body = Data()
if parameters != nil {
for (key, value) in parameters! {
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.append("\(value)\r\n")
}
}
for path in paths {
let url = URL(fileURLWithPath: path)
let filename = url.lastPathComponent
let data = try Data(contentsOf: url)
let mimetype = mimeType(for: path)
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(filePathKey)\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(mimetype)\r\n\r\n")
body.append(data)
body.append("\r\n")
}
body.append("--\(boundary)--\r\n")
return body
}
func sendMultipartRequest() {
let request: URLRequest
do {
request = try createRequest(ResumeID: "1", CandidateID: "1241124", MediaName: "dummy-pdf", FileExtension: "pdf", MediaType: "pdf")
} catch {
print(error)
return
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard error == nil else {
// handle error here
print(error!)
return
}
// if response was JSON, then parse it
do {
let responseDictionary = try JSONSerialization.jsonObject(with: data!)
print("success == \(responseDictionary)")
// note, if you want to update the UI, make sure to dispatch that to the main queue, e.g.:
//
// DispatchQueue.main.async {
// // update your UI and model objects here
// }
} catch {
print(error)
let responseString = String(data: data!, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
}
task.resume()
}
The Response I'm getting is:
Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start
with array or object and option to allow fragments not set."
UserInfo={NSDebugDescription=JSON text did not start with array or
object and option to allow fragments not set.} responseString =
Optional("No Records Found")
This is strange because Postman is giving correct response. Means there is something missing in the code only :(
Use Alamofire
let upload_url = "your url"
let fieldName = "UploadedFile"
let mimeType = "plain/text"
Alamofire.upload(multipartFormData: { multipartFormData in
//you can add multiple file
multipartFormData.append(fileData as Data, withName: fieldName, fileName: fileName, mimeType: mimeType)
}, to: upload_url, method: .post, headers: ["Authorization": "auth_token"],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { [weak self] response in
guard let _ = self else {
return
}
debugPrint(response)
}
case .failure(let encodingError):
debugPrint("uploaderService error:\(encodingError)")
}
})
Use JSONSerialization as below
if let responseDictionary = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? String {
...
}
I was using the same code before updating Alamofire to version 4.0 to upload image to server and it was working very good but now I have these errors I'm trying a lot but at each time the new error appears to me :
First Error:
Second Error:
My code:
func uploadFile() {
let image = UIImage(named: "ios9.jpg")
let newimage : NSData = UIImageJPEGRepresentation(selectedImage.image!, 32)! as NSData
let newRandomName = randomStringWithLength(32)
let fname = (newRandomName as String) + ".jpg"
let parameters = [
"pic" :NetData(data: newimage as Data, mimeType: .ImageJpeg, filename: fname),
"msg" :self.detailmsg,
"customer_key" : self.CUSTOMER_KEY
] as [String : Any]
let urlRequest = self.urlRequestWithComponents("link", parameters: parameters as NSDictionary)
//First error here
Alamofire.upload(urlRequest.0, data: urlRequest.1)
.progress { (bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
print("\(totalBytesWritten) / \(totalBytesExpectedToWrite)")
}
.responseJSON { response in
debugPrint(response)
}
}
func urlRequestWithComponents(_ urlString:String, parameters:NSDictionary) -> (URLRequestConvertible, NSData) {
// create url request to send
let mutableURLRequest = NSMutableURLRequest(url: URL(string: urlString)!)
mutableURLRequest.httpMethod = Alamofire.HTTPMethod.post.rawValue
//let boundaryConstant = "myRandomBoundary12345"
let boundaryConstant = "NET-POST-boundary-\(arc4random())-\(arc4random())"
let contentType = "multipart/form-data;boundary="+boundaryConstant
mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")
// create upload data to send
let uploadData = NSMutableData()
// add parameters
for (key, value) in parameters {
uploadData.append("\r\n--\(boundaryConstant)\r\n".data(using: String.Encoding.utf8)!)
if value is NetData {
// add image
let postData = value as! NetData
//uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(postData.filename)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
// append content disposition
let filenameClause = " filename=\"\(postData.filename)\""
let contentDispositionString = "Content-Disposition: form-data; name=\"\(key)\";\(filenameClause)\r\n"
let contentDispositionData = contentDispositionString.data(using: String.Encoding.utf8)
uploadData.append(contentDispositionData!)
// append content type
//uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) // mark this.
let contentTypeString = "Content-Type: \(postData.mimeType.getString())\r\n\r\n"
let contentTypeData = contentTypeString.data(using: String.Encoding.utf8)
uploadData.append(contentTypeData!)
uploadData.append(postData.data as Data)
}else{
uploadData.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".data(using: String.Encoding.utf8)!)
}
}
uploadData.append("\r\n--\(boundaryConstant)--\r\n".data(using: String.Encoding.utf8)!)
// return URLRequestConvertible and NSData
// return (Alamofire.ParameterEncoding.encode(mutableURLRequest as! ParameterEncoding).0, uploadData)
//Second error here
return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
}
let image = UIImage(named: "ios9.jpg")
let params:[String:Any] = ["msg": self.detailmsg,
"customer_key": self.CUSTOMER_KEY]
let urlRequest = try! URLRequest(url: url, method: .post, headers: nil)
Alamofire.upload(multipartFormData: { (multipartFormData) in
if let imageData = UIImageJPEGRepresentation(image!, 1.0){
multipartFormData.append(imageData, withName: "pic", fileName:"image.jpg", mimeType: "image/jpg")
}
for (key, value) in self.parameters! {
let data = "\(value)".data(using: .utf8)
multipartFormData.append(data!, withName: key)
}
}, with: urlRequest) { (result) in
switch result{
case .success(let request, _, _):
request.responseJSON { response in
debugPrint(response)
}
case .failure(let error):
print(error.localizedDescription)
}
}
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()
}