How to do multipart/form-data post request with Swift? - ios

let Url = String(format: "http://url/ios.php")
guard let serviceUrl = URL(string: Url) else { return }
let parameterDictionary :[String:String] = ["Episodes" : "http://url/anime/07-ghost.html"]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
request.httpBody = NSKeyedArchiver.archivedData(withRootObject: parameterDictionary)
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
}catch {
print(error)
}
}
}.resume()
}
I get error
Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}
not sure if im sending data correctly, i think im setting httpbody incorectly
i even tried with json
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameterDictionary, options: []) else {
return
}

Swift 3,
Try this, Remove responseHandler parameter and any other if not use in your code
class func API_POST_FORM_DATA(param:[String : String], songData:Data?, fileName:String ,responseHandler : #escaping CompletionHandler)
{
let API_URL = API_POST_ADD_SONG_TO_PLAYLIST
print("API_URL : \(API_URL)")
let request = NSMutableURLRequest(url: URL(string: API_URL)!)
request.httpMethod = "POST"
let boundary = API_Calling.generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
let fname = fileName
let mimetype = "image/png"
//define the data post parameter
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("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
if let songRawData = songData
{
body.append("Content-Disposition:form-data; name=\"song\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!)
body.append(songRawData)
}
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
for (key, value) in param
{
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)!)
}
request.httpBody = body as Data
// return body as Data
print("Fire....")
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) {
(
data, response, error) in
print("Complete")
if error != nil
{
print("error upload : \(error)")
responseHandler(nil)
return
}
do
{
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
{
responseHandler(json as NSDictionary?)
}else
{
print("Invalid Json")
}
}
catch
{
print("Some Error")
responseHandler(nil)
}
}
task.resume()
}
class func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}

Related

Required request part 'file' is not present error in Swift

