Send image to API - Swift 4 - swift

I'm new in Swift,and have some problem with sending an image to api, from MacOS app. I try with lot of codes, this one is(as I think) most correct, but it doesn't work:
func mimeTypeForPath(path: String) -> String {
let url = NSURL(fileURLWithPath: path)
let pathExtension = url.pathExtension
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() {
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
return mimetype as String
}
}
return "application/octet-stream";
}
func sendScreenshoot(url: String){
let img = NSImage(byReferencingFile: home.path)
guard let uploadData = try? img?.tiffRepresentation else {
return
}
let mimetype = mimeTypeForPath(path: home.path)
print(mimetype)
let boundary = "Boundary-\(UUID().uuidString)"
print(boundary)
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var body = Data()
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name=\"screenshot\"; filename=\"screenshot.png\"\r\n")
body.appendString("Content-Type: \(mimetype)\r\n\r\n")
body.append(uploadData!)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
request.httpBody = body
URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
print(error)
}).resume()
}
What is the best way to send files(images) with swift 4 Mac OS(without Alamofire)?

Try below code
func myImageUploadReques(){
if let data:Data = UIImageJPEGRepresentation(img_Selected.image!, 0.5) {
let base64String = data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
print(base64String)
let strBase1 = base64String.replacingOccurrences(of: "+", with: "%2B", options: NSString.CompareOptions.literal, range: nil)
let str = strBase1.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
var params: [String:String] = [:]
params["action"] = "upload_file"
params["document_type"] = "image"
params["file"] = str
myRequest.SendRequestUrl(del: self as MyURLRequestDelegate, params: params , type: "upload_file")
LoadingOverlay.shared.showLoaderView(view: self.view)
}
}

I found the working solution.
func sendScreenshoot(url: String){
let img = try? Data(contentsOf: home)
let mimetype = mimeTypeForPath(path: home.path)
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
let boundary = "Boundary-\(NSUUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)",
forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
let fname = "screenshoot.png"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data;name=\"photo\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("Incoming\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"file\";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(img!)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using:
String.Encoding.utf8)!)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
}
task.resume()
}

Related

API call for Multipart/form_data Body with application/json data

I am trying to upload some data to my server.I am tring to put my data in file and upload.The request body is multipart/form_data with a single parameter named "filemessage" containing text data which has a content-type of application/json
I am not sure how to handle the application/json as content-type for inner data contained by "filemessage".
I am getting 500 internal server error
{
"erMessage": "Unknown error",
"erCode": "UnknownErCode"
}
Here is the code.
func testMultipart()
{
let path = Bundle.main.path(forResource: "testregister", ofType: "txt")
do {
let mtext = try String(contentsOfFile: path!)
let dataA = Data(mtext.utf8)
guard let url = URL(string: "MY URL") else { return false }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let mKey = "filemessage"
let mFileName = "testregister"
let mMimeType = "text/plain"
let boundary = generateBoundary()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let lineBreak = "\r\n"
var body = Data()
body.append("--\(boundary + lineBreak)")
body.append("Content-Disposition: form-data; name=\"\(mKey)\"; filename=\"\(mFileName)\"\(lineBreak)")
body.append("Content-Type: \(mMimeType + lineBreak + lineBreak)")
body.append(dataA)
body.append(lineBreak)
request.httpBody = dataA
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
}.resume()
}
catch(_){print("error")}
}
func generateBoundary() -> String
{
return "Boundary-\(NSUUID().uuidString)"
}

Swift 3 - How to upload image with parameters to mysql

