"Invalid file" error while uploading pdf from iCloud drive in swift - 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.

Related

Swift form-data using Alamofire 5 with parameters

I am beginner iOS developer and I don't know how to upload a file using Alamofire 5, I know there are a lot of similar questions, but all the topics here are from very old versions and I couldn't get it working. I tried this code, but I couldn't fit to my case, it gives me success, but file is not uploaded and the result I get is not what I get in postman. This is the code:
func uploadFile(_ parameters: Parameters) {
AF.upload(multipartFormData: { multipartFormData in
URLEncoding.default.queryParameters(parameters).forEach { (key, value) in
if let data = value.data(using: .utf8) {
multipartFormData.append(data, withName: key)
}
}
}, to: url)
.responseDecodable(of: FileCreation.self) { response in
switch response.result {
case .success(let data):
print(data, "success")
case .failure(let error):
print(error)
}
}
}
usage:
#IBAction func upload(_ sender: UIButton) {
guard let data = image?.jpegData(compressionQuality: 0.5)! else { return }
let parameters = ["addFiles": data]
uploadFile(parameters)
}
Here's Xcode output:
Here you can see postman response after I upload file:
Alamofire.upload(multipartFormData: {
multipartFormData in
if let imageData = image[0].jpegData(compressionQuality: 0.6) {
multipartFormData.append(imageData, withName: "addFiles", fileName: "file.pdf", mimeType: "application/pdf")
}
for (key, value) in param {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
},to: apiurl, method: .post, headers: headers, encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON {
response in
print(response.result)
}
//break
case .failure(let encodingError):
break
}
})
Try This
func uploadFilesToServer(_ url: String, method: HTTPMethod, parameters: [String:Any]?, file: [String:Any]?, fileType: String, fileName: String, headers:HTTPHeaders?, completionHandler: #escaping (_ result: Data?, _ success: Bool, _ status: String) -> ()) {
var status = Bool()
var message = String()
let url = URL(string: url)
AF.upload(multipartFormData: { multiPart in
if let files = file {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy-hh-mm-ss"
let dateString = dateFormatter.string(from: Date())
for (key, value) in files {
if fileType == "pdf" {
let filePath = URL(fileURLWithPath: value as! String)
multiPart.append(filePath, withName: "\(key)", fileName: fileName, mimeType: "file/pdf")
} else {
multiPart.append(value as! Data, withName: "\(key)", fileName: "Uploads\(dateString).png", mimeType: "image/png")
}
}
}
if let params = parameters {
for (key, value) in params {
multiPart.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}
}, to: url!, method: method, headers: headers ?? nil)
.validate()
.uploadProgress(closure: { progress in
print(progress)
})
.responseJSON { response in
switch response.result {
case .success(let responseData):
print(responseData)
case .failure(let networkErr):
switch networkErr {
case .responseSerializationFailed(reason: _):
message = "Something went wrong"
case .sessionTaskFailed(error: let err):
message = err.localizedDescription
default:
message = "Something went wrong"
}
completionHandler(nil, false, message)
break
}
}
}
usage
uploadFilesToServer(url, method: .post, parameters: params, file: uploadFile, fileType: "pdf", fileName: fileNme, headers: tokenHeader) { [self] responseData, isSuccess, responseMsg in
if isSuccess {
} else {
}
}

How to send UIImage Extension as parameter to server using Alamofire ppost request in Swift?

I have a postman api that requires an Extension to send with the image. Without the extension it take the image as a file. Help me to send the image with the extension or tell me the better way to do so, or let me know where i am doing wrong.Postman Image Here is my code so far:
func UPLOD(){
guard let token = UserDefaults.standard.string(forKey: "accesstoken") else {
return
}
print("Create button ACCESS KEY::::- \(token)")
let headers: HTTPHeaders = [
"x-access-token": token,
"Content-type": "multipart/form-data",
"Content-Disposition" : "form-data",
"Filename" : "Angle",
"Ext" : ".png"
]
let image = myImageView.image
let imgData = image!.jpegData(compressionQuality: 0.7)!
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imgData, withName: "FileToUpload", fileName: "swift_file.png", mimeType: "image/png")
print("mutlipart 1st \(multipartFormData)")
multipartFormData.append("angela".data(using: String.Encoding.utf8, allowLossyConversion: false)!, withName :"Filename")
multipartFormData.append("Image".data(using: String.Encoding.utf8, allowLossyConversion: false)!, withName :"Folder")
//multipartFormData.append("jpeg".data(using: String.Encoding.utf8, allowLossyConversion: false)!, withName :"Ext")
//multipartFormData.append(imgData, withName: "Ext", mimeType: "image/png")
}, to:"http://192.168.80.21:8800/api/v1/upload/uploadfile", method:.post, headers:headers)
{
(result) in
switch result {
case .success(let upload, _, _):
print("x:::::::::\(result)")
print("Upload;;\(upload)")
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress)")
})
upload.validate(statusCode: 200..<300)
upload.responseJSON { response in
guard response.error == nil else {
print("Pre json\(response as Any)")
let json = JSON(response)
print("JSON: \(json)")
return
}
print(response.result.value as Any)
print("Response: \(JSON(response.data as Any))")
}
case .failure(let encodingError):
print(encodingError)
}
}
}

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