I am trying to upload profile image to server using multipart file upload.
My code is
func uploadPhoto(image: UIImage, filePath: String, completion: #escaping uploadPhotoClosure) {
let imageData = image.jpegData(compressionQuality: 0.3)
let url = "https:www.somepath.com/uploadFile"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
let boundary = UUID().uuidString
let contentType = "multipart/form-data; boundary=\(boundary)"
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var body = Data()
body.append("\r\n--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("field_mobileinfo_image".data(using: String.Encoding.utf8, allowLossyConversion: true)!)
body.append("\r\n--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"files[field_mobileinfo_image]\"; filename=\"img.jpg\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Type: application/octet-stream\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(imageData!)
body.append("\r\n--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body
self.serviceManager.async(request: request) { (innerClosure) in
do {
let response = try innerClosure()
guard let json = response.jsonObject else {
completion({ throw JSONErrorType.parsingError })
return
}
let jsonData = try JSONSerialization.data(withJSONObject: json, options: [])
let responseModel = try JSONDecoder().decode(EditProfilePhotoUploadResponse.self, from: jsonData)
completion({ return responseModel })
} catch {
completion({ throw error })
}
}
}
//servicemanager class
func async(request: URLRequest, completion: #escaping ServiceManagerAsyncCompletion) {
ServiceManager.log(request)
let task = self.urlSession.dataTask(with: request) { (data, response, error) in
guard error == nil else {
DispatchQueue.main.async {
completion({ throw error! })
}
return
}
guard let response = response as? HTTPURLResponse else {
DispatchQueue.main.async {
completion({ throw ServiceErrorType.invalidResponse })
}
return
}
ServiceManager.log(response, withBody: data)
//here handling status code
}
}
And the error from server is below
{
"status" : 500,
"message" : "Required request part 'file' is not present",
"timestamp" : "2022-08-05T05:30:55.415+0000",
"path" : "/uploadFile",
"error" : "Internal Server Error"
}
Any suggestions?
As your code does not contain a reproduclible example, this is just a long shot.
The final boundary is definitely wrong. It has to end with two "-" ticks.
e.g.
body.append("\r\n--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
but there might be more going on here.
Good article on multipart form data
RFC
The boundary header can be an arbitary string. But it has to be unique in the request to seperate it from the datastream. Also in the body it has to start with two "-" and the last boundary line in the request has to end with two "-" ticks also.

How to send the image file with value as image, key as 'file'

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)!)
}

Upload image to server Swift 3

I'm trying to upload an image to a server in iOS using Swift 3, I've tried with Alamofire but it's not working, so I just searched for another solution here in this forum but without luck.
I found some answers that said that the problem could have been server side, but, on Android the image is uploading correctly.
This is my upload function in swift 3:
func uploadImage(image: UIImage){
let imageData = UIImageJPEGRepresentation(image, 0.1)!
let session = URLSession(configuration: URLSessionConfiguration.default)
guard let url = URL(string: uploadPicUrl) /* your API url */) else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
let boundary = "---------------------------14737809831466499882746641449"
let contentType = "multipart/form-data; boundary=\(boundary)"
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
var body = Data()
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"userfile\"; filename=\"img.jpg\"\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Transfer-Encoding: binary\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(imageData)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body
print("request", request.debugDescription)
print("body", body.debugDescription)
let dataTask = session.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Something went wrong: \(error)")
}
if let response = response {
print("Response: \n \(response)")
}
}
dataTask.resume()
}
Without using Alamofire, you can do the following:
func uploadImage(chosenimage: UIImage) {
let url = ApiList.base_url + ApiList.uploadFile_Url
let myUrl = NSURL(string: url)
let image_data = UIImagePNGRepresentation(chosenimage)
let tempData = NSMutableData()
let request = NSMutableURLRequest(url:myUrl! as URL)
request.httpMethod = "POST"
let boundary = NSUUID().uuidString
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField:"Content-Type")
let mimetype = "image/png"
let fname = "test.png"
self.body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
self.body.append("Content-Disposition:form-data; name=\"profileUrl\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!)
self.body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
self.body.append(image_data!)
self.body.append("\r\n".data(using: String.Encoding.utf8)!)
let accessToken = UserDefaults.standard.value(forKey: "accessToken") as? String ?? ""
let deviceToken = UserDefaults.standard.value(forKey: "deviceToken") as? String ?? singletonclass.instance.getDeviceToken
let param = [
"accessToken":accessToken,
"deviceId":deviceToken,
"deviceType":"2"
]
for (key,value) in param {
tempData.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
tempData.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: String.Encoding.utf8)!)
tempData.append("\(value)\r\n".data(using: String.Encoding.utf8)!)
}
self.body.append(tempData as Data)
self.body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = self.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 { return }
do
{
let responseDict = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [String:Any]
//print("\n tyiukmqw",responseDict)
let code = responseDict.value(forKey: "code") as? String
let message = responseDict.value(forKey: "Message") as? String
singletonclass.instance.isrofilePicChagedOrNot = false
if code == "200"
{
print("success code")
DispatchQueue.main.async(execute: {
self.userProfile.image = chosenimage
UserDefaults.standard.setValue(UIImagePNGRepresentation(chosenimage), forKey: "UserProfilePicture")
singletonclass.instance.userProPic = chosenimage
})
}
else
{
DispatchQueue.main.async(execute: {
singletonclass.instance.showAlert(message!)
self.isActivityIndicatorNeed(false)
})
}
}
catch
{
}
}
task.resume()
}
Note : This function is to upload multiple files of different type using Alamofire
// upload file to server
func uploadFiles(files: [Data],completion : #escaping uploadHandler) {
let header : HTTPHeaders = ["Content-Type" : "application/x-www-form-urlencoded"] // if there's Authorization, you may add it in header
let url = URL(string: "Enter the url here")
Alamofire.upload(multipartFormData: { (multipartFormData) in
for document in files {
let fileName = NSUUID().uuidString
multipartFormData.append(document, withName: "documents", fileName:fileName ,mimeType: "image/jpeg") // You'll have to define the proper mime time for uploading other type of files. You may achieve it by creating a struct and storing the type of each file.
}
}, usingThreshold: UInt64.init(), to:url, method: .post, headers: header) { (result) in
switch result{
case .success(let upload, _, _):
upload.responseJSON { response in
switch response.result {
case .success(_) : completion(true, nil)
case .failure(let error) :
print("Error in upload: \(error.localizedDescription)")
completion(false, nil)
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
completion(false,error)
}
}
}
typealias uploadHandler = (_ status :Bool,_ error :Error?)->()// Define this anywhere globally
While calling the function I'm passing an array of files, I converted different type of file to data and uploading them to server.
if you want to upload array of images than before calling the function .
var documents = [Data]()
for image in imageArray {
if let imgData = UIImageJPEGRepresentation(image, 1.0) {
documents.append(document)
}
}
Now you can call the upload function and pass the documents and listen to completion Handler.
Good luck .

Upload the image with JSON parameter in swift 3

I am just trying to upload the image with json parameter in NSURLSession swift 3
url:"http:xxxxxxxx"
the JSON parameter : {"data":{"userId":9}}
Please help me to accomplish it
Here is the code:
func UploadRequest()
{
let username = "v"
let password = "v"
let loginData = String(format: "%#:%#", username, password).data(using: String.Encoding.utf8)!
let base64LoginData = loginData.base64EncodedString()
let url = NSURL(string: "http://xxxxxxxxxxxx")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
request.setValue("Basic \(base64LoginData)", forHTTPHeaderField: "Authorization")
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
if (imageView.image == nil)
{
return
}
let image_data = UIImageJPEGRepresentation(imageView.image!, 1)
if(image_data == nil)
{
return
}
let boundary = generateBoundaryString()
request.httpBody = createBodyWithParameters(filePathKey: "file", imageDataKey: image_data! as NSData, boundary: boundary) as Data
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest){
data, response, error in
self.loading.stopAnimating()
if data == nil{
print("data is nil")
}
else
{
print("data is\(data!)")
}
if error == nil{
print("error is nil")
}
else
{
print("error is \(error!)")
}
if response == nil{
print("response is nil")
}
else
{
print("response is \(response!)")
}
print("hitted")
guard let _:NSData = data as NSData?, let _:URLResponse = response, error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(dataString!)
}
self.loading.stopAnimating()
task.resume()
}
func jsonToNSData(json: AnyObject) -> NSData?{
return try? JSONSerialization.data(withJSONObject: json, options: []) as NSData
}
func generateBoundaryString() -> String
{
return "Boundary-\(NSUUID().uuidString)"
}
//[String:[String: Int]]?
func createBodyWithParameters(filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData();
let param:[String:Any] = ["data":["data":["userId":9]]]
do {
for i in param {
body.appendString(string:"--\(boundary)\r\n")
body.appendString(string:"Content-Disposition: form-data; name=\"\(i.key)\"\r\n\r\n")
body.appendString(string:"\(i.value)\r\n")
}
let jsonData = try JSONSerialization.data(withJSONObject: param, options: .prettyPrinted)
let decoded = try JSONSerialization.jsonObject(with: jsonData as Data, options: [])
let filename = "user-profile.jpg"
let mimetype = "image/jpg"
body.appendString(string:"--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(decoded)\"\r\n\r\n")
body.appendString(string:"\(decoded)\r\n")
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.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
return body
}
extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
In the backend aim getting error as ["userId":9] cannot deserialize it
The error looks like it could be related to the way you are both serialising, deserialising then converting the dictionary to a string then back to data again. You can see this in the use of the decoded property instead of the jsonData when creating the request payload.
Instead of body.appendString(string:"\(decoded)\r\n")
Why not try:
body.append(jsonData)
body.appendString(string:"\r\n")

Uploading multiple images with other parameters in Swift

Right now I've been uploading only one image to a server on a server side script through the code given below. Now I have an array of UIImage, I want to know how can I use UIImageJPEGRepresentation(myImageView.image!, 0.1) to post all the images in a UIImageView array?
func uploadImage()
{
let postPictureUrl = NSURL(string: "http://www.23look.com/merchant/verify")
let request = NSMutableURLRequest(URL: postPictureUrl!)
request.HTTPMethod="POST"
let param=[
"mer_name" : shopNameUITF.text!,
"mer_tel" : shopTelephoneUITF.text!,
"mer_address" : shopAddressUITF.text!,
"lat" : "39.6892",
"lng" : "115.9239",
"token": KeychainWrapper.stringForKey("tokenValue")!,
"mer_type": "smalll"
]
let abc = KeychainWrapper.stringForKey("tokenValue")!
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = UIImageJPEGRepresentation(myImageView.image!, 0.1)
if imageData==nil { print("image data is nil"); return }
request.HTTPBody = createBodyWithParameters(param, filePathKey: "mer_license", imageDataKey: imageData!, boundary: boundary)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
//You can print out response object
print("***** response = \(response)")
// Print out reponse body
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("**** response data = \(responseString!)")
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
dispatch_async(dispatch_get_main_queue(), {
print(NSString(data: data!, encoding:NSUTF8StringEncoding)!)
print(json)
})
} catch let err {
print(err)
}
}
task.resume()
}
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().UUIDString)"
}
func createBodyWithParameters(parameters:[String:String]?, filePathKey: String?, imageDataKey:NSData, boundary: String) -> NSData {
var 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
}
It takes following parameters:
mer_name - String
mer_tel - String
mer_address - string
lng - string
lat - string
mer_licence - file type (This is where my images will be uploaded)
token - string
mer_type - string
You should do changes in createBodyWithParameters like below.........
When you have multiple images...
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
}
doOnMain {
Loading.sharedInstance.startloading()
}
let url = NSURL(string:"URL")
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
let headers = ["Accept-Language": "en"]
request.allHTTPHeaderFields = headers
let boundary = generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
if (imgRefund.image == nil){
return
}
// First Image
let image_data = imgRefund.image!.pngData()
if(image_data == nil){
return
}
// Second Image
let image_data1 = imgRefund1.image!.pngData()
if(image_data1 == nil){
return
}
let body = NSMutableData()
let fname = "filename"
let fname1 = "filename1"
let mimetype = "image/png"
let parameters = ["key":"value","key":"value"]
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)!)
}
}
// First Image
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("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"parameter\"; filename=\"\(fname)\"\r\n".data(using: String.Encoding.utf8)!) // paramenter name
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)!)
// Second Image
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("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition:form-data; name=\"parameter1\"; filename=\"\(fname1)\"\r\n".data(using: String.Encoding.utf8)!) // paramenter name 1
body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append(image_data1!)
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
guard let _:NSData = data! as NSData, let _:URLResponse = response, error == nil else {
print("error")
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("****** response data = \(responseString!)")
do {
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
print("****** response json = \(json!)")
if(json?.value(forKey: "status") as! Int == 200){
print(json)
}
else{
}
}catch{
print(error)
}
}
task.resume()
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}

Resources