This code I use in Upload (I found it in a tutorial) is working successfully but the parameters is not being recognised instead of WHERE emp_name ='(insert employee)'it says emp_name='' because i'm trying to update the URL with the newly uploaded picture. Please help. i'm new to this.
func UploadRequest()
{
let url = URL(string: "http://www.example.com/empupload.php")
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
if (imageDetail.image == nil)
{
return
}
let image_data = UIImagePNGRepresentation(imageDetail.image!)
if(image_data == nil)
{
return
}
let body = NSMutableData()
let loadempname = NSMutableURLRequest()
let fname = "test.png"
let mimetype = "image/png"
let postString = "empName=\(empname.text!))"
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"test\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("hi\r\n".data(using: String.Encoding.utf8)!)
body.append(postString.data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"file\"; 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)!)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard ((data) != nil), let _:URLResponse = response, error == nil else {
print("error")
return
}
if let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
{
print(dataString)
}
})
task.resume()
}
You can post image through Alamofire multipartFormData in swift3.0. Here is sample code:
let parameters = ["name":"YourName"]
Alamofire.upload(.POST, baseUrl, multipartFormData:
{
multipartFormData in
if let imageData = UIImageJPEGRepresentation(self.imageView.image!, 0.6)
{
multipartFormData.appendBodyPart(data: imageData, name: "keyName", fileName: "photo.jpg", mimeType: "image/jpeg")
}
for (key, value) in parameters
{
if value is String || value is Int
{
multipartFormData.appendBodyPart(data: "\(value)".dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
}
}, encodingCompletion:
{
encodingResult in
switch encodingResult
{
case .Success(let upload, _, _):
upload.responseJSON { response in
print(response)
if String(response.result) == "SUCCESS"
{
if(response.result.value!.objectForKey("status")) as! String != "fail"
{
// here you can write success case
}
else
{
}
}
else
{
MyLoadingView.dismiss();
MyAlertView.showErrorAlert("Please try Again" )
}
}
case .Failure(let encodingError):
print(encodingError)
}
})

Swift 3 How To Send A Multipart Post Request With Vapor

I'm using vapor to host images for my app.I have the following code to recieve the image and print it.
drop.post("saveArt") { request in
if let contentType = request.headers["Content-Type"], contentType.contains("image/png"), let bytes = request.body.bytes {
let image = NSImage(data: Data(bytes))
print(image)
return JSON(["Testawesome":"awesome123"])
}
return JSON(["test":"123"])
}
How can I send a multipart request using just swift?.Here is the current post request code i'm using.
let tiffData = imagetosend?.tiffRepresentation
let imageRep = NSBitmapImageRep(data: tiffData!)
let image_data = imageRep?.representation(using: .JPEG, properties: [:])
print("Hi")
let url = NSURL(string: "http://localhost:8080/getArt")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
//define the multipart request type
request.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
let mimetype = "image/png"
//define the data post parameter
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)!)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
guard let _:NSData = data as NSData?, let _:URLResponse = response , error == nil else {
print(error?.localizedDescription)
return
}
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(dataString)
}
task.resume()
I solved it using this alamofire method.
Alamofire.request("YOUR URL", method: .post, parameters: parm, encoding: JSONEncoding.default).responseJSON(completionHandler: { json in
// If you want to return json.
print(json)
})

Can't upload image to server swift

I'm trying to upload an image to the server. As for now, I get an error response which checks if name='image', and the error means that it's not. The line where I set it is this:
body.appendString("Content-Disposition: form-data; name='image'; filename='test.jpg'")
my full code of the POST request is this: I do get a 200 and the only problem is with the name parameter which I really can't figure out.
func imageUploadRequest()
{
let stringUrl = "http://88.162.41.55/app_backend/public/api/v1/image?_r=1836486547600309"
let URL = NSURL(string: stringUrl.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!
let request = NSMutableURLRequest(URL: URL)
request.HTTPMethod = "POST";
request.setValue("Bearer \(jwtToken)", forHTTPHeaderField: "Authorization")
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(image, 1)
if(imageData == nil) {
print("image data is nil")
return
}
let body:NSMutableData = NSMutableData()
body.appendString("--\(boundary)\r\n")
body.appendString("Content-Disposition: form-data; name='image'; filename='test.jpg'")
body.appendString("Content-Type: image/jpg")
body.appendData(imageData!)
body.appendString("\r\n")
body.appendString("--\(boundary)--\r\n")
request.HTTPBody = body
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(" response = \(responseString!)")
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
print("json", json)
} catch {
print("bad things happened")
}
}
task.resume()
}
Any ideas? Thank you so much!!
Sample NSURLSession
func getMetaData(lePath:String, completion: (string: String?, error: ErrorType?) -> Void) {
// **** get_metadata ****
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/files/get_metadata")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("Bearer ab-blah", forHTTPHeaderField: "Authorization")
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("path", forHTTPHeaderField: lePath)
let cursor:NSDictionary? = ["path":lePath]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(cursor!, options: [])
request.HTTPBody = jsonData
print("json ",jsonData)
} catch {
print("snafoo alert")
}
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
//print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
completion(string: "", error: nil)
} catch {
completion(string: nil, error: error)
}
})
task.resume()
}

