Set progressive view for multiple Alamofire calls in swift - ios

In one Viewcontrollers, I have three Alamofire API calls...I wish to set progressive view's progress to 100% when the three API calls are completed?
PS: Also, can someone teach me how to do it for a single Alamofire API call too?
Thanks in advance.

Alamofire offering progress block for giving status about api progress status, you can use this to show your progress of you request or response like below for single api,
Alamofire.request("url", method: "httpMethod", parameters: "parameter", encoding: JSONEncoding.default, headers: "headers").downloadProgress(closure: { (progress) in
// Progress block called frequently during the lifecycle of api.
let fractionCompletedINpercentage = progress?.fractionCompleted * 100
}).validate().responseData(completionHandler: { (response) in
if response.result.isSuccess {
// Download success
} else if response.result.isFailure {
// Download failed
}
})
For handling multiple api, you can use Bool for each api and show your progress by taking minimum or average of fraction completed from all api progress.
Thanks

The download progress is available right in the Alamofire's doc
let utilityQueue = DispatchQueue.global(qos: .utility)
Alamofire.download("https://httpbin.org/image/png")
.downloadProgress(queue: utilityQueue) { progress in
print("Download Progress: \(progress.fractionCompleted)")
}
.responseData { response in
if let data = response.result.value {
let image = UIImage(data: data)
}
}
That said, it probably wouldn't work if the API response is gzipped or the content-length header isn't set.

Working method to use Alamofire
let strURL:String = "https://xxxx"
let parameters: Parameters = ["keyword": "current_timestamp"]
Alamofire.request(strURL, method: .post, parameters: parameters, encoding: URLEncoding.default).responseJSON { (response) in
print(response.data!)
print(response.result)
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}

Related

getting data from AF.Request response

I need the data from the json response from my Post request call using Alamofire but I cannot access that data for some reason
I tried following along with Alamofire github documentation along with this post get data from AF responseJSON. but neither have helped me.
AF.request("https://mbd.cookcountysupernetwork.com/ap/swift_math_get.asp", method: .post, parameters: parameters, encoding: JSONEncoding.default)
.responseJSON { response in
print(response)
print("floop")
}
This is what I see when the code runs
success({
Operand = (
{
A = 12;
},
{
B = 25;
}
);
Operation = Multiply;
Result = 300;
})
so I know the json is there, i just need to access the "Result = 300" so I can set a text box to say "300". but I tried many different methods and I cannot access the information I need from response. Also i do not have a response.result.value which is what almost every post I see about this says to use.
You can access the Result value as,
AF.request("https://mbd.cookcountysupernetwork.com/ap/swift_math_get.asp", method: .post, parameters: parameters, encoding: JSONEncoding.default)
.responseJSON { response in
switch response.result {
case .success(let value):
if let json = value as? [String: Any] {
print(json["Result"] as? Int)
}
case .failure(let error):
print(error)
}
}

FAILURE: responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)

I'm trying to read the JSON using Alamofire. Here is my code:
let headers = ["Content-Type": "application/json"]
func getConfirmationCode(params: [String:Any], block: #escaping(_ data : JSON, _ success : Bool) -> Void) {
if let url = URL(string: baseURL + "getConfirmationCode.php") {
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in
DispatchQueue.main.async {
if let value = response.result.value {
let json = JSON(value)
block(json, true)
} else {
block(JSON.null, false)
}
}
}
}
}
The JSON is valid, everything works perfectly in Postman, but I can't make it work. None of the suggestions on the web helped (changing the responseJSON to responseString/responseData, changing the JSONEncoding.default to URLEncoding.default, etc.)
Can anyone help me?
You should try to check response in postman in "Preview" tab of response section. sometime it displays proper json in "Pretty" section. but in "Preview" section it many contains some print statements of API response. and those print statements makes problem in json decoding.
also, if you want to get swift code of postman response you can always get it from postman's code feature:
Hope this helps..!

Alamofire (json, request, delay)

i have a json request and my problem is that the response from the server does not have time to come and because of this I get an error because I'm working with data (in viewdidload()) which is not yet available. I tried to read about synchronous and asynchronous requests but I don't understand how to do them.
in viewDidLoad() i call my fucn which is call to the my server and i wait a json, after executing the function, I start working with the data that should come , But the code does not wait for the moment when they come and go further. Can I specify a delay or something like that?
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON {
(response: DataResponse) in
switch(response.result) {
case .success(let value):
let json = JSON(value)
for index in 0 ..< json["items"].count {
let path = json["items"][index]
self.Data.append(ProfileModel())
self.Data[index].name = path["name"].stringValue
self.Data[index].email = path["email"].stringValue
self.Data[index].created = path["created"].double!
self.tableView.reloadData()
}
DispatchQueue.main.async {
}
case .failure(let error):
print(error)
break
}
}.resume()
}

