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?
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) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With