Upload images to the server using Alamofire

The following problem arose, the fact is that sometimes images are not uploaded to the server. All the data is correct, the image is present, the variables are arranged in the correct order, the function reports a successful upload, but sometimes the images still do not reach the server. There are no such problems with the Retorfit library, but with Alamofire it often arises. I can not figure out yet why.
class func write_photo(params:[String:String],image:UIImage, in_position:String, completion:_ js:String, _ success:Bool -> Void, failure:_ errorMessage:String,_ failure:Bool -> Void) {
let url = BaseURL + "xdb_items.write_photo"
let URL = try! URLRequest(url: url, method: .post)
let in_idclient = params["in_idclient"]
let in_iditem = params["in_iditem"]
let imgData = UIImageJPEGRepresentation(image, 0.5)!
sessionManagerImage.upload(multipartFormData: { multipartFormData in
multipartFormData.append((in_idclient?.data(using: String.Encoding.utf8)!)!, withName: "in_idclient")
multipartFormData.append((in_iditem?.data(using: String.Encoding.utf8)!)!, withName: "in_iditem")
multipartFormData.append(imgData, withName: "in_filename", fileName: "photo", mimeType: "image/png")
multipartFormData.append((in_position.data(using: String.Encoding.utf8)!), withName: "in_position")
}, with: URL, encodingCompletion: {
encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { response in
completion("", true)
}
case .failure(let encodingError):
print("ERROR RESPONSE: \(encodingError)")
}
})
}
my friends, when I did the application rollout, the Xcode issued such a warning on the id_item variable: could not execute support code to read Objective-C class data in the process. at real iPhone device maybe this is the problem
found an error, status code 500, because of what it can occur?
Postman work great! Screenshot Postman:
enter image description here
enter image description here
Code that Postman offers, but I need Alamofire:
import Foundation
let headers = [
"content-type": "multipart/form-data; boundary=----WeXXXXXXXXXXXXXXXXXXrZu0gW",
"Authorization": "Basic dXXXXXXXXXXXX=",
"cache-control": "no-cache",
"Postman-Token": "2c1bXXXXXXXXXXXXXXXXX4e"
]
let parameters = [
[
"name": "in_filename",
"fileName": "/home/iv/Рабочий стол/Скрины/Скрин6.png"
],
[
"name": "in_idclient",
"value": "516"
],
[
"name": "in_iditem",
"value": "1232"
],
[
"name": "in_position",
"value": "5"
]
]
let boundary = "----WeXXXXXXXXXXXXXXXXXXrZu0gW"
var body = ""
var error: NSError? = nil
for param in parameters {
let paramName = param["name"]!
body += "--\(boundary)\r\n"
body += "Content-Disposition:form-data; name=\"\(paramName)\""
if let filename = param["fileName"] {
let contentType = param["content-type"]!
let fileContent = String(contentsOfFile: filename, encoding: String.Encoding.utf8)
if (error != nil) {
print(error)
}
body += "; filename=\"\(filename)\"\r\n"
body += "Content-Type: \(contentType)\r\n\r\n"
body += fileContent
} else if let paramValue = param["value"] {
body += "\r\n\r\n\(paramValue)"
}
}
let request = NSMutableURLRequest(url: NSURL(string: "http://XXXXXXXXXX:XXXX/XX/xdb_items.write_photo")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
try instead of this
multipartFormData.append(imgData, withName: "in_filename", fileName: "photo", mimeType: "image/png")
to
multipartFormData.append(imgData, withName: "profile_photo")
may be this will helpful for you
let imageData : Data! = (UIImage converted to Data)
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData, withName: "image", fileName: "file.jpeg", mimeType: "image/jpeg")
}, to: NSURL(string: "http://URL you want to upload it to")! as URL)
{ (result) in
switch result {
case .success(let upload, _, _):
//Success
case .failure(let encodingError):
//Failure
}
}

Alamofire error copying matching creds - Swift

