How to upload zip data with alamofire? - swift

I try to upload data using Alamofire
Issue is: if I try to upload image from project it works ok, but if I try to upload zip dir I got error and timeout exception
There is my code which produces timeout exception
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 10 // seconds
configuration.timeoutIntervalForResource = 10
alamoFireManager = Alamofire.SessionManager(configuration: configuration)
let fileData = FileManager.default.contents(atPath: filePath)
alamoFireManager.upload(fileData,
to: url,
method: .post,
headers: headers)
.validate()
.responseJSON {}
And here is code which works fine
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 10 // seconds
configuration.timeoutIntervalForResource = 10
alamoFireManager = Alamofire.SessionManager(configuration: configuration)
let fileURL = Bundle.main.url(forResource: "MyImage", withExtension: "jpg")
alamoFireManager.upload(fileURL,
to: url,
method: .post,
headers: headers)
.validate()
.responseJSON {}
I tried to pass Data() to upload request also I tried pass reference to zip dit URL to upload request, also I tried InputStream(url: fileURL!)! but without success...
What am I doing wrong? how to send zip data to the server?
if there is some question feel free to ask!

Eventually, I found the issue, server side does not accept my request. Also, there is some confusion, because if I try to download an image file from my project it works, but if the file is selected from the document directory then there is an issue.
Anyway if someone has a similar issue try to check your server side.
Try to check if your request came to server and with content inside.

Related

Uploading a PDF File From Swift Yields a Blank PDF

Im trying to upload a PDF generated from a UIImage. I take a picture using my camera framework, uploads all ok but the PDF on S3 is blank. Below is the code I am using:
I use the following class to create the PDF from a UIImage, tested ok.
// Using PDFKit
func generatePDF(source: UIImage) -> PDFDocument {
let pdfDocument = PDFDocument()
let pdfPage = PDFPage(image: source)
pdfDocument.insert(pdfPage!, at: 0)
return pdfDocument
}
I used Alamofire to perform a multipart upload with the pdf, tested ok.
class NetworkManager {
static let shared = NetworkManager()
func upload(document: Data, name: String) {
let filename = "\(name).pdf"
let urlString = endpoint + "?filename=" + filename
let url = URL(string: urlString)!
var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 30)
request.method = .post
request.setValue(key, forHTTPHeaderField: api)
AF.upload(multipartFormData: { multiPart in
multiPart.append(document, withName: name, fileName: filename, mimeType: "application/pdf")
}, with: request)
.uploadProgress(queue: .main, closure: { progress in
print("Upload Progress: \(progress.fractionCompleted)")
})
.responseJSON(completionHandler: { data in
print("data: \(data)")
})
}
}
On AWS I am using the following framework to reconstruct the multipart data back to a PDF
lambda-multipart-parser
https://www.npmjs.com/package/lambda-multipart-parser
How Im using it in Lambda:
let filename = event.queryStringParameters.filename;
let documentData = await imageParser.parse(event);
let document = documentData.files[0];
var data = {
Bucket: 'order-scanned-copy',
Key: filename,
Body: document.content,
ContentType: "application/pdf",
};
let uploadFile = await s3.putObject(data).promise();
No errors, no warnings just a blank PDF. I can tell by the size around 500kb-1mb that it has something in it. Any help would be appreciated.
Thanks.
I figured it out, since I am using AWS specifically API Gateway and Lambda I needed to add the "Binary Media Type" to API Gateway. To do this I opened Api Gateway console and choose my API. Then, selected Settings and added the following types.
I did a redeploy of my api and everything worked perfect, so in the end it was not a code problem but configuration mistake on AWS.
This blog post was very helpful:
AWS SAM Configuration for API Gateway Binary Response / Payloads
Thanks for your help everyone.

Alamofire session configurations are not reflected in the request

