Search code examples
swift3closuresalamofire

Swift 3: Alamorefire block UI


I have APIManager singleton class and have a function to get data from server like this:

func scanOrder(order: String, completion:@escaping Handler){
    let url = K.API_URL + "/api/containers/picking/" + order

    Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: getHeader()).responseJSON { (response) in
        DispatchQueue.main.async {
            completion(response)
        }
    }
}

and I call this function in other class like this:

apiMan.scanOrder(order: tfCode.text!) { (response) in
        ...
    }

while waiting for server to response, my UI is blocked. I tried to wrap alamofire request call within DispatchQueue.global().async but it still blocks the UI.
Please help!


Solution

  • I never used Alamofire.request with DispatchQueue.main.async like you do. The reason is that Alamofire in combination with completion blocks already operates async and shouldn't block the UI, which is settled in the Main Thread.

    Have you tried something like:

    class NetworkManager {
    
        func scanOrder(order: String, completion:@escaping (Any?) -> Void){
            let url = "https://example.com/api/containers/picking/" + order
    
            Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: AppConfiguration.sharedInstance.defaultHeader())
                .responseJSON { response in
                    guard response.result.isSuccess else {
                        Log.info("Error while fetching: \(response.result.error)")
                        completion(nil)
                        return
                    }
    
                    guard let responseJSON = response.result.value as? [String: AnyObject] else {
                        Log.info("Invalid information received from service")
                        completion(nil)
                        return
                    }
                    completion(responseJSON)
            }
        }
    }
    

    Call:

    class CallingClass {
        func scanOrder(order:String){
            let manager = NetworkManager()
            var result: Any?
    
            manager.scanOrder(order: "example") { response in
                result = response
            }
            print(result as Any)
        }
    }