Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alamofire network calls not being run in background thread

Tags:

It is my understanding that by default, Alamofire requests run in a background thread.

When I tried running this code:

let productsEndPoint: String = "http://api.test.com/Products?username=testuser"          Alamofire.request(productsEndPoint, method: .get)             .responseJSON { response in                 // check for errors                 guard response.result.error == nil else {                     // got an error in getting the data, need to handle it                     print("Inside error guard")                     print(response.result.error!)                     return                 }                  // make sure we got some JSON since that's what we expect                 guard let json = response.result.value as? [String: Any] else {                     print("didn't get products as JSON from API")                     print("Error: \(response.result.error)")                     return                 }                  // get and print the title                 guard let products = json["products"] as? [[String: Any]] else {                     print("Could not get products from JSON")                     return                 }                 print(products)          } 

The UI was unresponsive until all the items from the network call have finished printing; so I tried using GCD with Alamofire:

let queue = DispatchQueue(label: "com.test.api", qos: .background, attributes: .concurrent)      queue.async {          let productsEndPoint: String = "http://api.test.com/Products?username=testuser"          Alamofire.request(productsEndPoint, method: .get)             .responseJSON { response in                 // check for errors                 guard response.result.error == nil else {                     // got an error in getting the data, need to handle it                     print("Inside error guard")                     print(response.result.error!)                     return                 }                  // make sure we got some JSON since that's what we expect                 guard let json = response.result.value as? [String: Any] else {                     print("didn't get products as JSON from API")                     print("Error: \(response.result.error)")                     return                 }                  // get and print the title                 guard let products = json["products"] as? [[String: Any]] else {                     print("Could not get products from JSON")                     return                 }                 print(products)          }     } 

and the UI is still unresponsive as it was before.

Am I doing anything wrong here, or does the fault lie with Alamofire?

like image 552
SJCypher Avatar asked Jan 18 '17 17:01

SJCypher


1 Answers

I was wrong about Alamofire running on a background thread by default. It actually runs on the main queue by default. I've opened an issue on Alamofire's Github page and it's been solved here: https://github.com/Alamofire/Alamofire/issues/1922

The correct way to solve my problem was to specify what kind of queue I want my request to be run on using the "queue" parameter on the .responseJSON method (

.responseJSON(queue: queue) { response in ... } 

)

This is the entire, corrected version of my code:

let productsEndPoint: String = "http://api.test.com/Products?username=testuser"      let queue = DispatchQueue(label: "com.test.api", qos: .background, attributes: .concurrent)      Alamofire.request(productsEndPoint, method: .get)         .responseJSON(queue: queue) { response in             // check for errors             guard response.result.error == nil else {                 // got an error in getting the data, need to handle it                 print("Inside error guard")                 print(response.result.error!)                 return             }              // make sure we got some JSON since that's what we expect             guard let json = response.result.value as? [String: Any] else {                 print("didn't get products as JSON from API")                 print("Error: \(response.result.error)")                 return             }              // get and print the title             guard let products = json["products"] as? [[String: Any]] else {                 print("Could not get products from JSON")                 return             }             print(products)      } 
like image 191
SJCypher Avatar answered Sep 22 '22 05:09

SJCypher