Alamofire Version: 5.1
We are modifying our alamofire session configuration as following:
let apiManager: Session = {
let configuration = URLSessionConfiguration.af.default
configuration.timeoutIntervalForRequest = 20
configuration.requestCachePolicy = .reloadIgnoringCacheData
configuration.urlCache = nil
let manager = Alamofire.Session(
configuration: configuration,
cachedResponseHandler: ResponseCacher(behavior: .doNotCache)
)
return manager
}()
And we are making the request as following
apiManager.request(
url,
method: .post,
parameters: requestBodyParameters,
encoding: JSONEncoding.default,
headers: generateHeaders(enableAuth: authorisation) // to generate headers
)
.validate(statusCode: 200..<300)
.responseJSON { response in
print(response)
}
}
}
But the request configurations is not updated, they remain at default values
[Timeout]
60
[Cache policy]
UseProtocolCachePolicy
You're looking at the URLRequest generated by Alamofire which doesn't include the URLSession-level configuration, and which will never reflect the cache customization. If you want to see the actual URLRequest being performed after it passes through both Alamofire and URLSession, you can access the latest URLSessionTask that the Alamofire Request (in this case a DataRequest) performed by using request.task. However, like I said, this will never reflect the other behaviors you've attached, like a ResponseCacher, since those exist outside of the request pipeline.

Post Method Error : "The request timed out." - Swift

I am sending data to api using the post method. But while working in advance, I have now moved my server to the windows sdd server and started to get the problem I wrote below all the time. While working on Similator, it doesn't work when I try it on my physical phone, I get this problem. What is the problem? A situation related to the firewall? Because I started to get this problem after moving the server. Or another problem?
NSErrorFailingURLStringKey=....php, NSErrorFailingURLKey=....php,
_kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
#objc func veriGonder() {
let url = NSURL(string: "...php")
var request = URLRequest(url: url! as URL)
request.httpMethod = "POST"
...
dataString = dataString + "&formCLASSNAMESTARIH\(verıTURUSTarih)"
dataString = dataString + "&formCLASSNAMESZAMAN\(verıTURUsZaman)"
...
let dataD = dataString.data(using: .utf8)
do {
let uploadJob = URLSession.shared.uploadTask(with: request, from: dataD)
{
data, response, error in
...
}
Here as the error specifies your request timed out. So to fix this either you need to increase the timeout interval or increase the server response interval from server-side. So, if it's the first option here's the code you need:
request.timeoutInterval = 100 // increase this to your desired value.

Alamofire - Add a timeout if there is no response

I have a JSON call using Alamofire, it works well except if the query on the server is not responding. If the endpoint times out then Alamofire does give a timeout error but recently the endpoint was working but MSSQL on the server was not responding. In that case, the SVProgress would just spin and wait for the server to return the response and would not timeout.
How can I add a timeout to the below code so that if the server is not responding after x seconds I get an error?
I'm using Swift 5.
SVProgressHUD.show()
let apiEndpoint: String = "https://intelipos.dynalias.net/iocserver/MobileApp.aspx?action=MobileApp"
let headers = HTTPHeaders(["Content-Type" : "application/json","WebSiteAppID":self.webSiteAppID])
var param = [String: Any?]()
param["Command"] = "GetSales"
let keychain = KeychainSwift()
let sessionID = keychain.get("adminSessionID")!.base64Decoded()!
let strParam = jsonToString(json: ["SessionID":sessionID])
param["Data"] = strParam?.base64Encoded()
param["Signature"] = strParam?.base64Encoded()?.sha256Signature()
let request = AF.request(URL(string: apiEndpoint)!, method: .post, parameters: param as Parameters, encoding: JSONEncoding.default, headers: headers)
You just need to set the timeout interval of your url request to your desired value.
request.timeoutInterval = 30

Alamofire timeout url

I am using the Alamofire Swift library
Alamofire.request
(RestApiManager.sharedInstance.baseURL+"login?language="+lang,
method: .post,
parameters: requestDictionary,
encoding: URLEncoding.httpBody,
headers: headers
).responseObject(keyPath: "") { (response: DataResponse<User>) in
let user = response.result.value
print(user?.status)
print(user?.message)
}
So simply, I want to put a timeout of 60 seconds on every call I make.And i like to give a message connection timeout after 60 seconds. I also want to know, if there exists an internet connection or not. If it doesnt exist, I like to avoid calling alamofire.
Here's the Swift 3.0 / Alamofire 4.0 code to get an alamofireManager that has a 60 second timeout.
You need create a global variable for the request manager:
var alamoFireManager = Alamofire.Manager.sharedInstance
And after configure the custom parameters:
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.timeoutIntervalForRequest = 60 // seconds
configuration.timeoutIntervalForResource = 60
self.alamoFireManager = Alamofire.Manager(configuration: configuration)