Uploading image to server with parameter error swift - ios

I am trying to upload image to server with folder name, filename and extension as parameter. I have done some code, but it gives me a Nil response. can someone help me to solve that?
Sometimes this uploads image and sometimes don't. And when it failed to upload image gives a Nil response.and sends some garbage value to server.
Here is my image upload method:
func UPLOD(){
let image = myImageView.image!
let serviceName = "http://192.168.80.21:8800/api/v1/upload/uploadfile"
var parameters = [String: AnyObject]()
parameters["Folder"] = "uploadfile" as AnyObject?
parameters["Filename"] = "demo\(self.currentTimeStamp)" as AnyObject?
parameters["Ext"] = "jpg" as AnyObject?
parameters["FileToUpload"] = image.jpegData(compressionQuality: 0.5) as AnyObject?
guard let token = UserDefaults.standard.string(forKey: "accesstoken") else {
return
}
print("Create button ACCESS KEY::::- \(token)")
let headers: HTTPHeaders = [
"x-access-token": token
]
Alamofire.upload(multipartFormData: { (multipartFormData:MultipartFormData) in
for (key, value) in parameters {
if key == "FileToUpload" {
multipartFormData.append(
value as! Data,
withName: key,
fileName: "demo\(self.currentTimeStamp)",
mimeType: "image/jpg"
//_img.jpg
)
} else {
//Data other than image
multipartFormData.append((value as! String).data(using: .utf8)!, withName: key)
}}},
to: serviceName, method: .post, headers: headers) { (encodingResult:SessionManager.MultipartFormDataEncodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
//print response.result
print(response.result.value as Any)
}
upload.responseJSON { [self] response in
if let Response = response.result.value as? [String : Any],
let myData = Response["data"] as? [String : Any],
let imgPath = myData["ImagePath"] {
imageUrl = imgPath as! String
print(imageUrl)
print("ImagePath --> ", imgPath)
responseURL = imageUrl
let defaults = UserDefaults.standard
defaults.setValue(imageUrl, forKey: "imageURL")
let key = defaults.object(forKey: "imageURL")
print(key as Any)
self.alamofireRequest(requestURL: "http://192.168.80.21:3204/api/product/create")
}
if let data = response.result.value {
let _ = JSON(data)
}
}
break
case .failure(let encodingError):
print(encodingError)
break
}
}
}

Swift 5.0
pod 'Alamofire', '~> 5.4'
func postImageData(url:String, param:[String:Any], img:Data) {
print("POST URL : ", url)
let header: HTTPHeaders = [
"Content-type": "multipart/form-data"
]
AF.upload(multipartFormData: { (MultipartFormData) in
MultipartFormData.append(img, withName: "image", fileName: "image", mimeType: "image/jpeg")
for (key,value) in param {
MultipartFormData.append((value as! String).data(using: .utf8)!, withName: key)
}
}, to: url, method: .post, headers: header).uploadProgress { (progress) in
print(progress.fractionCompleted)
} .responseJSON { response in
switch response.result {
case .success:
if let JSON = response.value as? [String: Any] {
let flag = JSON["flag"] as! Bool
let code = JSON["code"] as! Int
} else {
}
break
case .failure(let error):
if let data = response.data {
print("Response Error Line No. 265:- \(NSString(data: data, encoding: String.Encoding.utf8.rawValue)!)")
}
break
}
}
}

Related

Alamofire post request for image upload giving status code- 400 in swift

