Getting image URL after uploading to Imgur API using Swift 3 - ios

I am uploading images anonymously using the Imgur API and Alamofire. However, I am not getting the url in the response json. Here is my code:
static func post(image: UIImage, for username: String) {
let imageData = UIImagePNGRepresentation(image)
let base64Image = imageData?.base64EncodedString(options: .lineLength64Characters)
let url = "https://api.imgur.com/3/upload"
let parameters = [
"image": base64Image
]
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 1) {
multipartFormData.append(imageData, withName: username, fileName: "\(username).png", mimeType: "image/png")
}
for (key, value) in parameters {
multipartFormData.append((value?.data(using: .utf8))!, withName: key)
}}, to: url, method: .post, headers: ["Authorization": "Client-ID " + Constants.IMGUR_CLIENT_ID],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { response in
print(response) // url nowhere to be found
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}
Here is the printed response:

The issue in your code is that you are just printing the response of the request, you actually need to parse that into JSON and than check the response of your request, it does contain the image url you just uploaded.
This is how you should parse the response and get the image url.
static func post(image: UIImage, for username: String) {
let imageData = UIImagePNGRepresentation(image)
let base64Image = imageData?.base64EncodedString(options: .lineLength64Characters)
let url = "https://api.imgur.com/3/upload"
let parameters = [
"image": base64Image
]
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 1) {
multipartFormData.append(imageData, withName: username, fileName: "\(username).png", mimeType: "image/png")
}
for (key, value) in parameters {
multipartFormData.append((value?.data(using: .utf8))!, withName: key)
}}, to: url, method: .post, headers: ["Authorization": "Client-ID " + Constants.IMGUR_CLIENT_ID],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { response in
//This is what you have been missing
let json = try? JSONSerialization.jsonObject(with: response.data!, options: .allowFragments) as! [String:Any]
print(json)
let imageDic = json?["data"] as? [String:Any]
print(imageDic?["link"])
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}

Related

How to send array in params using Alamofire multipart

