How to upload multiple images in multipart using Alamofire? - ios

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

Related

Uploading image to server with parameter error swift

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

upload image from multipart-from-data using Alamofire '~> 5.0.0-beta.3'

func uploadImage(image: UIImage, imageUrl: String, imageExtension: String , responseData: #escaping (_ response: UploaderModel)-> ()) {
var status : UploaderModel?
let token = UserDefaults.standard.string(forKey: PrefKeys.loginToken) ?? ""
let authorization = ["Authorization" : "Bearer \(token)"]
let imageURl = "http://68.183.152.132/api/v1/stuff/uploader"
//Parameter HERE
let parameters = [
"garbageCollector": 0,
"stuff_uuid": "2b4b750a-f4a6-4d61-84ce-7c42b5c030ee",
"delete_file" : ""
] as [String : Any]
//Header HERE
let headers: HTTPHeaders
headers = ["Content-type": "multipart/form-data",
"Content-Disposition" : "form-data"]
guard let imgData = firstImage.image?.jpegData(compressionQuality: 0.7) else { return }
AF.upload(multipartFormData: { multipartFormData in
//Parameter for Upload files
multipartFormData.append(imgData, withName: "file",fileName: imageUrl , mimeType: "image/\(imageExtension)")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
}, usingThreshold:UInt64.init(),
to: imageURl, //URL Here
method: .post,
headers: headers, //pass header dictionary here
interceptor: { (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Uploading")
})
upload.responseJSON { response in
print("the resopnse code is : \(response.response?.statusCode)")
print("the response is : \(response.description)")
let json = JSON(response.data)
if let msg = json["msg"].string {
status.msg = msg
}
if let stat = json["status"].int {
status.status = stat
}
responseData(status)
}
break
case .failure(let encodingError):
print("the error is : \(encodingError.localizedDescription)")
break
}
} )
}
error : Cannot convert value of type '(_) -> ()' to expected argument type 'RequestInterceptor?'
A little bit cleaner look solution of Vishal Darvara asnwer for Alamofire 5 .
func uploadPhoto(_ url: String, image: UIImage, params: [String : Any], header: [String:String], completion: #escaping (JSON) -> ()) {
let httpHeaders = HTTPHeaders(header)
AF.upload(multipartFormData: { multiPart in
for p in params {
multiPart.append("\(p.value)".data(using: String.Encoding.utf8)!, withName: p.key)
}
multiPart.append(image.jpegData(compressionQuality: 0.4)!, withName: "avatar", fileName: "file.jpg", mimeType: "image/jpg")
}, to: url, method: .post, headers: httpHeaders) .uploadProgress(queue: .main, closure: { progress in
print("Upload Progress: \(progress.fractionCompleted)")
}).responseJSON(completionHandler: { data in
print("upload finished: \(data)")
}).response { (response) in
switch response.result {
case .success(let resut):
print("upload success result: \(resut)")
case .failure(let err):
print("upload err: \(err)")
}
}
}
//swift 5
static func postComplexPictures(url:URL, params:[String:Any],pictures : UIImage, finish: #escaping ((message:String, list:[[String: Any]],isSuccess:Bool)) -> Void) {
var result:(message:String, list:[[String: Any]],isSuccess:Bool) = (message: "Fail", list:[],isSuccess : false)
let headers: HTTPHeaders
headers = ["Content-type": "multipart/form-data",
"Content-Disposition" : "form-data"]
AF.upload(multipartFormData: { (multipartFormData) in
for (key, value) in params {
multipartFormData.append((value as! String).data(using: String.Encoding.utf8)!, withName: key)
}
if let imageData = pictures.pngData() {
multipartFormData.append(imageData, withName: "document", fileName: "document.png", mimeType: "image/png")
}
}, usingThreshold: UInt64.init(), to: url, 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["status"] as? NSInteger ?? 0
let msg = parsedData["message"] as? String ?? ""
if(status==1)
{
result.isSuccess = true
result.message=msg
if let jsonArray = parsedData["data"] as? [[String: Any]] {
result.list=jsonArray
}
}
else
{
result.isSuccess = false
result.message=msg
}
}
finish(result)
}
catch
{
finish(result)
}
}
else
{
finish(result)
}
}
}

Alamofire multipart upload giving error

