upload image to server in iOS swift - ios

I'm new in swift.
I have no idea about how to upload image from UIImage Piker Controller to server using Alamofire. I tried many solution from stackOverflow And Google etc from last week unfortunately. But I can't figure out it.
Please anyone Help me.
Now I tried to implement this code:
func uploadImgRiderAPI(){
print("I am in uploadImgAPI")
let imgData = UIImageJPEGRepresentation(profilePicOut.image!, 0.2)! //Error: UIImageJPEGRepresentation' has been replaced by instance method 'UIImage.jpegData(compressionQuality:)'
let parameters : [String : Any] = ["image": imgData, "riderId" : "5ed4eecfe3ec0c6b7c8e4990"]
guard let url = URL(string: "\(Constents.baseURL)/rider/uploadImage") else {
print("Invalid URL")
return
}
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "image",fileName: "alkaram.png", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8), withName: key) // Error: Cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members
}
}, to:url) { (result) in
switch result {
case .success(let upload, _, _): //Error : Pattern cannot match values of type 'URLRequest'
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
print(response.result.value)
if let result = response.data {
do {
let jsonData = try JSONEncoder().encode(parameters)
let jsonString = String(data: jsonData, encoding: .utf8)
let url = URL(string: self.retrivedRiderProfileImg!)
print("Complete URL is :-> \(url)")
let placeholderImage = UIImage(named: "referral_icon")!
self.profilePicOut.af_setImage(withURL: url!, placeholderImage: placeholderImage)
print("JSON String : " + jsonString!)
print("And Responce is : \(response)")
} catch {
print(error)
}
}
}
case .failure(let encodingError): //Error : Pattern cannot match values of type 'URLRequest'
print(encodingError)
}
}
}

Firstly, You need to replace the old API for UIImageJPEGRepresentation with the new jpegData(compressionQuality:) method.
Replace this:
let imgData = UIImageJPEGRepresentation(profilePicOut.image!, 0.2)!
With this:
guard let imgData = profilePicOut.image?.jpegData(compressionQuality: 0.2) else { return }
And replace the case where only one parameter for URLRequest is returned to accept just one parameter as the error states.
Replace this:
case .success(let upload, _, _):
With this:
case .success(let upload):

Related

iOS : How to upload multiple images to server using multipart using alamofire

I have to upload multiple images to the server through alamofire. I am able to get the images in the form of array, convert them to data but when i upload them to the server only first image is appearing.
I am sharing my code please help.
i am getting image array of this type
image array== [<UIImage:0x2804cb210 anonymous {1170, 2532}
renderingMode=automatic(original)>, <UIImage:0x2804f03f0 anonymous
{1170, 2532} renderingMode=automatic(original)>]
and when i convert it to data from the code i got this response
print("image array==", self.images)
self.photoImageData = self.images.compactMap { $0.pngData() }
print("====", photoImageData)
==== [4074684 bytes, 1353198 bytes]
here is my function
func hitPostAPIWithprofileImageArray(urlString: String, params: [String: String],imageData: [Data],imageKey: String, completionHandler:#escaping (_ result: [String: Any], _ errorC : Error?) -> Void)
{
print("params-> ",params)
let openUrl : URL
openUrl = URL(string: baseURL + urlString)!
print("params-> ",openUrl)
Alamofire.upload(
multipartFormData: { multipartFormData in
for imageData in imageData {
multipartFormData.append(imageData, withName: imageKey, fileName: "user.jpg", mimeType: "image/jpeg")
}
for (key, value) in params {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
},
to: openUrl,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
do{
let result = try JSONSerialization.jsonObject(with: response.data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [String:Any]
print(result)
let errorC = Error.self
completionHandler(result,errorC as? Error)
}catch{
if let err = response.error {
completionHandler(self.resultG,err as? Error); return
}
} }
upload.uploadProgress(queue: DispatchQueue(label: "uploadQueue"), closure: { (progress) in
})
case .failure(let encodingError):
print(encodingError)
completionHandler(self.resultG,encodingError as? Error)
}
}
)
}

How to convert UIImage to JPEG without loosing exif data?