How to set method, header, parameter in Alamofire 4 and Swift 3

In past version of Alamofire, for send method,header and parameter I used to do like this:
Alamofire.request(.GET, URLRequest, headers:headers, parameters: parameters)
but version 4 and swift 3 is different.
How can I set method, send header & parameter?
The migration guide at Alamofire github explains this very well.
Take a look here:
// Alamofire 3
let parameters: [String: AnyObject] = ["foo": "bar"]
Alamofire.request(.GET, urlString, parameters: parameters, encoding: .JSON)
.progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
print("Bytes: \(bytesRead), Total Bytes: \(totalBytesRead), Total Bytes Expected: \(totalBytesExpectedToRead)")
}
.validate { request, response in
// Custom evaluation closure (no access to server data)
return .success
}
.responseJSON { response in
debugPrint(response)
}
// Alamofire 4
let parameters: Parameters = ["foo": "bar"]
Alamofire.request(urlString, method: .get, parameters: parameters, encoding: JSONEncoding.default)
.downloadProgress(queue: DispatchQueue.utility) { progress in
print("Progress: \(progress.fractionCompleted)")
}
.validate { request, response, data in
// Custom evaluation closure now includes data (allows you to parse data to dig out error messages if necessary)
return .success
}
.responseJSON { response in
debugPrint(response)
}
The migration guide explained well, but there are no headers in the example, just to avoid confusions, bellow I add the example of a GET request to add them.
Alamofire.request(URL, method: .get, parameters: parameters, headers: headers)
.validate { request, response, data in
return .success
}
.responseJSON { response in
switch response.result {
case .success:
// do something
break
case .failure(let error):
// handle error
break
}
}
I found this information in here so, go and check it there if you have question related with the headers in the request.

Alamofire POST request with progress

I'm using Alamofire to do a POST request.
As this POST request can take a while and I want to keep track of the progress and display it as a ProgressView.
Alamofire.request(.POST, ApiLink.create_post, parameters: parameters, encoding: .JSON)
.progress { (bytesRead, totalBytesRead, totalBytesExpectedToRead) -> Void in
println("ENTER .PROGRESSS")
println("\(totalBytesRead) of \(totalBytesExpectedToRead)")
self.progressView.setProgress(Float(totalBytesRead) / Float(totalBytesExpectedToRead), animated: true)
}
.responseJSON { (_, _, mydata, _) in
println(mydata)
}
However, I've noticed that the .progress block only get called after the post request has ended instead of getting called multiple times to actually keep track of the progress.
println("ENTER .PROGRESSS") gets called only once (at the end)
How can I make .progress works with Alamofire.request POST ?
Also : My parameters include a base64 encoded image string. I'm using a back-end Ruby on Rails to process the image. It's that process that is taking quite some time.
What you can do instead is first use the ParameterEncoding enum to generate the HTTPBody data. Then you can pull that data out and pass it off to the Alamofire upload method. Here's a modified version of your same function that compiles in a playground and instead uses the upload function.
struct ApiLink {
static let create_post = "/my/path/for/create/post"
}
let parameters: [String: AnyObject] = ["key": "value"] // Make sure this has your image as well
let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: ApiLink.create_post)!)
mutableURLRequest.HTTPMethod = Method.POST.rawValue
let encodedURLRequest = ParameterEncoding.JSON.encode(mutableURLRequest, parameters: parameters).0
let data = encodedURLRequest.HTTPBody!
let progressView = UIProgressView()
Alamofire.upload(mutableURLRequest, data)
.progress { _, totalBytesRead, totalBytesExpectedToRead in
println("ENTER .PROGRESSS")
println("\(totalBytesRead) of \(totalBytesExpectedToRead)")
progressView.setProgress(Float(totalBytesRead) / Float(totalBytesExpectedToRead), animated: true)
}
.responseJSON { _, _, mydata, _ in
println(mydata)
}
This will certainly have progress updates as #mattt originally mentioned in his comment above.
As #cnoon said you can use upload method to track progress with some modifications. Here is what exactly worked with me:
let jsonData = NSJSONSerialization.dataWithJSONObject(jsonObject, options: .PrettyPrinted)
Alamofire.upload(.POST, "API URL String", headers: ["Content-Type": "application/json"], data: jsonData)
.validate()
.responseJSON(completionHandler: { (response: Response<AnyObject, NSError>) in
//Completion handler code
})
.progress({ (bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) in
//Progress handler code
})
Note that you must set the "Content-Type" http header field value to "application/json" if the data is formatted as json to be decoded correctly at the backend.
There's a separate method in Alamofire to upload. Please check their documentation here.
They have sub-sections
Uploading with Progress
Uploading MultipartFormData
Which describes uploading.

Resources