I am trying to upload an image to server using Alamofire Multipart Form data however upon execution iam getting error as
exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber
dataUsingEncoding:]: unrecognized selector sent to instance
0x1669e250'
in the line
MultipartFormData.append(((value as AnyObject).data(using: String.Encoding.utf8.rawValue))!, withName: key)
below is my full code
guard let image = selectedImage else {
return
}
let heightInPixels = Int(image.size.height * image.scale)
let widthInPixels = Int(image.size.width * image.scale)
let parameters: Parameters = ["user_id": Utility().getBearerToken(),"description": descriptionTextView.text ?? "",
"lat": self.lat ?? "" , "long":self.long ?? "" ,
"location_name": locationTextView.text ?? "" ,
"height": heightInPixels, "width": widthInPixels];
// let parameters: Parameters = ["user_id": Utility().getBearerToken()];
print(parameters)
Alamofire.upload(multipartFormData: { MultipartFormData in
for (key, value) in parameters {
MultipartFormData.append(((value as AnyObject).data(using: String.Encoding.utf8.rawValue))!, withName: key)
}
let imgData = UIImageJPEGRepresentation(image,1)
MultipartFormData.append(imgData!, withName: "file", fileName: "upload.jpg", mimeType: "image/jpeg")
}, to: "http://server.com/upload.php") { (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (Progress) in
print("Upload Progress: \(Progress.fractionCompleted)")
})
upload.responseString { response in
print(response.result.value!)
}
case .failure(let encodingError):
print(encodingError.localizedDescription)
break
}
}
I tried with MultipartFormData.append(value.data(using: .utf8)!, withName: name!) but it says value has no member data
Try this below func, it is working.
func uploadImage(urlString : String , image : UIImage, param : [String : Any], completionHandler : #escaping ( _ result : Any?) -> ()) {
guard let imageData = UIImageJPEGRepresentation(image, 0.5) else {
print("Could not get JPEG representation of UIImage")
return
}
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in param {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
multipartFormData.append(imageData,
withName: "image",
fileName: "image.jpg",
mimeType: "image/jpeg")
},
to: urlString,
headers: ["Authorization": "Basic xxx"],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress { progress in
}
upload.validate()
upload.responseJSON { response in
completionHandler(response.result.value)
}
case .failure(let encodingError):
print(encodingError)
completionHandler(nil)
}
})
}
Here is the function for upload video and image with your other API Parameters.
func uploadWithAlamofire(Parameters params : [String: Any]?,ImageParameters imgparams : [NSObject : AnyObject]?,VideoParameters vidoparam : [NSObject : AnyObject]?,Action action : NSString, success: #escaping (AnyObject) -> Void, failure: #escaping (AnyObject) -> Void)
{
var base_url = BASEURL
base_url.append(action as String)
print(base_url)
var headers : HTTPHeaders = [:]
if let token = UserDefaults.standard.value(forKey: "webToken"){
headers = ["JWT-Authorization": "Bearer \(token)"]
}
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: headers,
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)
var dictonary:NSDictionary?
if let data = responseString?.data(using: String.Encoding.utf8) {
do {
dictonary = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject] as NSDictionary?
if dictonary != nil{
if dictonary?.value(forKey: "status_code") as! String == "200"{
return success(dictonary!)
}else{
print(dictonary?.value(forKey: "status_code")! as Any)
let errorMsg : Any = Int(dictonary?.value(forKey: "status_code") as Any)
utility.showAlertWithStatusCode(code: errorMsg)
}
}
} catch let error as NSError {
print(error)
}
}
}
case .failure(let encodingError):
print("error:\(encodingError)")
return failure(encodingError as AnyObject)
}
})
}

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

Image upload with paramteres in MultiPartFormData is not working in Alamofire 4.0

I am using this function to upload multiple images with parameters in post method in Alamofire. My image is not uploading. I cross checked there is no entry of image on server but other data successfully stored in DB .
I was using this method in Alamofire 3.0 and now I updated to 4.0 . Other post and get function are working fine for me.
static func callUploadApi (_ url: String , parameter:[String: String] , images: [URL] , imageParameterName:String ,showHud:Bool , handler: #escaping (_ result : NSMutableDictionary) -> Void )
{
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in parameter // Add Paramters
{
multipartFormData.append(value.data(using: .utf8 )! , withName: key)
}
for imageUrl in images // Add Images
{
multipartFormData.append(imageUrl, withName: imageParameterName)
}
}, to: "\(baseUrl)\(url)", method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
print(upload.progress)
upload.responseJSON { response in
if let JSON = response.result.value
{
print("***********************************************")
print("JSON: \(JSON)")
print("***********************************************")
handler(JSON as! NSMutableDictionary)
}
}
break
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}
func urlRequestWithComponents(urlString:String, parameters:Dictionary<String, String>, imageData:NSData) -> (URLRequestConvertible, NSData) {
let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!)
mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue
let boundaryConstant = "------------0x0x0x0x0x0x0x0x";
let contentType = NSString(format: "multipart/form-data;boundary=%#",boundaryConstant)
mutableURLRequest.setValue(contentType as String, forHTTPHeaderField: "Content-Type")
let uploadData = NSMutableData()
uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData(NSString(format: "Content-Disposition: form-data; name=\"file\";filename=\"%#\"\r\n", self.imageURL).dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData("Content-Type: application/octet-stream\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
uploadData.appendData(imageData)
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)!)
return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
}
This worked for me, I write this for my need. Anyone can change it according to there need.
static func upload( _ url : String ,
parameter : [String : String] = [:],
arrayImage : [String : UIImage],
shouldShowHud : Bool = true,
completionHandler : #escaping (_ result : NSDictionary , _ status : Bool) -> Void )
{
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in parameter{
multipartFormData.append(value.data(using: .utf8 )! , withName: key)
}
for (key, value) in arrayImage {
if let imageData = UIImageJPEGRepresentation(imageUrl, 0.5) {
multipartFormData.append(imageData , withName: key, fileName: "file.jpeg", mimeType: "image/jpeg")
}
}
}, to: MainUrl+url , method: .post, headers : Header, encodingCompletion: { encodingResult in
switch encodingResult{
case .success(let upload, _, _):
print("Upload Progress \(upload.uploadProgress.completedUnitCount) '\' \(upload.uploadProgress.totalUnitCount)")
upload.responseJSON { response in
if let JSON = response.result.value {
let status = (JSON as! NSDictionary)["status"] as? Bool
completionHandler(JSON as! NSDictionary , status!)
} else {
let result : NSDictionary = ["message" : "Request Time out, please refresh again." as Any]
completionHandler( result as NSDictionary , false)
}
}
break
case .failure:
let result : NSDictionary = ["message" : "Request Time out, please refresh again." ]
completionHandler( result as NSDictionary , false)
break
}
}
)
}

Resources