I'm currently working on iOS applications and I'm using multipart image upload to uploading images to the server. Following is my image uploading method.
func uploadImageData(imageType:Int, uploadId:String, fileName:String, imageFile:UIImage, completion:#escaping (APIResponseStatus, ImageUploadResponse?) -> Void) {
let image = imageFile
let imgData = image.jpegData(compressionQuality: 0.2)!
let params = [APIRequestKeys.imageType:imageType, APIRequestKeys.uploadId:uploadId, APIRequestKeys.fileName:fileName] as [String : Any]
//withName is the post request key for the image file
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imgData, withName: APIRequestKeys.imageFile, fileName: "\(fileName).jpg", mimeType: "image/jpg")
for (key, value) in params {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key)
}
}, to: Constants.baseUrl + APIRequestMetod.uploadImageData, headers:self.getImageUploadHeaders())
{ (result) in
switch result {
case .success(let upload, _, _):
APIClient.currentRequest = upload
upload.uploadProgress(closure: { (progress) in
})
upload.responseObject {
(response:DataResponse<ImageUploadResponse>) in
switch response.result {
case .success(_):
completion(APIClient.APIResponseStatus(rawValue: (response.response?.statusCode)!)!, response.value!)
case .failure(let encodingError):
if let err = encodingError as? URLError, err.code == .notConnectedToInternet {
completion(APIClient.APIResponseStatus.NoNetwork, nil)
} else {
completion(APIClient.APIResponseStatus.Other, nil)
}
}
}
case .failure( _):
completion(APIClient.APIResponseStatus.Other, nil)
}
}
}
But for this implementation server is always sending exif data error. Following is the error that I'm getting.
exif_read_data(A029C715-99E4-44BE-8691-AA4009C1F5BD_FOTOPREGUNTA.ico): Illegal IFD size in
upload_image_xhr.php on line
The important thing is this service is working without errors in POSTMAN and android application as well. This error is only getting for my iOS implementation. My backend developer telling me that there is and exif data error in data that I'm sending and please verify the data from my side.
Anyone have an idea about this?
Thanks in advance.
I will make block function for Upload image to Server Using Multipart
//Here strUrl = YOUR WEBSERVICE URL
//postParam = post Request parameter i.e.
//let postParam : [String : Any] = [first_name : "name"]
//imageArray = image upload array i.e.
//var imageArray : [[String:Data]] = [["image_name" : YOUR IMAGE DATA]]
func postImageRequestWithURL(withUrl strURL: String,withParam postParam: Dictionary<String, Any>,withImages imageArray:[[String:Data]], completion:#escaping (_ isSuccess: Bool, _ response:NSDictionary) -> Void)
{
let requetURL = strURL
Alamofire.upload(multipartFormData: { (MultipartFormData) in
for (imageDic) in imageArray
{
for (key,valus) in imageDic
{
MultipartFormData.append(valus, withName:key,fileName: "file.jpg", mimeType: "image/jpg")
}
}
for (key, value) in postParam
{
MultipartFormData.append("\(value)".data(using: .utf8)!, withName: key)
// MultipartFormData.append(value, withName: key)
}
}, usingThreshold: UInt64.init(), to: requetURL, method: .post, headers: ["Accept": "application/json"]) { (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
let desiredString = NSString(data: response.data!, encoding: String.Encoding.utf8.rawValue)
print("Response ====================")
print(desiredString!)
if let json = response.result.value as? NSDictionary
{
if response.response?.statusCode == 200
|| response.response?.statusCode == 201
|| response.response?.statusCode == 202
{
completion(true,json);
}
else
{
completion(false,json);
}
}
else
{
completion(false,[:]);
}
}
case .failure(let encodingError):
print(encodingError)
completion(false,[:]);
}
}
}
I Hope this will help...

Not able to upload camera images using Almofire multipart