I am using Alamofire for uploading image and file to the server. But I am facing issue to send an array in parameters with the image. But when I send an array in params it converts the array in JSON string. But I want to send an array in params, not JSON string. I have searched a lot and did not find any solution. So please tell me what's wrong in my code. I am using below code:
let params = ["id":"112","arrayParam":["1232","12344","14325"]]
let url = www.khxjjhdfsj.com/hsdgs
let headers: HTTPHeaders = [
/* "Authorization": "your_access_token", in case you need authorization header */
"Content-type": "multipart/form-data"
]
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in params
{
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
if let data = imageData
{
multipartFormData.append(data, withName: "file", fileName: fileName, mimeType: "image/png")
}
if let data = pdfData
{
multipartFormData.append(data, withName: "file", fileName: fileName, mimeType:"application/pdf")
}
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
switch result{
case .success(let upload, _, _):
upload.responseJSON { response in
print("Succesfully uploaded")
if let err = response.error
{
onError?(err)
return
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
onError?(error)
}
}
You need to pass image parameter along with your other request parameters. Pass your array parameters like this in below code:
Alamofire.upload(
multipartFormData: { multipartFormData in
// Pass your image parameter in imgObj
if let imageData = UIImageJPEGRepresentation(imgObj, 1) {
multipartFormData.append(UIImagePNGRepresentation(imgObj)!, withName: "profile_image", fileName: "THDC", mimeType: "image/png")
}
// Send other request parameters
for (key, value) in yourArray {
multipartFormData.append((value as! String).data(using: .utf8)!, withName: key)
}
},to: YourURL,headers:[:],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
SVProgressHUD.dismiss()
debugPrint("SUCCESS RESPONSE: \(response)")
if let dicObj = response.result.value as? NSDictionary {
print(dicObj)
}
}
case .failure(let encodingError):
SVProgressHUD.dismiss()
print("ERROR RESPONSE: \(encodingError)")
}
}
)
This is the static way to upload arrays to Alamofire.
hope this may useful to you.
Alamofire.upload(multipartFormData: { (multipartFormData) in
let imageData = UIImageJPEGRepresentation(imageUpload!, 0.5)
multipartFormData.append(imageData!, withName: "profile_file", fileName: "file.png", mimeType: "image/jpg")
for (key, value) in parameters {
if (value as AnyObject).isKind(of: NSMutableArray.self)
{
let arrayObj = value as! NSMutableArray
//let data2 = NSData(bytes: &arrayObj, length: arrayObj.count)
let count : Int = arrayObj.count
for i in 0 ..< count
{
let value = arrayObj[i] as! Int
let valueObj = String(value)
let keyObj = key + "[" + String(i) + "]"
multipartFormData.append(valueObj.data(using: String.Encoding.utf8)!, withName: keyObj)
}
}
else{
var valueStr = String()
if let param = value as? String{
valueStr = param
}else{
let valueInt = value as! Int
valueStr = String(valueInt)
}
multipartFormData.append((valueStr).data(using: String.Encoding.utf8)!, withName: key)
}
}
}, to: urlString, encodingCompletion: { (encodingResult) in
print("=====encodingResult=========",encodingResult)
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON(completionHandler: { (response) -> Void in
switch response.result {
case .success(let JSON):
print("JSON: \(JSON)")
onCompletion(JSON as? NSDictionary, nil)
case .failure(let error):
print(error)
}
})
case .failure(let encodingError):
print(encodingError);
}
})
You need to append array with multipart data on the same key required, like in your code you need to change only given line of code:
for (key, value) in params
{
// check the key on which key array is coming
if key == "arrayParam" {
let arrData = try! JSONSerialization.data(withJSONObject: value, options: .prettyPrinted)
multipartFormData.append(arrData, withName: key as String)
}
else {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
}
Rest will be the same.

How to upload image using Alamofire with token&parameters?

I use Alamofire to upload images, however the upload is unsuccessful. I also bring token & parameters to server.
I don't know whether I add token & parameters correctly or not.
What's wrong with me to using Alamofire?
Have any suggestion?
Thanks.
func uploadWithAlamofire(image:UIImage, imageData:Data, imageUrl:URL) {
let parameters = ["avatar":imageData]
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: user.id, fileName: "\(user.id).jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append(value, withName: key)
}
}, to: apiUrl , method: .put, headers: ["Authorization": "Bearer \(token)"],
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { [weak self] response in
guard self != nil else {
return
}
debugPrint(response)
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
photoImage = info[UIImagePickerControllerOriginalImage] as! UIImage
photoImageView.image = photoImage
let imageName:String = user.id + ".jpg"
let documentsPath = NSHomeDirectory().appending("/Documents/Icon/")
let imagePath = documentsPath.appending(imageName)
let imageUrl = URL(fileURLWithPath: imagePath)
print("imageUrl is here:\(imageUrl)")
let imageData:Data = UIImageJPEGRepresentation(photoImage, 0.001)!
do {
try imageData.write(to: imageUrl,options: .atomic)
} catch let error {
print(error)
}
uploadWithAlamofire(image: photoImage, imageData: imageData, imageUrl: imageUrl)
self.dismiss(animated: true, completion: nil)
}
Try this:
func uploadImageWith(param params:Dictionary<String,String>,image:UIImage?,handler:#escaping ((Dictionary<String,Any>?,Int) -> Void)) {
// let keyJson = "json".dataUsingEncoding(NSUTF8StringEncoding)!
print("Params:\(params)")
let BASE_URL = "http://"
Alamofire.upload(
multipartFormData: { multipartFormData in
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8, allowLossyConversion: false)!, withName: key)
}
if image != nil{
let imgData = UIImageJPEGRepresentation(image!, 0.5)
if imgData != nil {
multipartFormData.append(imgData!, withName: "photo_upload", fileName: "file.png", mimeType: "image/png")
}
}
},
to: BASE_URL,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
switch response.result {
case .success:
if let jsonDict = response.result.value as? Dictionary<String,Any> {
print_debug("Json Response: \(jsonDict)") // serialized json response
handler(jsonDict,(response.response!.statusCode))
}
else{
handler(nil,(response.response!.statusCode))
}
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Server Response: \(utf8Text)") // original server data as UTF8 string
}
break
case .failure(let error):
handler(nil,(response.response!.statusCode))
break
}
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
USE
uploadImageWith(param: ["key":"value"], image: UIImage(name:"icon")) { (response, statusCode) in
print(response)
}
You have to pass the params and image object and you get the response as a Dictionary object in closure.
Use this function to upload image to the server with token and parameters
func uploadImageAndData(){
var parameters = [String:AnyObject]()
parameters = ["token": token,
"Name": Name]
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)
}
})}
Works for the Alamofire 3.0+

