I am using Alamofire for my data post to the server. I ahve an image which I want to upload to server in Data form with some other parameters. In Alamofire, I am using multipartFormData method to post all the parameters and image. Server needs data to be in JSON format with parameters which is shown below:
{"product_name": "almondsfdsfsdf",
"product_price": "400",
"product_img": image.jpg}
I am trying but it gives me a failure in response. Here is my code of what I am doing in swift with alamofire:
let productName = itemNameTF.text!
let productPrice = itemPriceTF.text!
let productImage:UIImage = itemImage.image!
let url = "URL"
let parameter = ["product_name": productName, "product_price": productPrice]
let headers : HTTPHeaders = ["Content-Type": "application/json","Authorization" : "Token abcd"]
Alamofire.upload(multipartFormData: {
multipartFormData in
if let imageData = UIImageJPEGRepresentation(productImage, 0.5){
multipartFormData.append(imageData, withName: "image", fileName: "file.png", mimeType: "image/png")
}
for (key,value) in parameter {
multipartFormData.append(value.data(using: .utf8)!, withName: key)
}
}, to: url,method: .post, headers: headers, encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload,_,_):
upload.responseJSON { response in
print(response.request)
print(response.response)
print(response.result)
print(response.data)
}
break
case .failure(let encodingError):
print("error: \(encodingError)")
break
}
})
My server accept image in BLOB data. If anyone could help me. Thank you!
Try to change this line:
multipartFormData.append(imageData, withName: "image", fileName: "file.png", mimeType: "image/png")
To this:
multipartFormData.append(imageData, withName: "product_img", fileName: "image.jpg", mimeType: "image/jpeg")
Please take reference from below method to get the answer(Works for the Alamofire 3.0+).
func uploadImageAndData(){
var parameters = [String:AnyObject]()
parameters = ["token":token,
"lastName":lastName]
let URL = "http://yourserviceurl/"
let image = UIImage(named: "image.png")
Alamofire.upload(.POST, URL, multipartFormData: {
multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 0.6) {
multipartFormData.appendBodyPart(data: imageData, name: "image", fileName: "file.png", mimeType: "image/png")
}
for (key, value) in parameters {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
}, encodingCompletion: {
encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
print("s")
upload.responseJSON {
response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
case .Failure(let encodingError):
print(encodingError)
}
})
}
Related
I want to upload png image to URL like postman , i used postman
postman screenshot
I used this function to upload png image to url using post method using Alamofire
this is upload function , but it return error code 500 Internal server error although it success with code 200 in postman
static func updateProfileImage(image : UIImage , result : #escaping()->()) {
if let user = UserDefaults.standard.string(forKey: "mail") , let imgData = image.pngData(){
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append("form-data".data(using: .utf8 ,allowLossyConversion: false)!, withName: "Content-Disposition")
//multipartFormData.append("name".data(using: .utf8 ,allowLossyConversion: false)!, withName: "fileUpload")
multipartFormData.append(imgData, withName: "fileUpload", mimeType: "image/png")
},
to: URLs.profileImage+user,method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { response in
print(response)
}
case .failure( _):
print("error")
}
}
)
}
I have code of multipart data request follows, I hope this will help you.
Alamofire.upload( multipartFormData: { multipartFormData in
// parameters is method arguments in my webs ervice call method
for (key, value) in parameters {
if let data = (value as! String).data(using: .utf8) {
multipartFormData.append(data, withName: key)
}
}
let imageData = image?.jpegData(compressionQuality: 0.5)
multipartFormData.append(imageData!, withName: "profile_image", fileName: "profileImage", mimeType: "image/jpeg")
// getURL(.addProfile) will create url, method from my structure
// getHeaders() will return required header from that method
}, to: getURL(.addProfile), headers: getHeaders(), encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response(completionHandler: { (defaultDataResponse) in
guard let httpResponse = defaultDataResponse.response else {
completion(nil, defaultDataResponse.error)
return
}
if httpResponse.statusCode == 200 {
// Success Code
} else {
// Failed code
}
})
case .failure(let encodingError):
// Failed code.
}
})
Try this
func generateBoundary() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
//Set Headers with required auth
let boundary = generateBoundary()
let headers = ["content-type": "multipart/form-data; boundary=\(boundary)",
"Content-Type": "application/json",
"cache-control": "no-cache"]
//Api Call
Alamofire.upload(multipartFormData:{ multipartFormData in
if let image = imageData {
multipartFormData.append(image, withName: "<param_key>", fileName: objIdentityDetails.fileName ?? (String(Date().timeIntervalSince1970) + ".jpeg"), mimeType: "image/jpeg")
}
for (key, value) in parameters {
multipartFormData.append(value?.data(using: String.Encoding.utf8) ?? Data(), withName: key)
}},
usingThreshold:UInt64.init(),
to: try! <URL>,
method: .post,
headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseObject { (response: <model>) in
switch response.result {
case .failure (let error):
//Error
case .success (let responseObject):
//response
}
}
case .failure(let encodingError):
//Error
}
})
You can use this following code to upload :
Alamofire.upload(multipartFormData:{ multipartFormData in multipartFormData.append(img, withName: "image", fileName: "image.png", mimeType: "image/png") },
"img" - Is Your Image Data &
"withName" - Is Your Name In Postman &
"fileName" - Your Image Name Which You Want To Upload
Iam trying to upload 2 images to server with JSON request using alamofire
and here's my code :
let parameters = ["CreditCardImage":CreditCardImage,"CreditCardBackImage":CreditCardBackImage , "CustomerID" : CustomerID]
let headers: HTTPHeaders = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
Alamofire.request("MY URL", method : .post , parameters : parameters, encoding: JSONEncoding.default , headers: headers).responseJSON { response in
// get json Response
let json = JSON(response.result.value)
print(json)
}
When i print the response iam getting message << unknown >> in the console
and i tried that in postman it's not working too what's wrong with that ? any help ?
you should use other Alamofire methods. Here is an example:
func uploadAvatar(image: UIImage) {
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 1) {
multipartFormData.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png")
}
}, to: self.serverAddress + "/user/uploadAvatar", method: .post, headers: ["Authorization": User.shared.token], encodingCompletion: { _ in })
}
You can try this
let image = UIImage.init(named: "myImage")
let imgData = UIImageJPEGRepresentation(image!, 0.2)!
let parameters = ["name": rname]
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "fileset",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
},
to:"mysite/upload.php")
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value)
}
case .failure(let encodingError):
print(encodingError)
}
}
Plese have a look at the pic here from postman
POSTMAN success result
but the code does not run I am missing something please help me out
var parameters = [String: String]()
parameters = [
"profile_image": "imagefile"
]
let headers: HTTPHeaders = [
"Accept": "application/json"
]
let url = "http://******/public/api/v1/profile/update-picture?api_token=" + "aySlC26ZTHtlnS0lhUpdghxkd9gKJBLXLYFUO2Jidmiisoka9iFIicwRIZFx"
let completeUrl = URL(string:url)!
let imageData = UIImageJPEGRepresentation(chosenImage!, 1)
print ("image data:: \(imageData)")
print ("chosenImage:: \(chosenImage)")
// Alamofire.upload(imageData!, to: completeUrl).response { response in
// print (response)
// }
Alamofire.upload(
multipartFormData: {
multipartFormData in
multipartFormData.append(imageData!,
withName: "imagefile",
fileName: "image.jpg",
mimeType: "image/jpeg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!, withName: key)
}
},
to: completeUrl,
headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON{ response in
print(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
Postman Response
Success on postman but having issue with headers, can you point out the silly mistake i have make
I believe you need to append the image this way
multipartFormData.append(imageData!,
withName: "profile_image",
fileName: "image.jpg",
mimeType: "image/jpeg")
And you don't need to set or include parameters = ["profile_image": "image file"]
As #rob mentioned, use Charles and compare the request from Postman with the request from the simulator. It will help to pinpoint what's different
I'm using the following code to upload a single image to a server:
private static func urlRequestWithComponents(urlString:String, parameters:Dictionary<String, String>, imageData:NSData?, imageName: String) -> (URLRequestConvertible , NSData) {
// create url request to send
let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!)
mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue
let boundaryConstant = "myRandomBoundary12345";
let contentType = "multipart/form-data;boundary="+boundaryConstant
mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")
// create upload data to send
let uploadData = NSMutableData()
if(imageData != nil && imageData?.length != 0) {
// add image
uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData("Content-Disposition: form-data; name=\"\(imageName)\"; filename=\"\(StringHelper.sharedInstance.randomString(5)).png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData(imageData!)
}
// add parameters
for (key, value) in parameters {
uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!)
}
uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
print("upload",parameters)
// return URLRequestConvertible and NSData
return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
}
How can I upload multiple images in single parameter by editing this code?
Swift 3
Just use "[]" with image upload param to make it array of images.
Alamofire.upload(multipartFormData: { multipartFormData in
// import image to request
for imageData in imagesData {
multipartFormData.append(imageData, withName: "\(imageParamName)[]", fileName: "\(Date().timeIntervalSince1970).jpeg", mimeType: "image/jpeg")
}
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
}, to: urlString,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
}
case .failure(let error):
print(error)
}
})
This one helps me:
private func urlRequestWithComponentsForUploadMultipleImages(urlString:String, parameters:Dictionary<String, String>, imagesData:[Data], imageName: String) -> (URLRequestConvertible , Data) {
// create url request to send
var mutableURLRequest = URLRequest(url: NSURL(string: urlString)! as URL)
mutableURLRequest.httpMethod = Alamofire.HTTPMethod.post.rawValue
let boundaryConstant = "myRandomBoundary12345";
let contentType = "multipart/form-data;boundary="+boundaryConstant
mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")
// create upload data to send
var uploadData = Data()
// add image
for data in imagesData {
uploadData.append("\r\n--\(boundaryConstant)\r\n".data(using: String.Encoding.utf8)!)
uploadData.append("Content-Disposition: form-data; name=\"\(imageName)\"; filename=\"\(Date().timeIntervalSince1970).jpeg\"\r\n".data(using: String.Encoding.utf8)!)
uploadData.append("Content-Type: image/jpeg\r\n\r\n".data(using: String.Encoding.utf8)!)
uploadData.append(data)
}
// add parameters
for (key, value) in parameters {
uploadData.append("\r\n--\(boundaryConstant)\r\n".data(using: String.Encoding.utf8)!)
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)!)
print("upload",parameters)
return (mutableURLRequest , uploadData)
}
here is my solution and it will work 100% no bugs..
Alamofire.upload(multipartFormData: { (multipartFormData : MultipartFormData) in
let count = imageToUpload.count
for i in 0..<count{
multipartFormData.append(imageToUpload[i], withName: "morephoto[\(i)]", fileName: "photo\(i).jpeg" , mimeType: "image/jpeg")
}
for (key, value) in parameterrs {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
print(multipartFormData)
}, to: url!) { (result) in
switch result {
case .success(let upload, _ , _):
upload.uploadProgress(closure: { (progress) in
print("uploding: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value!)
let resp = response.result.value! as! NSDictionary
if resp["status"] as! String == "success"{
print(response.result.value!)
let alert = UIAlertController(title: "Alert", message: "Image Upload Successful", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
else{
}
}
case .failure(let encodingError):
print("failed")
print(encodingError)
}
}
in this the imagetoupload array is the array of image data which i have made before.
It looks like this question was already answered on SO, probably in multiple places. Here is one link I found:
How to upload multiple images in multipart using Alamofire?
I'll paste their solution for convenience but they said it works for Swift 3.x:
//MARK: - upload multiple photos
func uploadImagesAndData(params:[String : AnyObject]?,image1: UIImage,image2: UIImage,image3: UIImage,image4: UIImage,headers : [String : String]?, completionHandler:#escaping CompletionHandler) -> Void {
let imageData1 = UIImageJPEGRepresentation(image1, 0.5)!
let imageData2 = UIImageJPEGRepresentation(image2, 0.5)!
let imageData3 = UIImageJPEGRepresentation(image3, 0.5)!
let imageData4 = UIImageJPEGRepresentation(image4, 0.5)!
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in params! {
if let data = value.data(using: String.Encoding.utf8.rawValue) {
multipartFormData.append(data, withName: key)
}
}
multipartFormData.append(imageData1, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
multipartFormData.append(imageData2, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
multipartFormData.append(imageData3, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
multipartFormData.append(imageData4, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
},
to: K_BASEURL + K_API_LOGINDATA, encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload
.validate()
.responseJSON { response in
switch response.result {
case .success(let value):
print("responseObject: \(value)")
case .failure(let responseError):
print("responseError: \(responseError)")
}
}
case .failure(let encodingError):
print("encodingError: \(encodingError)")
}
})
The solution appears to be based off the recommended approach detailed in the Alamofire documentation here: https://github.com/Alamofire/Alamofire#uploading-multipartformdata
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(unicornImageURL, withName: "unicorn")
multipartFormData.append(rainbowImageURL, withName: "rainbow")
},
to: "https://httpbin.org/post",
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
})
I am uploading an image with parameters (Full name, username, email) to my server with the following code, using Alamofire:
func uploadImageData(imageView: UIImageView, fullNameToPass: String, userNameToPass: String, emailToPass: String){
//parameters
let parameters = [
"full_name" : fullNameToPass,
"user_name" : userNameToPass,
"email" : emailToPass
]
let URL = "https://webiste/add_user.php"
profileData.fetchFromDatabase()
let filename = "\(profileData.getEmail()).jpg"
Alamofire.upload(.POST, URL, multipartFormData: {
multipartFormData in
if let imageData = UIImageJPEGRepresentation(imageView.image!, 0.6) {
multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: filename, mimeType: "image/jpg")
}
for (key, value) in parameters {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
}, encodingCompletion: {
encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
print("success")
upload.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
case .Failure(let encodingError):
print("Failure:\(encodingError)")
}
})
}
This part works and it all gets saved.
Now I want the user to be able to edit and update the profile. I am using the following but it does not work, can you tell me why?:
func updateImageData(imageView: UIImageView, fullNameToPass: String, userNameToPass: String, emailToPass: String, userID: String){
//parameters
let parameters = [
"full_name" : fullNameToPass,
"user_name" : userNameToPass,
"email" : emailToPass,
"userID" : userID
]
let URL = "https://webiste/edit_user.php"
profileData.fetchFromDatabase()
let filename = "\(profileData.getEmail()).jpg"
print("all\(fullNameToPass), \(userNameToPass), \(emailToPass), \(userID), filename: \(filename)")
Alamofire.upload(.POST, URL, multipartFormData: {
multipartFormData in
if let imageData = UIImageJPEGRepresentation(imageView.image!, 0.6) {
multipartFormData.appendBodyPart(data: imageData, name: "file", fileName: filename, mimeType: "image/jpg")
}
for (key, value) in parameters {
multipartFormData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}
}, encodingCompletion: {
encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
print("success")
upload.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
case .Failure(let encodingError):
print("Failure:\(encodingError)")
}
})
}