I am trying to upload image to server, but my code sometimes uploads the image and sometimes don't and gives a Status = 400 and says failed to upload file. Can you guys check that out why my code give me this error. And i note it gives me this error sometimes.
Here is the postman requirements:Postman Image.And here is the Status = 400 response:
Response.
Here is my code:
func UPLOD(){
let image = myImageView.image
let serviceName = "http://192.168.80.21:8800/api/v1/upload/uploadfile"
var parameters = [String: Any]()
parameters["Folder"] = "uploadfile"
parameters["Filename"] = "demo3\(self.currentTimeStamp)"
parameters["Ext"] = "jpeg"
parameters["FileToUpload"] = image?.jpegData(compressionQuality: 0.5)
guard let token = UserDefaults.standard.string(forKey: "accesstoken") else {
return
}
print("Create button ACCESS KEY::::- \(token)")
let headers: HTTPHeaders = [
"x-access-token": token,
"Content-type": "multipart/form-data"
]
Alamofire.upload(multipartFormData: { (multipartFormData:MultipartFormData) in
for (key, value) in parameters {
if key == "FileToUpload" {
multipartFormData.append(
value as! Data,
withName: key,
fileName: "demo3\(self.currentTimeStamp)",
mimeType: "image/jpeg"
//_img.jpg
)
} else {
multipartFormData.append((value as! String).data(using: .utf8)!, withName: key)
}}},
to: serviceName, method: .post, headers: headers) { (encodingResult:SessionManager.MultipartFormDataEncodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response.result.value!)
}
upload.responseJSON { [self] response in
if let Response = response.result.value as? [String : Any],
let myData = Response["data"] as? [String : Any],
let imgPath = myData["status"] {
imageUrl = imgPath as! String
print(imageUrl)
print("ImagePath --> ", imgPath)
responseURL = imageUrl
let defaults = UserDefaults.standard
defaults.setValue(imageUrl, forKey: "imageURL")
let key = defaults.object(forKey: "imageURL")
print(key as Any)
self.alamofireRequest(requestURL: "http://192.168.80.21:3204/api/product/create")
}
if let data = response.result.value {
let _ = JSON(data)
}
}
break
case .failure(let encodingError):
print(encodingError)
break
}
}
}

JSON parameter in multipart form PUT request in iOS Swift using AlmoFire

I want to upload image using Multipart/formdata put request in iOS Swift using Almofire Networking which has few parameters and one parameter contains JSON. e.g
"parameter_name":{
"field_1" : {
"type" : "MULTISELECT",
"value" : [
"Option 1",
"Option 3"
],
"name" : "Multi Selection"
},
"field_2" : {
"type" : "DATE",
"name" : "BirthDate",
"value" : "2000-09-08"
},
"field_3" : {
"type" : "SINGLESELECT",
"value" : "Option1",
"name" : "Single Select"
}
}
This is one parameter in multipart formdata with other parameters like name, email, photo and more (all are of type string)
Could anyone help me achieving this as using Swift & AlamoFire As I am receiving 503 status code for this.
Note:- In postman same API is working fine.
What I have done so far is:
Alamofire.upload(multipartFormData: { multipartData in
parameters.forEach { (key, value) in
if let arrdata = (value as? [AnyHashable : Any]) {
if arrdata.count > 0 {
let arrdatas = try! JSONSerialization.data(withJSONObject: arrdata, options: [])
multipartData.append(arrdatas, withName: key as String)
}
}
guard
let data = (value as? String)?
.data(using: .utf8)
else { return }
multipartData.append(data, withName: key)
}
if let img = photo,
let data = UIImageJPEGRepresentation(img, 0.0) {
multipartData
.append(data,
withName: Keys.photo,
fileName: Keys.fileName,
mimeType: Keys.mimeType)
}
},
to: "My URL",
headers: requestType.headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseData(completionHandler: { response in
if let statusCode = response.response?.statusCode,
200 <= statusCode && statusCode < 300,
let data = response.data {
guard
let decoded = try? JSONSerialization.jsonObject(with: data, options: []),
let dic = decoded as? [String: Any] else {
return
}
printOnlyOnDebug("Response got is --> \(self.convertToJSON(toConvert: dic))")
success(data)
} else {
guard
let data = response.data,
let decoded = try? JSONSerialization.jsonObject(with: data, options: []),
let dic = decoded as? [String: Any],
let message = dic[Keys.message] as? String else {
let code = response.response?.statusCode == 503 ? 401 : response.response?.statusCode
failure(code, "Network error")
return
}
failure(response.response?.statusCode, message)
}
})
case .failure(let error):
failure(nil, error.localizedDescription)
}
})
Also header contains 'Content-Type' as 'multipart/form-data'
I forgot to mention method type PUT in AlamoFire request so it was creating POST request and it was causing the issue.
Alamofire.upload(multipartFormData: { multipartData in
parameters.forEach { (key, value) in
if let arrdata = (value as? [AnyHashable : Any]) {
if arrdata.count > 0 {
let arrdatas = try! JSONSerialization.data(withJSONObject: arrdata, options: [])
multipartData.append(arrdatas, withName: key as String)
}
}
guard
let data = (value as? String)?
.data(using: .utf8)
else { return }
multipartData.append(data, withName: key)
}
if let img = photo,
let data = UIImageJPEGRepresentation(img, 0.0) {
multipartData
.append(data,
withName: Keys.photo,
fileName: Keys.fileName,
mimeType: Keys.mimeType)
}
},
to: "My URL",
method:.put,
headers: requestType.headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseData(completionHandler: { response in
if let statusCode = response.response?.statusCode,
200 <= statusCode && statusCode < 300,
let data = response.data {
guard
let decoded = try? JSONSerialization.jsonObject(with: data, options: []),
let dic = decoded as? [String: Any] else {
return
}
printOnlyOnDebug("Response got is --> \(self.convertToJSON(toConvert: dic))")
success(data)
} else {
guard
let data = response.data,
let decoded = try? JSONSerialization.jsonObject(with: data, options: []),
let dic = decoded as? [String: Any],
let message = dic[Keys.message] as? String else {
let code = response.response?.statusCode == 503 ? 401 : response.response?.statusCode
failure(code, "Network error")
return
}
failure(response.response?.statusCode, message)
}
})
case .failure(let error):
failure(nil, error.localizedDescription)
}
})