we are working to get an upload to an API with a POST method. We are trying to push an image. We are getting the next error
success(request: 2018-02-03 16:27:53.087629-0800 Optimio-iOS[5425:201118] CredStore - performQuery - Error copying matching creds. Error=-25300, query={
class = inet;
"m_Limit" = "m_LimitAll";
ptcl = htps;
"r_Attributes" = 1;
sdmn = "llegoelbigotes.ubiqme.es";
srvr = "llegoelbigotes.ubiqme.es";
sync = syna;
}
$ curl -v \
-X POST \
-H "Content-Type: multipart/form-data; boundary=alamofire.boundary.7105b62be90b880b" \
-H "Accept-Language: en;q=1.0, es-ES;q=0.9" \
-H "Authorization: Token 1b0ad885a95334154ca3bfa79b3f52ca35c25e0e" \
-H "User-Agent: Optimio-iOS/1.0 (Ubiqme-com.ubiqme.ubiqme; build:1; iOS 11.2.0) Alamofire/4.6.0" \
-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
"https://llegoelbigotes.ubiqme.es/api/new-ticket", streamingFromDisk: true, streamFileURL: Optional(file:///Users/polvallsortiz/Library/Developer/CoreSimulator/Devices/EE663E81-6611-4B69-ABD6-AF97D19D6FB7/data/Containers/Data/Application/E7B9F357-DD51-4512-8173-37C932C0E4B9/tmp/org.alamofire.manager/multipart.form.data/74C9B75E-614D-4FCD-9DBC-1F5D07D773C4))
Our code is the next one:
func myImageUploadRequest() {
guard let urlStr = "https://llegoelbigotes.ubiqme.es/api/new-ticket".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed),
let url = URL(string: urlStr)
else {return}
let isPaymentCard = card ? "true" : "false"
let headers: HTTPHeaders = ["Authorization": "Token \(token!)"]
let param = [ "comment": comment, "category": String(category), "amount": String(money), "payment_card": isPaymentCard ]
Alamofire.upload(multipartFormData: { multipartFormData in
if let imageData = UIImageJPEGRepresentation(self.image,0.5)
{ multipartFormData.append(imageData,withName:"image",fileName:"image.jpeg",mimeType:"image/jpeg") }
for(key,value) in param {
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
}
}, usingThreshold: UInt64.init(),
to: urlStr,
method: .post,
headers: headers) {(result) in
print(result)
switch result{
case .success(let upload, _, _):
upload.responseJSON {
response in
print("Succesfully uploaded")
if let err = response.error{
print(err)
return
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
print(error)
}
}
}
Anyone can show us some tips or say what might be wrong?
Thanks to all the community!
-> I have created a dynamic function for uploading Image and Files you can even upload multiple images and files my this
func makeFormDataAPICall<T: Codable>(url: String, params: [String: Any], objectType: T.Type,
success: #escaping(_ responseObject: T) -> Void,
failure: #escaping (_ error: String) -> Void) {
let name = self.randomNumberWith(digits: 6)
self.headers = [kAuthorization: self.userData?.authToken ?? ""]
//Network check
if Utilities.isConnectedToNetwork() {
guard let urlIs = URL(string: url) else {
failure(ServerAPI.errorMessages.kServerDownError)
return
}
// Almofire upload request
AF.upload(multipartFormData: { multiPartData in
for (key, value) in params {
if value is UIImage {
let img = (value as? UIImage)?.jpegData(compressionQuality: 0.5)
multiPartData.append(img!, withName: key, fileName: "img_\(name).jpeg", mimeType: "image/jpeg")
} else if value is NSArray {
for childValue in value as? NSArray ?? [] {
if childValue is UIImage {
let img = (childValue as? UIImage)?.jpegData(compressionQuality: 0.5)
multiPartData.append(img!, withName: key, fileName: "profile_image.png", mimeType: "image/jpeg")
}
}
} else if value is NSURL || value is URL {
do {
guard let pdf: URL = value as? URL else { return }
let name = pdf.lastPathComponent
let mimeType = pdf.mimeType()
let pdfData = try Data(contentsOf: pdf)
multiPartData.append(pdfData, withName: key, fileName: name, mimeType: mimeType)
} catch { print(error) }
} else {
if value is String || value is Int || value is Bool {
multiPartData.append("\(value)".data(using: .utf8)!, withName: key)
}
}
}
}, to: urlIs,method: .post, headers: headers).responseDecodable(of: FetchAPI<T>.self) { response in
// preetify data
if let data = response.data {
let str = data.prettyPrintedJSONString!
Logger.logResponse(ofAPI: "\(urlIs)", logType: .success, object: str)
}
// response result
switch response.result {
case .success(let data):
// check auth token Exp condition
if data.statusCode == 401 {
let appDelegate = AppDelegate.shared()
let rootVC = R.storyboard.auth.authNavigationController()!
appDelegate.window?.rootViewController = rootVC
return
}
// check flag status
if data.flag! { success(data.data!) } else { failure(data.message!) }
case .failure(let error):
failure("Something went wrong.")
Logger.log(logType: .error, object: error.localizedDescription)
}
}
} else { failure(ServerAPI.errorMessages.kNoInternetConnectionMessage) }
}
-> Usage
APIManager.shared.makeFormDataAPICall(url: ServerAPI.editProfile, params: params, objectType: User.self, success: { response in
success(response)
print(response)
}, failure: { error in
failure(error)
}) // 1st Parameter is URL 2nd Parameter are params to send
//3rd parameter is Object to which you want to convert the Json data into
//4th and 5th parameter are compilation handler which gives you response and errors accordingly
-> you can remove auth token conditions which I have written for myself
-> if you are passing data in json you just have to write JSONEncoding: JSONEncoding.default before "header parameter" in almofire function