How to upload file using Alamofire with base64EncodedString?

How to upload base64EncodedString on the server using Alamofire.upload?
My upload file URL accepts the file in base64.
And when the upload completes sending the response in JSON format.
How to upload and read the response?
func uploadWithAlamofire() {
let image = #imageLiteral(resourceName: "cartest")
let imageData:NSData = UIImagePNGRepresentation(image)! as NSData
// let imagencoded:String = imageData.base64EncodedString(options: [])
let params = ["token": "454545sddsddf",
"filepath": "/",
"filearea": "draft"]
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(image, 1) {
multipartFormData.append(imageData, withName: "filecontent", fileName: "filetest.jpg", mimeType: "image/jpg")
}
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
}, to: "http://myuploadurl.php", method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { [weak self] response in
guard let strongSelf = self else {
return
}
debugPrint("DATA RESPOND======== \(response)")
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}

Upload an image (Base64) using Alamofire Swift 3

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

Send POST parameters with MultipartFormData using Alamofire, in iOS Swift

I am using Alamofire, very first time. I am using the latest version Alamofire 1.3.1. I want to send one image , one video and some POST parameters in one API call. I am using multipart form data. The mutipart module is working. I am facing a problem to send extra POST parametersparams . Below is my code. "params" is the dictionary which contains extra parameters? How can I append these POST parameters in the request. Please help
var fullUrl :String = Constants.BASE_URL + "/api/CompleteChallenge"
var params = [
"authKey": Constants.AuthKey,
"idUserChallenge": "16",
"comment": "",
"photo": imagePath,
"video": videoPath,
"latitude": "1",
"longitude": "1",
"location": "india"
]
let imagePathUrl = NSURL(fileURLWithPath: imagePath!)
let videoPathUrl = NSURL(fileURLWithPath: videoPath!)
Alamofire.upload(
.POST,
URLString: fullUrl, // http://httpbin.org/post
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(fileURL: imagePathUrl!, name: "photo")
multipartFormData.appendBodyPart(fileURL: videoPathUrl!, name: "video")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, JSON, error in
}
}
case .Failure(let encodingError):
}
}
)
I found the solution :) finally.
We can append data in the request as multipartformdata.
Below is my code.
Alamofire.upload(
.POST,
URLString: fullUrl, // http://httpbin.org/post
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(fileURL: imagePathUrl!, name: "photo")
multipartFormData.appendBodyPart(fileURL: videoPathUrl!, name: "video")
multipartFormData.appendBodyPart(data: Constants.AuthKey.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"authKey")
multipartFormData.appendBodyPart(data: "\(16)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"idUserChallenge")
multipartFormData.appendBodyPart(data: "comment".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"comment")
multipartFormData.appendBodyPart(data:"\(0.00)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"latitude")
multipartFormData.appendBodyPart(data:"\(0.00)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"longitude")
multipartFormData.appendBodyPart(data:"India".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"location")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.responseJSON { request, response, JSON, error in
}
case .Failure(let encodingError):
}
}
)
EDIT 1: For those who are trying to send an array instead of float, int or string, They can convert their array or any kind of data-structure in Json String, pass this JSON string as a normal string. And parse this json string at backend to get original array
In Alamofire 4 it is important to add the body data before you add the file data!
let parameters = [String: String]()
[...]
self.manager.upload(
multipartFormData: { multipartFormData in
for (key, value) in parameters {
multipartFormData.append(value.data(using: .utf8)!, withName: key)
}
multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg")
},
to: path,
[...]
)
This is how i solve my problem
let parameters = [
"station_id" : "1000",
"title": "Murat Akdeniz",
"body": "xxxxxx"]
let imgData = UIImageJPEGRepresentation(UIImage(named: "1.png")!,1)
Alamofire.upload(
multipartFormData: { MultipartFormData in
// multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg")
for (key, value) in parameters {
MultipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
MultipartFormData.append(UIImageJPEGRepresentation(UIImage(named: "1.png")!, 1)!, withName: "photos[1]", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
MultipartFormData.append(UIImageJPEGRepresentation(UIImage(named: "1.png")!, 1)!, withName: "photos[2]", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
}, to: "http://platform.twitone.com/station/add-feedback") { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response.result.value)
}
case .failure(let encodingError): break
print(encodingError)
}
}
Swift 3 / Alamofire 4.0 (Addendum to the accepted answer)
To append to multipartFormData in Swift 3 / Alamofire 4.0, use the following method of MultipartFormData:
public func append(_ data: Data, withName name: String) { /* ... */ }
And, to convert String to Data, the data(using:) method of String. E.g.,
multipartFormData.append("comment".data(using: .utf8)!, withName: "comment")
For Swift 4.2 / Alamofire 4.7.3
Alamofire.upload(multipartFormData: { multipart in
multipart.append(fileData, withName: "payload", fileName: "someFile.jpg", mimeType: "image/jpeg")
multipart.append("comment".data(using: .utf8)!, withName :"comment")
}, to: "endPointURL", method: .post, headers: nil) { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { answer in
print("statusCode: \(answer.response?.statusCode)")
}
upload.uploadProgress { progress in
//call progress callback here if you need it
}
case .failure(let encodingError):
print("multipart upload encodingError: \(encodingError)")
}
}
Also you could take a look at CodyFire lib it makes API calls easier using Codable for everything.
Example for Multipart call using CodyFire
//Declare your multipart payload model
struct MyPayload: MultipartPayload {
var attachment: Attachment //or you could use just Data instead
var comment: String
}
// Prepare payload for request
let imageAttachment = Attachment(data: UIImage(named: "cat")!.jpeg(.high)!,
fileName: "cat.jpg",
mimeType: .jpg)
let payload = MyPayload(attachment: imageAttachment, comment: "Some text")
//Send request easily
APIRequest("endpoint", payload: payload)
.method(.post)
.desiredStatus(.created) //201 CREATED
.onError { error in
switch error.code {
case .notFound: print("Not found")
default: print("Another error: " + error.description)
}
}.onSuccess { result in
print("here is your decoded result")
}
//Btw normally it should be wrapped into an extension
//so it should look even easier API.some.upload(payload).onError{}.onSuccess{}
You could take a look at all the examples in lib's readme
Alamofire 5 and above
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(Data("one".utf8), withName: "one")
multipartFormData.append(Data("two".utf8), withName: "two")
},
to: "https://httpbin.org/post").responseDecodable(of: MultipartResponse.self) { response in
debugPrint(response)
}
documentation link: multipart upload
Swift 5, update #Ankush's Alamofire Code to
var fullUrl = "http://httpbin.org/post" // for example
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append( imagePathUrl! , withName: "photo")
multipartFormData.append( videoPathUrl!, withName: "video")
multipartFormData.append(Constants.AuthKey.data(using: .utf8, allowLossyConversion: false)!, withName: "authKey")
multipartFormData.append("16".data(using: .utf8, allowLossyConversion: false)!, withName: "idUserChallenge")
multipartFormData.append("111".data(using: .utf8, allowLossyConversion: false)!, withName: "authKey")
multipartFormData.append("comment".data(using: .utf8, allowLossyConversion: false)!, withName: "comment")
multipartFormData.append("0.00".data(using: .utf8, allowLossyConversion: false)!, withName: "latitude")
multipartFormData.append("0.00".data(using: .utf8, allowLossyConversion: false)!, withName: "longitude")
multipartFormData.append("India".data(using: .utf8, allowLossyConversion: false)!, withName: "location")
}, to: fullUrl, method: .post) { (encodingResult) in
switch encodingResult {
case .success(request: let upload, streamingFromDisk: _, streamFileURL: _):
upload.responseJSON { (response) in // do sth }
case .failure(let encodingError):
()
}
}
As in Swift 3.x for upload image with parameter we can use below alamofire upload method-
static func uploadImageData(inputUrl:String,parameters:[String:Any],imageName: String,imageFile : UIImage,completion:#escaping(_:Any)->Void) {
let imageData = UIImageJPEGRepresentation(imageFile , 0.5)
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData!, withName: imageName, fileName: "swift_file\(arc4random_uniform(100)).jpeg", mimeType: "image/jpeg")
for key in parameters.keys{
let name = String(key)
if let val = parameters[name!] as? String{
multipartFormData.append(val.data(using: .utf8)!, withName: name!)
}
}
}, to:inputUrl)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (Progress) in
})
upload.responseJSON { response in
if let JSON = response.result.value {
completion(JSON)
}else{
completion(nilValue)
}
}
case .failure(let encodingError):
completion(nilValue)
}
}
}
Note: Additionally if our parameter is array of key-pairs then we can
use
var arrayOfKeyPairs = [[String:Any]]()
let json = try? JSONSerialization.data(withJSONObject: arrayOfKeyPairs, options: [.prettyPrinted])
let jsonPresentation = String(data: json!, encoding: .utf8)
Well, since Multipart Form Data is intended to be used for binary ( and not for text) data transmission, I believe it's bad practice to send data in encoded to String over it.
Another disadvantage is impossibility to send more complex parameters like JSON.
That said, a better option would be to send all data in binary form, that is as Data.
Say I need to send this data
let name = "Arthur"
let userIDs = [1,2,3]
let usedAge = 20
...alongside with user's picture:
let image = UIImage(named: "img")!
For that I would convert that text data to JSON and then to binary alongside with image:
//Convert image to binary
let data = UIImagePNGRepresentation(image)!
//Convert text data to binary
let dict: Dictionary<String, Any> = ["name": name, "userIDs": userIDs, "usedAge": usedAge]
userData = try? JSONSerialization.data(withJSONObject: dict)
And then, finally send it via Multipart Form Data request:
Alamofire.upload(multipartFormData: { (multiFoormData) in
multiFoormData.append(userData, withName: "user")
multiFoormData.append(data, withName: "picture", mimeType: "image/png")
}, to: url) { (encodingResult) in
...
}
for alamofire 4 use this ..
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(fileUrl, withName: "video")
//fileUrl is your file path in iOS device and withName is parameter name
}, to:"http://to_your_url_path")
{ (result) in
switch result {
case .success(let upload, _ , _):
upload.uploadProgress(closure: { (progress) in
print("uploding")
})
upload.responseJSON { response in
print("done")
}
case .failure(let encodingError):
print("failed")
print(encodingError)
}
}
Found one more way of doing it
if let parameters = route.parameters {
for (key, value) in parameters {
if value is String {
if let temp = value as? String {
multipartFormData.append(temp.description.data(using: .utf8)!, withName: key)
}
}
else if value is NSArray {
if let temp = value as? [Double]{
multipartFormData.append(temp.description.data(using: .utf8)!, withName: key)
}
else if let temp = value as? [Int]{
multipartFormData.append(temp.description.data(using: .utf8)!, withName: key)
}
else if let temp = value as? [String]{
multipartFormData.append(temp.description.data(using: .utf8)!, withName: key)
}
}
else if CFGetTypeID(value as CFTypeRef) == CFNumberGetTypeID() {
if let temp = value as? Int {
multipartFormData.append(temp.description.data(using: .utf8)!, withName: key)
}
}
else if CFGetTypeID(value as CFTypeRef) == CFBooleanGetTypeID(){
if let temp = value as? Bool {
multipartFormData.append(temp.description.data(using: .utf8)!, withName: key)
}
}
}
}
if let items: [MultipartData] = route.multipartData{
for item in items {
if let value = item.value{
multipartFormData.append(value, withName: item.key, fileName: item.fileName, mimeType: item.mimeType)
}
}
}
Alamofire 5 with Array params
The issue for me was that my params could be any type. Converting to them to strings and then getting the data encoding worked for most, but I kept running into issues with arrays. For arrays you have to encode each element with a key denoting its index. This is how I ended up encoding my params so it would be dynamic for any type:
let image = UIImage(named: "your image") // Change me
let imageData = image.jpegData(compressionQuality: 1.0)!
let imageKey = "image_key" // Change me
let urlString = "https://yourserver.com/yourendpoint/" // Change me
let params: [String: Any]? = [:] // Change me. Your POST params here
let headers: HTTPHeaders = [
// Change me. Your headers here.
]
AF.upload(multipartFormData: { multiPart in
for (key, value) in (params ?? [:]) {
if let arrayObj = value as? [Any] {
for index in 0..<arrayObj.count {
multiPart.append("\(arrayObj[index])".data(using: .utf8)!, withName: "\(key)[\(index)]")
}
} else {
multiPart.append("\(value)".data(using: .utf8)!, withName: key)
}
}
multiPart.append(imageData, withName: imageKey, fileName: "file.jpg", mimeType: "image/jpg")
}, to: urlString, headers: headers).responseJSON { response in
switch response.result {
case .success(_):
if let dictionary = response.value as? [String:Any] {
print("success", dictionary)
} else {
print("error")
}
case .failure(let error):
print("error", error.localizedDescription)
}
}
Also note that you have to append the image after appending all your params
func funcationname()
{
var parameters = [String:String]()
let apiToken = "Bearer \(UserDefaults.standard.string(forKey: "vAuthToken")!)"
let headers = ["Vauthtoken":apiToken]
let mobile = "\(ApiUtillity.sharedInstance.getUserData(key: "mobile"))"
parameters = ["first_name":First_name,"last_name":last_name,"email":Email,"mobile_no":mobile]
print(parameters)
ApiUtillity.sharedInstance.showSVProgressHUD(text: "Loading...")
let URL1 = ApiUtillity.sharedInstance.API(Join: "user/update_profile")
let url = URL(string: URL1.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
var urlRequest = URLRequest(url: url!)
urlRequest.httpMethod = "POST"
urlRequest.allHTTPHeaderFields = headers
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(self.imageData_pf_pic, withName: "profile_image", fileName: "image.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, with: urlRequest) { (encodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
if let JSON = response.result.value {
print("JSON: \(JSON)")
let status = (JSON as AnyObject).value(forKey: "status") as! Int
let sts = Int(status)
if sts == 200
{
ApiUtillity.sharedInstance.dismissSVProgressHUD()
let UserData = ((JSON as AnyObject).value(forKey: "data") as! NSDictionary)
ApiUtillity.sharedInstance.setUserData(data: UserData)
}
else
{
ApiUtillity.sharedInstance.dismissSVProgressHUD()
let ErrorDic:NSDictionary = (JSON as AnyObject).value(forKey: "message") as! NSDictionary
let Errormobile_no = ErrorDic.value(forKey: "mobile_no") as? String
let Erroremail = ErrorDic.value(forKey: "email") as? String
if Errormobile_no?.count == nil
{}
else
{
ApiUtillity.sharedInstance.dismissSVProgressHUDWithError(error: Errormobile_no!)
}
if Erroremail?.count == nil
{}
else
{
ApiUtillity.sharedInstance.dismissSVProgressHUDWithError(error: Erroremail!)
}
}
}
}
case .failure(let encodingError):
ApiUtillity.sharedInstance.dismissSVProgressHUD()
print(encodingError)
}
}
}

Resources