how to upload image (Multipart) using Alamofire 5.0.0-beta.3 (Swift 5)

I am working on uploading image using multipart. This Code Working fine in swift 4 and Alamofire 4. Please give any solution for this.
public class func callsendImageAPI(param:[String: Any],arrImage:[UIImage],imageKey:String,URlName:String,controller:UIViewController, withblock:#escaping (_ response: AnyObject?)->Void){
Alamofire.upload(multipartFormData:{ MultipartFormData in
for (key, value) in param {
MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
for img in arrImage {
guard let imgData = img.jpegData(compressionQuality: 1) else { return }
MultipartFormData.append(imgData, withName: imageKey, fileName: FuncationManager.getCurrentTimeStamp() + ".jpeg", mimeType: "image/jpeg")
}
},usingThreshold:UInt64.init(),
to: "URL",
method:.post,
headers:["Content-type": "multipart/form-data",
"Content-Disposition" : "form-data"],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, , ):
upload.uploadProgress(closure: { (Progress) in
print("Upload Progress: \(Progress.fractionCompleted)")
})
upload.responseJSON { response in
switch(response.result) {
case .success(_):
let dic = response.result.value as! NSDictionary
if (dic.object(forKey: "status")! as! Int == 1){
withblock(dic.object(forKey: "data") as AnyObject)
}else if (dic.object(forKey: Message.Status)! as! Int == 2){
print("error message")
}else{
print("error message")
}
case .failure(_):
print("error message")
}
}
case .failure(let encodingError):
print("error message")
}
})}
Thanks in advance.
Almofire 5.0 & Swift 5.0
//Set Your URL
let api_url = "YOUR URL"
guard let url = URL(string: api_url) else {
return
}
var urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10.0 * 1000)
urlRequest.httpMethod = "POST"
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
//Set Your Parameter
let parameterDict = NSMutableDictionary()
parameterDict.setValue(self.name, forKey: "name")
//Set Image Data
let imgData = self.img_photo.image!.jpegData(compressionQuality: 0.5)!
// Now Execute
AF.upload(multipartFormData: { multiPart in
for (key, value) in parameterDict {
if let temp = value as? String {
multiPart.append(temp.data(using: .utf8)!, withName: key as! String)
}
if let temp = value as? Int {
multiPart.append("\(temp)".data(using: .utf8)!, withName: key as! String)
}
if let temp = value as? NSArray {
temp.forEach({ element in
let keyObj = key as! String + "[]"
if let string = element as? String {
multiPart.append(string.data(using: .utf8)!, withName: keyObj)
} else
if let num = element as? Int {
let value = "\(num)"
multiPart.append(value.data(using: .utf8)!, withName: keyObj)
}
})
}
}
multiPart.append(imgData, withName: "file", fileName: "file.png", mimeType: "image/png")
}, with: urlRequest)
.uploadProgress(queue: .main, closure: { progress in
//Current upload progress of file
print("Upload Progress: \(progress.fractionCompleted)")
})
.responseJSON(completionHandler: { data in
switch data.result {
case .success(_):
do {
let dictionary = try JSONSerialization.jsonObject(with: data.data!, options: .fragmentsAllowed) as! NSDictionary
print("Success!")
print(dictionary)
}
catch {
// catch error.
print("catch error")
}
break
case .failure(_):
print("failure")
break
}
})
Happy to help you :)
Its Work for me
Please refer Below code.
public class func callsendImageAPI(param:[String: Any],arrImage:[UIImage],imageKey:String,URlName:String,controller:UIViewController, withblock:#escaping (_ response: AnyObject?)->Void){
let headers: HTTPHeaders
headers = ["Content-type": "multipart/form-data",
"Content-Disposition" : "form-data"]
AF.upload(multipartFormData: { (multipartFormData) in
for (key, value) in param {
multipartFormData.append((value as! String).data(using: String.Encoding.utf8)!, withName: key)
}
for img in arrImage {
guard let imgData = img.jpegData(compressionQuality: 1) else { return }
multipartFormData.append(imgData, withName: imageKey, fileName: FuncationManager.getCurrentTimeStamp() + ".jpeg", mimeType: "image/jpeg")
}
},usingThreshold: UInt64.init(),
to: URL.init(string: URlName)!,
method: .post,
headers: headers).response{ response in
if((response.error != nil)){
do{
if let jsonData = response.data{
let parsedData = try JSONSerialization.jsonObject(with: jsonData) as! Dictionary<String, AnyObject>
print(parsedData)
let status = parsedData[Message.Status] as? NSInteger ?? 0
if (status == 1){
if let jsonArray = parsedData["data"] as? [[String: Any]] {
withblock(jsonArray as AnyObject)
}
}else if (status == 2){
print("error message")
}else{
print("error message")
}
}
}catch{
print("error message")
}
}else{
print(response.error!.localizedDescription)
}
}
}
Happy to help you :)