I have to upload images, audio, documents. I'm using Alamofire to upload. Everything is uploaded including gallery images like screenshots, but pictures taken from camera are not getting uploaded.
Here's my code:
func requestUploadFileWithMultipart(connectionUrl: String, param : [String: AnyObject], filePath: String?, _ callBack: #escaping (_ data: DataResponse<Any>?, _ error:Error?) -> Void) {
let URLString = MainURL + connectionUrl
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in param {
let stringValue = "\(value)"
multipartFormData.append(stringValue.data(using: String.Encoding.utf8)!, withName: key)
print("Key: \(key), Value: \(stringValue)")
}
if filePath != "" {
do {
var fileData = try Data(contentsOf: URL(string: filePath!)!)
let ext = URL(fileURLWithPath: filePath!).lastPathComponent.components(separatedBy: ".").last
let mime = filePath?.mimeTypeForPath()
let fileName = "\(Date().timeIntervalSince1970)".components(separatedBy: ".").first
multipartFormData.append(fileData, withName: "file", fileName: "\(fileName ?? "file").\(ext ?? "")", mimeType: mime ?? "")
} catch {
print("error loading file in multipart")
}
}
}, to:URLString) { (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 as Any)
callBack(response, nil)
}
case .failure(let encodingError):
print(encodingError)
callBack(nil, encodingError)
}
}
}
Image compression worked for me. May be large files were no uploading.
Please try below code, I am using this code in my one of project. But make sure that API is suitable for multipart uploading.
Alamofire.upload(multipartFormData: {
multipartFormData in
if let img = image {
if let imageData = img.jpegData(compressionQuality: 0.4) {
multipartFormData.append(imageData, withName: "cmt_img", fileName: "\(Date()).jpg", mimeType: "image/jpg")
}
}
do {
let theJSONData = try JSONSerialization.data(withJSONObject: param, options: JSONSerialization.WritingOptions(rawValue: 0))
multipartFormData.append(theJSONData, withName: "data")
} catch {}
},usingThreshold: 0 ,to: baseURL + URLS.AddComment.rawValue, headers: appDelegate.headers, encodingCompletion: {
encodingResult in switch encodingResult {
case .success(let upload, _, _):
upload.responseObject(completionHandler: { (response: DataResponse<AddCommentData>) in
SVProgressHUD.dismiss()
if (response.result.value != nil) {
showAlert(popUpMessage.uploadingSuccess.rawValue)
}
else {
showAlert(popUpMessage.someWrong.rawValue)
}
})
break
case .failure(let encodingError):
SVProgressHUD.dismiss()
print(encodingError)
break
}
})
}

how to upload an Image using alamofire with basic authentication?

I am trying to upload an image using alamofire 4.7.1 with this code, but to be honest I suspect that I didn't write a right code to upload the image
func uploadDefect(defectRemark: String, defectLocation: String, defectImage: UIImage, fileNameImage: String, completion: #escaping(_ errorMessage: String?) -> Void) {
guard let imgData = defectImage.jpeg(.medium) else {return}
let urlUpload = URLService.uploadDefect.endPoint
let username = "admin"
let password = "1234"
let credentialData = "\(username):\(password)".data(using: String.Encoding.utf8)!
let base64Credentials = credentialData.base64EncodedString(options: [])
let headers = ["Authorization": base64Credentials]
let parameters : [String:Any] = ["defect_remark" : defectRemark, "defect_location": defectLocation, "tenant_id" : tenantID]
let url = try! URLRequest(url: URL(string: urlUpload)!, method: .post, headers: headers)
Alamofire.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "file", fileName: fileNameImage, mimeType: "image/jpeg")
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
},
with: url,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
print("upload response: \(response)")
switch response.result {
case .failure(let error) :
let message : String
if let httpStatusCode = response.response?.statusCode {
switch(httpStatusCode) {
case 404:
message = "File not found"
case 500 :
message = "Internal Error"
default:
message = "Connection issue, please make sure you have a good internet access, or please contact IT Support."
}
} else {
message = error.localizedDescription
}
completion(message)
case .success( _) :
completion(nil)
}
}
case .failure(let encodingError):
let messageEncodingError = encodingError.localizedDescription
print(encodingError)
completion(messageEncodingError)
break
}
}
)
}
it seems that case .success is triggered
case .success( _) :
completion(nil)
}
but seems no error, but I didn't get the expected JSON response from the server.
here is the error log from the debugging area
I suspect that I didn't write a right code to upload the image server using alamofire using basic authentication. could you please help me with this one?
Change your Authorization like this:
let headers = ["Authorization": "Basic \(base64Credentials)"]
You can also make use of Alamofire to create the authentication header like:
var headers: HTTPHeaders = [:]
if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
headers[authorizationHeader.key] = authorizationHeader.value
}

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+

Resources