uploading an image to server using Alamofire Swift - swift

I am trying to upload an image to server , but its showing its not current format , I have seen so many solutions in stack , but haven't work on my code .
here is the screenshot of my postman : postman response for auth:
Screenshot of Authorization page
code I have tried with Alamofire : `
func upload(image: Data, to url: Alamofire.URLRequestConvertible, params: [String: Any]) {
AF.upload(multipartFormData: { multiPart in
for (key, value) in params {
if let temp = value as? String {
multiPart.append(temp.data(using: .utf8)!, withName: key)
}
if let temp = value as? Int {
multiPart.append("\(temp)".data(using: .utf8)!, withName: key)
}
if let temp = value as? NSArray {
temp.forEach({ element in
let keyObj = key + "[]"
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(image, withName: "file", fileName: "file.png", mimeType: "image/png")
}, with: url)
.uploadProgress(queue: .main, closure: { progress in
//Current upload progress of file
print("Upload Progress: \(progress.fractionCompleted)")
})
.responseJSON(completionHandler: { data in
//Do what ever you want to do with response
})
}
`
now I need help to upload the image using url session or Alamofire .
need help about parameter to url: also.
the url is : "http://germanbutcher.easyservice.xyz/backend/api/v1/users/33/photo"
thanks in advance

Related

To upload images to the server using Alamofire multipart in swift

During resistration of a user, i am uploading some photoes to the server. The first one is the profile photo. And the rest photoes i want to upload after the resistration process once completed. Means i want to upload the photo after getting the userid and the access token.Means after a successfully image upload, the user will enter to the "matchesViewController" and then only the upload process will start. Also i want to upload these photoes in background thread. Also if the app rinning in background then also the upload process should be continue. All the uploading process is done by Alamofire.
By writting the following code the photos are uploading successfully, but it is taking more time. Which is not a good user experience.
Also please tell me how to continue the upload process when the app running in back ground thread.
Also if the code is not good please help me to modify any changes in code if needed.
My code is: -
private func handleRegistration (_ parameterDict : [String : Any]){
let url = USER_REGISTER_URL
let headers: HTTPHeaders = [
"Content-Type": "application/x-www-form-urlencoded"
]
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameterDict {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
let random = randomString(length: 7)
multipartFormData.append(self.selectedProfilePic.image!.jpegData(compressionQuality: 0.4)!, withName: "fileset",fileName: "\(random).jpg", mimeType: "image/jpg")
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
switch result{
case .success(let upload, _, _):
upload.responseJSON { response in
print(response)
var userId: String?
var token: String?
if let result = response.result.value {
let JSON = result as! NSDictionary
guard let accessToken = JSON["access_token"] as? String
else{ return }
guard let uid = JSON["User_Id"] as? String
else{return}
userId = uid
token = "bearer " + accessToken
UserDefaults.standard.set(Int(uid), forKey: "User_Id")
UserDefaults.standard.set(token, forKey: "access_token")
let phone = JSON["Phone_Number"] as? String
let FirstName = JSON["FirstName"] as? String
let email = uid + "#gmail.com"
let tempDictionary : Dictionary = [kFIRSTNAME : FirstName!, kLASTNAME : "", kFULLNAME : FirstName!, kPHONE : phone!, kREGISTERUSEID: userId, kEMAIL: email] as [String : Any]
self.checkDeviceTokenAvailibility(uid: Int(userId!)!)
self.startRegistrationWithFirebase( detailDict: tempDictionary)
let storyBoard = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MainTabbarView")
storyBoard.modalPresentationStyle = .fullScreen
self.present(storyBoard, animated: true, completion: nil)
if let message = JSON["Message"] as? String{
if message == "Please Upload a image."{
}
}
}
if userId != nil && token != nil{
self.multiImageUpload(userId: Int(userId!)!, token: token!)
}
print("Succesfully uploaded")
if let err = response.error{
// onError?(err)
// print(err.localizedDescription)
return
}
// onCompletion?(nil)
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
// onError?(error)
}
}
}
One way to make the upload time a lot less is to send multiple parts at once using a for loop and using Alamofire to send a specific part. That way, it breaks it up into parts that take a lot less time to send. The con is that on the server side you will have to reconstruct the image.
Also if the code is not good please help me to modify any changes in code if needed.
It seems you have a lot of arbitrary space in your code.

Module 'Alamofire' has no member named 'upload'

I am trying to upload an image using swift to the server. i tried NSMutableURLRequest with URLSession. i received network connection lost. I thought it will be a better way to simply use Alamofire but got into a problem as xcode doesn't find the function update.
Any idea how to upload image with Alamofire? or find the update func?
the code for alamofire:
func uploadImageWithAlmofire(url: String) {
let params: Parameters = ["name": "abcd", "gender": "Male"]
Alamofire.upload(multipartFormData:
{
(multipartFormData) in
multipartFormData.append(UIImageJPEGRepresentation(self.yourimageView.image!, 0.1)!, withName: "file", fileName: "file.jpeg", mimeType: "image/jpeg")
for (key, value) in params
{
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, to:url,headers:nil)
{ (result) in
switch result {
case .success(let upload,_,_ ):
upload.uploadProgress(closure: { (progress) in
//Print progress
})
upload.responseJSON
{ response in
//print response.result
if response.result.value != nil
{
let dict :NSDictionary = response.result.value! as! NSDictionary
let status = dict.value(forKey: "status")as! String
if status=="1"
{
print("DATA UPLOAD SUCCESSFULLY")
}
}
}
case .failure(let encodingError):
break
}
}
}
When you check Uploading Data to a Server example, it uses AF instead of Alamofire:
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(Data("one".utf8), withName: "one")
multipartFormData.append(Data("two".utf8), withName: "two")
}, to: "https://httpbin.org/post")
.responseJSON { response in
debugPrint(response)
}
Try with this
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(Data(self.businessType.utf8), withName: "business_type")
let theFileName1 = (self.doc1.absoluteString as NSString).lastPathComponent
multipartFormData.append(self.doc1, withName: "key_value", fileName: theFileName1, mimeType: "image/png")
}, to: "https://www.test_document.php") //POST URL
.responseJSON { response in
debugPrint(response)
}