swift, send file to server

I am learning swift and I send a request to the server with the code below. It works for simple request and I get response from the server. My problem is I can not send a file to server.
code :
let parameters = parameter
let request = NSMutableURLRequest(URL: NSURL(string: requestUrl)!)
let boundaryConstant = "-----Boundary+\(arc4random())\(arc4random())"
let contentType = "multipart/form-data; boundary=" + boundaryConstant
let boundaryStart = "--\(boundaryConstant)\r\n"
let boundaryEnd = "--\(boundaryConstant)--\r\n"
let body:NSMutableString = NSMutableString();
for (key, value) in parameters {
body.appendFormat(boundaryStart)
body.appendFormat("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendFormat("\(value)\r\n")
}
body.appendFormat(boundaryEnd)
request.HTTPMethod = "POST"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
request.HTTPBody = body.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
// check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
self.responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print("MMMMMMMM \(self.responseString)")
self.result = self.responseString.dataUsingEncoding(NSUTF8StringEncoding)! as NSData
callback(self.responseString)
}
print("code start")
task.resume()
result :
i can post file to server by this code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let request = createRequest()
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if error != nil {
// handle error here
print(error)
return
}
do {
if let responseDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
print("success == \(responseDictionary)")
}
} catch {
print(error)
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
}
task.resume()
}
func createRequest () -> NSURLRequest {
let param = []
let boundary = generateBoundaryString()
let url = NSURL(string: "URl")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.setValue("userValue", forHTTPHeaderField: "X-Client-user")
request.setValue("passValue", forHTTPHeaderField: "X-Access-pass")
//let path1 = NSBundle.mainBundle().pathForResource("voice", ofType: "png") as String!
request.HTTPBody = createBodyWithParameters(param, filePathKey: "voice", paths: ["pathURl"], boundary: boundary)
return request
}
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, paths: [String]?, 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")
}
}
if paths != nil {
for path in paths! {
let url = NSURL(fileURLWithPath: path)
let filename = url.lastPathComponent
let data = NSData(contentsOfURL: url)!
let mimetype = mimeTypeForPath(path)
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(data)
body.appendString("\r\n")
}
}
body.appendString("--\(boundary)--\r\n")
return body
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
func mimeTypeForPath(path: String) -> String {
let url = NSURL(fileURLWithPath: path)
let pathExtension = url.pathExtension
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension! as NSString, nil)?.takeRetainedValue() {
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
return mimetype as String
}
}
return "application/octet-stream";
}
As you read here, you should use NSURLSession for HTTP work, it far more flexible and powerful; and I think is destined to replace NSURLconnection...
https://www.objc.io/issues/5-ios7/from-nsurlconnection-to-nsurlsession/
Here is a example for you...
func getMetaData(lePath:String, completion: (string: String?, error: ErrorType?) -> Void) {
// **** get_metadata ****
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/files/get_metadata")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("Bearer ab-blah-blah", forHTTPHeaderField: "Authorization")
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("path", forHTTPHeaderField: lePath)
let cursor:NSDictionary? = ["path":lePath]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(cursor!, options: [])
request.HTTPBody = jsonData
print("json ",jsonData)
} catch {
print("snafoo alert")
}
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
self.jsonParser(jsonResult,field2file: "ignore")
for (key, value) in self.parsedJson {
print("key2 \(key) value2 \(value)")
}
completion(string: "", error: nil)
} catch {
completion(string: nil, error: error)
}
})
task.resume()
}
Great answer above.. Here it's updated for Swift3:
func getMetaData(lePath:String, completion: (string: String?, error: ErrorType?) -> Void) {
// **** get_metadata ****
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/files/get_metadata")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("Bearer ab-blah-blah", forHTTPHeaderField: "Authorization")
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue("path", forHTTPHeaderField: lePath)
let cursor:NSDictionary? = ["path":lePath]
do {
let jsonData = try NSJSONSerialization.dataWithJSONObject(cursor!, options: [])
request.HTTPBody = jsonData
print("json ",jsonData)
} catch {
print("snafoo alert")
}
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
self.jsonParser(jsonResult,field2file: "ignore")
for (key, value) in self.parsedJson {
print("key2 \(key) value2 \(value)")
}
completion(string: "", error: nil)
} catch {
completion(string: nil, error: error)
}
})
task.resume()
}