Upload Photo / File with JSON and custom headers via Swift 3 and Alamofire 4 | iOS | Swift

I need to call the Multipart request with Image file and JSON.
I have tried this, but still getting the error.
// define parameters
let parameters = [
"hometown": "yalikavak",
"living": "istanbul"
]
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 1) {
multipartFormData.append(imageData, withName: "file", fileName: "file.png", mimeType: "image/png")
}
for (key, value) in parameters {
multipartFormData.append((value?.data(using: .utf8))!, withName: key)
}}, 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 strongSelf = self else {
return
}
debugPrint(response)
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}
How to send the JSON?
Try This Code for Multiple upload Images in Single Request, This code is already working.
// For Pass Valid Parameters & number of Images in Array in Image Upload Function
var dicImgData : NSMutableDictionary? = NSMutableDictionary()
if let img = UIImage(named: "Your Image") {
if let data:Data = UIImagePNGRepresentation(img) {
var imageData : NSData = data
dicImgData! .setObject(imageData, forKey: "data" as NSCopying)
dicImgData! .setObject("file", forKey: "name" as NSCopying)
dicImgData! .setObject("file.png", forKey: "fileName" as NSCopying)
dicImgData! .setObject("image/png", forKey: "type" as NSCopying)
let dicParameter = [
"hometown": "yalikavak",
"living": "istanbul"
]
self.uploadImage(url: "Your URL", Parameter: dicParameter, Images: [dicImgData])
}
}
Upload Function
func uploadImage (url: String, Parameter param : NSDictionary, Images arrImage: NSArray) -> Void
{
var requestURL : String! = url
let headers = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json",
]
print("---------------------")
print("Request URL :- \(requestURL)")
print("---------------------")
Alamofire.upload(multipartFormData: { (data) in
for (key, value) in param {
data.append((value as! String).data(using: .utf8)!, withName: key as! String)
}
for imageInfo in arrImage
{
var dicInfo : NSDictionary! = imageInfo as! NSDictionary
data.append(dicInfo["data"] as! Data, withName: dicInfo["name"] as! String, fileName: dicInfo["fileName"] as! String, mimeType: dicInfo["type"] as! String)
dicInfo = nil
}
}, to: requestURL, method: .post , headers:nil, encodingCompletion: { (encodeResult) in
switch encodeResult {
case .success(let upload, _, _):
upload.responseJSON(completionHandler: { (response) in
switch response.result
{
case .success(let responseJSON):
guard let dicResponse = responseJSON as? NSDictionary else{
return
}
print("Response : \((dicResponse))")
case .failure(let error):
print(error)
break
}
})
case .failure(let error):
print(error)
break
}
})
}
From data you have given, I comes to an conclusion as given below.
The status code 400 means json you're passing to the api was not following the api documentation. For example if they expect a key "name" and you're not given such a key at all.
Other possible reasons for this error.
Seems like you haven't mentioned any of content types
Add these line of code to assure that the response and your request are in proper formats
Alamofire.request(.GET, "your url", parameters: ["foo": "bar"])
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.response { (_, _, _, error) in
println(error)
}
The Accept header tells the server what your client wants in the
response. The Content-Type header tells the server what the client
sends in the request.
If you can give more information we can help further.
Here I made my custom webservice, You can use it. This webservice is for upload dictionary with image and video or both or without it.
import Foundation
import Alamofire
class WebServiceHandler: AnyObject {
func uploadWithAlamofire(Parameters params : [NSObject : AnyObject]?,ImageParameters imgparams : [NSObject : AnyObject]?,VideoParameters vidoparam : [NSObject : AnyObject]?,Action action : NSString, success: #escaping (AnyObject) -> Void, failure: #escaping (AnyObject) -> Void)
{
var base_url = "http://benzatineinfotech.com/webservice/finder/index.php/Web_api/"
base_url.append(action as String)
Alamofire.upload(multipartFormData: { multipartFormData in
if imgparams != nil{
for (key, value) in imgparams! {
if let imageData = UIImageJPEGRepresentation(value as! UIImage, 1) {
multipartFormData.append(imageData, withName: key as! String, fileName: "\(NSDate().timeIntervalSince1970 * 1000)).jpg", mimeType: "image/jpg")
}
}
}
if vidoparam != nil{
for (key, value) in vidoparam! {
multipartFormData.append(value as! URL , withName: key as! String, fileName: "\(NSDate().timeIntervalSince1970 * 1000).mp4", mimeType: "application/octet-stream")
}
}
if params != nil
{
for (key, value) in params! {
multipartFormData.append((value as! String).data(using: .utf8)!, withName: key as! String)
}
} }, to: base_url, method: .post, headers: nil,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress { progress in
print(progress.fractionCompleted)
}
upload.response { [weak self] response in
guard self != nil else {
return
}
let responseString = String(data: response.data!, encoding: String.Encoding.utf8)
return success(responseString as AnyObject)
}
case .failure(let encodingError):
print("error:\(encodingError)")
return failure(encodingError as AnyObject)
}
})
}
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
}
Usage:
self.webservice.uploadWithAlamofire(Parameters: dict_params as [NSObject : AnyObject], ImageParameters: imgparam as [NSObject : AnyObject], VideoParameters: videoparam as [NSObject : AnyObject], Action: "write_message", success: { (success) in
print(success)
}) { (error) in
print(error)
}