"Invalid file" error while uploading pdf from iCloud drive in swift

I need to upload documents from iPhone to the application server, for that I am using UIDocumentPickerViewController and I have successfully picked the file from iCloud drive but when I am uploading file using alamofire multipart I am getting error msg from backend "invalid file".
I have converted the URL received from UIDocumentPickerViewController to Data before uploading. Here is my complete code:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
self.urlfilepick = url
self.filePickedBlock?(url)
stringpath = self.urlfilepick.path
print(stringpath)
thefileExtension = (stringpath as NSString).lastPathComponent
thefileExtension = thefileExtension.replacingOccurrences(of: "Response Format :-.", with: "")
UserDefaults.standard.set( thefileExtension , forKey: "fromdocument")
stringcomingFrom = "Files"
parameters = ["user_id":UserDefaults.standard.string(forKey: "userid") ?? "","treatment_id":self.treatmentId!,"document_type_id":strdocumnetid,"label_name":self.txtdocumnetName.text!,"type":"1","ext":thefileExtension,]
let datadat = NSData(contentsOfFile: stringpath)
data = datadat as Data?
self.requestWith(data: data, fileName: "file", pathExtension: thefileExtension, parameters: parameters)
}
and the alamofire upload function is:
func requestWith(
data: Data?,
fileName: String?,
pathExtension: String?,
parameters: [String : Any]){
guard let emailId = UserDefaults.standard.string(forKey: "email") else {return}
guard let token = UserDefaults.standard.string(forKey: "token") else {return}
let headers = ["Content-Type": "application/json","med-token":token,"user":emailId,"device":"1"]
let URL = baseUrl + uploadDocuments
Alamofire.upload(multipartFormData: { (multipartFormData) in
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
if let data = data {
multipartFormData.append(data, withName: "filename", fileName: "\(fileName!).\(pathExtension!)", mimeType: "\(fileName!)/\(pathExtension!)")
}
}, usingThreshold: UInt64.init(), to: URL, method: .post, headers: headers) { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response)
if let err = response.error {
return
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
}
}
}
It is working fine in Postman.

Alamofire 5 upload encodingCompletion

I'm working with Swift 4 and Alamofire 5, I upload two multibart photos and I want to print the progress
AF.upload(
multipartFormData: { MultipartFormData in
MultipartFormData.append(firstPic, withName: "first_pic", fileName: "image.jpeg", mimeType: "image/jpeg")
MultipartFormData.append(secondPic, withName: "second_pic", fileName: "image.jpeg", mimeType: "image/jpeg")
}, to: urlString, encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
print(totalBytesRead)
}
upload.responseJSON { request, response, result in
print(result)
}
case .Failure(let encodingError):
print(encodingError)
}
})
and this gets an error saying
Argument labels '(multipartFormData:, to:, encodingCompletion:)' do not match any available overloads
did the library update the code or something??
Please modify according to your need
func upload(image: Data, to url: Alamofire.URLRequestConvertible, params: [String: Any]) {
AF.upload(multipartFormData: { multiPart in
for (key, value) in params {
if let temp = value as? String {
multiPart.append(temp.data(using: .utf8)!, withName: key)
}
if let temp = value as? Int {
multiPart.append("\(temp)".data(using: .utf8)!, withName: key)
}
if let temp = value as? NSArray {
temp.forEach({ element in
let keyObj = key + "[]"
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(image, withName: "file", fileName: "file.png", mimeType: "image/png")
}, with: url)
.uploadProgress(queue: .main, closure: { progress in
//Current upload progress of file
print("Upload Progress: \(progress.fractionCompleted)")
})
.responseJSON(completionHandler: { response in
//Do what ever you want to do with response
if let error = response.error {
print(error)
}
guard let data = response.value else {
return
}
print(value)
})
}
Alamofire 5 no longer requires an encodingCompletion! Instead, multipart form encoding is done as part of the standard now-asynchronous request process and will return errors on the Request, and they're available during validate and response* calls.
let headers: HTTPHeaders = [
/* "Authorization": "your_access_token", in case you need authorization header */
"Content-type": "multipart/form-data"
]
AF.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(imageOrVideo!.jpegData(compressionQuality: 0.5)!, withName: "upload_data" , fileName: "file.jpeg", mimeType: "image/jpeg")
},
to: "http://----/new.php", method: .post , headers: headers)
.response { resp in
print(resp)
}

Only last image in array uploads with Alamofire Swift 3

I need to upload several images to an API at a time. I am using Alamofire to upload images and the API only allows one image to be uploaded per request.
I have an array of images to be uploaded and I am going through the array and making a request each time. Each image appears to upload correctly but then when I check the database only the last image has been uploaded. Each call prints a response with status code 200 and prints "SUCCESSFUL" when it is complete, but only the last in the array actually uploads.
for (index, image) in self.imageArray.enumerated() {
self.uploadImages(photoIndex: index, photo: image.image, fileName: image.imageName, completion: { (true) in
print("SUCCESSFUL")
})
}
I have also tried using a DispatchQueue, but that didn't work either:
let serialQueue = DispatchQueue(label: "serialQueue")
And inside the for loop
serialQueue.async {
//self.uploadImages...
}
I've tried a few more things, with no success. How would I be able to fix this?
Also, here is my uploadImages function
func uploadImages(photoIndex: Int, photo: UIImage, fileName: String, completion: #escaping (_ Success : Bool?) -> ())
{
var success: Bool? = nil
let url : String? = //url
// define parameters
let parameters = [
"photoIndex": "\(photoIndex)"]
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(photo, 1)
{
multipartFormData.append(imageData, withName: "photo", fileName: fileName, mimeType: "image/png")
}
for (key, value) in parameters {
multipartFormData.append((value.data(using: .utf8))!, withName: key)
}}, to: url!, method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { [weak self] response in
guard let strongSelf = self else {
return
}
success = true
debugPrint(response)
completion(success)
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}
Use multipart form data to upload the any media file below is the code snippet to upload multiple video
for (key , value) in arrMediaUpload {
if let image = value as? UIImage {
if let imageData = UIImageJPEGRepresentation(image,0.9) {
print("key => \(key)")
multipartFormData.append(imageData as Data, withName: key, fileName: "\(NSDate().timeIntervalSince1970).jpg", mimeType: "image/*")
}
}
}
I am not that good in Swift so take this answer with a grain of salt but I do not see were you are adding any new keys to your dictionary. So since there is only one key there would be only one value. Therefore the for loop would only be done one time.