How to upload multiple images in multipart using Alamofire?

I am stuck in uploading multiple images in multipart using Alamofire. Can any one help me?
Thanks in advance!!
For more details, I am using this code to create body part of images data:
func imageArrayToNSData(array: [UIImage],boundary:String) -> NSData {
let body = NSMutableData()
var i = 0;
for image in array{
let filename = "image\(i).jpg"
let data = UIImageJPEGRepresentation(image,0.8);
let mimetype = "image/jpeg"
let key = "product_images"
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"\(key)\"; filename=\"\(filename)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(data!)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
i += 1
}
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
return body
}
to upload I am using :
Alamofire.upload(.POST, EDIT_PRODUCT_URL, headers: ["Accept": "application/json","Content-Type":"application/json"], multipartFormData: { (formData) in
if productImages.count>0{
let boundary = generateBoundaryString()
let imageData = CommonClass.imageArrayToNSData(productImages,boundary: boundary)
formData.appendBodyPart(data: imageData, name: "product_images", mimeType: "image/jpeg")
}
for (key, value) in params {
if value is [String]{
let data = CommonClass.stringArrayToNSData(value as! [String])
formData.appendBodyPart(data:data , name: key)
}else if value is String{
formData.appendBodyPart(data: value.dataUsingEncoding(NSUTF8StringEncoding)!, name: key)
}else if let v = value as? Bool{
var bValue = v
let d = NSData(bytes: &bValue, length: sizeof(Bool))
formData.appendBodyPart(data: d, name: key)
}
}
}) { (encodingResult) in
switch encodingResult {
case .Success(let upload, _, _):
KVNProgress.showProgress(CGFloat(0), status:"0% Sent")
upload.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
// This closure is NOT called on the main queue for performance
// reasons. To update your ui, dispatch to the main queue.
dispatch_async(dispatch_get_main_queue()) {
let prg = Int((CGFloat(totalBytesWritten)*100)/CGFloat(totalBytesExpectedToWrite))
if prg == 100{
KVNProgress.showSuccessWithStatus("Created")
}
KVNProgress.updateStatus("\(prg)% Sent")
KVNProgress.updateProgress(CGFloat(Float(prg)/100.0), animated: true)
}
}
upload.responseJSON { response in
CommonClass.hideLoader()
switch response.result {
case .Success:
if let value = response.result.value {
let json = JSON(value)
print_debug("edit Product JSON is\n\(json)");
completionBlock(json)
}else{
completionBlock(nil)
}
case .Failure(let error):
print_debug(error.description)
showErrorWithMessage("Oops! Couldn't connect to server!")
completionBlock(nil)
}
}
case .Failure(let encodingError):
print(encodingError)
}
}
Can any one please let me suggest the way to upload multiple files in multipart using Alamofire?
In Swift 3 and above
Just append "[]" with image key identifier to treat it as 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)
}
})
I Hope it will be helpful for you:
Using Swift 3x: (I have uploaded four Photos in this snippet)
//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)")
}
})
}
1) To upload multiple image using Alamofire in Swift3
typealias APICompletionHandler = (code:Int, error:NSError?, response:AnyObject?) -> Void
func uploadIMultipart(_ strApiName:String, param : NSDictionary?, data:Array<NSDictionary>, header:[String : String]?, completionHandler:#escaping APICompletionHandler)
{
let strURL : String = strApiName
let apiURL = try! URLRequest(url: strURL, method: .post, headers: header)
Alamofire.upload(multipartFormData: { (multipartFormData) in
// code
var i : Int = 0
for dict:NSDictionary in data {
let extention = dict["format"] as? String
let strMimeType = dict["strMimeType"] as? String
let nameofFile:String = (6.randomString as String)+"."+extention!
if (dict["data"] as? Data != nil) {
multipartFormData.append(Foundation.Data(dict["data"] as! Data), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)
} else {
let strUrl = dict["data"] as! String
let fileURL : URL? = URL(string: strUrl)
multipartFormData.append(try! Foundation.Data(contentsOf: fileURL!), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)
}
i += 1
}
for (key, value) in param! {
multipartFormData.append((value as! NSString).data(using: String.Encoding.utf8.rawValue)!, withName: key as! String)
}
}, with: apiURL, encodingCompletion: { (result) in
// code
switch result {
case .success(let upload,_ ,_ ):
upload.responseJSON { response in
switch response.result {
case .success(let data):
//Sucess
case .failure(let error):
print(error.localizedDescription)
}
}
case .failure(let encodingError):
print(encodingError)
completionHandler(0, encodingError as NSError?, nil)
}
})
}
2) To call Function
let imageData : NSData = UIImagePNGRepresentation(imgUserProfile.image!)! as NSData
let imageData1 : NSData = UIImagePNGRepresentation(imgUserProfile.image!)! as NSData
let dict1: Dictionary = ["data":imageData,"key":"user_image", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
let dict2: Dictionary = ["data":imageData1,"key":"image1", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
let array: Array = [dict1,dict2]; //pass this image array
self.uploadIMultipart(strAPI, param: dictParam as NSDictionary, data: array as Array<NSDictionary>, header: nil) { (code, error, response) in
AppSingletonObj.stopLoading(inView: self.view)
//API manager sucess or failure
if code == 1 {
let status = response?["success"]
//API sucess or failure
if(status as! Int == 1) {
print(response!)
}
else {
let errorMessage = response?["message"]
AppSingletonObj.showAlert(msg: errorMessage as! String)
}
}
else {
AppSingletonObj.showAlert(msg: "Some error occured! please try after sometime")
}
}
3) Extension to create file name
//MARK: CREATE RANDOM STRING of LENGTH
extension Int{
var randomString : String {
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomString : NSMutableString = NSMutableString(capacity: self)
for _ in 0 ..< self{
let length = UInt32 (letters.length)
let rand = arc4random_uniform(length)
randomString.appendFormat("%C", letters.character(at: Int(rand)))
}
return randomString as String
}
}
To upload multiple image you need to call this code in loop
let boundary = generateBoundaryString()
let imageData = CommonClass.imageArrayToNSData(productImages,boundary: boundary)
formData.appendBodyPart(data: imageData, name: "product_images", mimeType: "image/jpeg")
Swift 4.2.
Here code is only for without any parameters.
If you need to pass extra parameters just go with #Hardik Thakkar code.
typealias APICompletionHandler = (code:Int, error:NSError?, response:AnyObject?) -> Void
#IBOutlet weak var thirdImage: UIImageView!
var fristImage:UIImage = UIImage()
var secondimage:UIImage = UIImage()
extension ViewController {
func upload() {
let imgData1 = fristImage.jpegData(compressionQuality: 0.7)
let imgData2 = secondimage.jpegData(compressionQuality: 0.7)
let imgData3 = thirdImage.image!.jpegData(compressionQuality: 0.7)
let headers = [
"Authorization" : "Bearer " + "Your Token",
"Content-type": "form-data",
]
let dict1: Dictionary = ["data":imgData1 as Any,"key":"Here Your Body Key1", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
let dict2: Dictionary = ["data":imgData2 as Any,"key":"Here Your Body Key2", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
let dict3: Dictionary = ["data":imgData3 as Any,"key":"Here Your Body Key3", "format":"jpg", "strMimeType":"image/jpeg"] as [String : Any]
let array: Array = [dict1, dict2, dict3]; //pass this image array
self.uploadIMultipart("Here Your URL", data: array as Array<NSDictionary>, header: headers) { (code, error, response) in
let httpResponse = response as? HTTPURLResponse
print("the resopnse code is : \(String(describing: httpResponse?.statusCode.description))")
}
}
func uploadIMultipart(_ strApiName:String, data:Array<NSDictionary>, header:[String : String]?, completionHandler:#escaping APICompletionHandler) {
let strURL : String = strApiName
let apiURL = try! URLRequest(url: strURL, method: .post, headers: header)
Alamofire.upload(multipartFormData: { (multipartFormData) in
// code
var i : Int = 0
for dict:NSDictionary in data {
let extention = dict["format"] as? String
let strMimeType = dict["strMimeType"] as? String
let nameofFile:String = (6.randomString as String)+"."+extention!
if (dict["data"] as? Data != nil) {
multipartFormData.append(Foundation.Data(dict["data"] as! Data), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)
} else {
let strUrl = dict["data"] as! String
let fileURL : URL? = URL(string: strUrl)
multipartFormData.append(try! Foundation.Data(contentsOf: fileURL!), withName: dict["key"] as! String, fileName: nameofFile , mimeType: strMimeType!)
}
i += 1
}
}, with: apiURL, encodingCompletion: { (result) in
// code
switch result {
case .success(let upload,_ ,_ ):
upload.responseJSON { response in
switch response.result {
case .success(let response):
//Sucess
print("response :-", response)
case .failure(let error):
//Failure
print(error.localizedDescription)
}
}
case .failure(let encodingError):
print(encodingError)
completionHandler(0, encodingError as NSError?, nil)
}
})
}
}
extension Int{
var randomString : String {
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let randomString : NSMutableString = NSMutableString(capacity: self)
for _ in 0 ..< self{
let length = UInt32 (letters.length)
let rand = arc4random_uniform(length)
randomString.appendFormat("%C", letters.character(at: Int(rand)))
}
return randomString as String
}
}
class func uploadImageToServer(uploadTo: String, imageParameters:[[String: Any]], otherParameters:[String: Any],authorization: String, completionHandler:#escaping ((_ responseValue: Any?, _ error: Error?) -> Void)) {
if isNetWorkAvailable() {
var urlRequest = URLRequest(url: URL.init(string: uploadTo)!)
urlRequest.httpMethod = "POST"
urlRequest.addValue(authorization, forHTTPHeaderField: "Authorization")
DispatchQueue.main.async(execute: {
ActivityIndicatorView.showActivity()
})
print("Request Url: \(uploadTo)\nRequest Params: \(imageParameters)\nRequest Params: \(otherParameters)")
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key,value) in otherParameters {
multipartFormData.append((value as! String).data(using: .utf8)!, withName: key)
}
for value in imageParameters {
let image = value["image"] as! UIImage
let imgData = UIImageJPEGRepresentation(image, 1)!
let imageName = value["imageName"] as! String
let fileName = value["fileName"] as! String
multipartFormData.append(imgData, withName: imageName, fileName: fileName ,mimeType: "image/jpeg")
}
}, usingThreshold: UInt64.init(), with: urlRequest, encodingCompletion: { (encodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
let uploadPercetange = Int(progress.fractionCompleted*100)
print("Upload Progress: \(uploadPercetange)%")
})
upload.responseJSON(completionHandler: { (response) in
print(response.result.value ?? "NaN")
let result = response.result.value
completionHandler(result, nil)
DispatchQueue.main.async(execute: {
ActivityIndicatorView.hideActivity()
})
})
case .failure(let encodingError):
print(encodingError)
let error = encodingError
completionHandler(nil, error)
DispatchQueue.main.async(execute: {
ActivityIndicatorView.hideActivity()
})
}
})
} else {
AlertView.showAlert(title: "Error", message: "Network not available")
}
}

Resources