web-dev-qa-db-fra.com

Les appels réseau Alamofire ne sont pas exécutés dans le thread d'arrière-plan

Je crois comprendre que par défaut, les requêtes Alamofire s'exécutent dans un thread d'arrière-plan.

Lorsque j'ai essayé d'exécuter ce 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)

        }

L'interface utilisateur ne répondait pas jusqu'à ce que tous les éléments de l'appel réseau aient fini d'imprimer; j'ai donc essayé d'utiliser GCD avec 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)

        }
    }

et l'interface utilisateur ne répond toujours pas comme avant.

Suis-je en train de faire quelque chose de mal ici, ou est-ce la faute à Alamofire?

18
SJCypher

Je me trompais sur Alamofire fonctionnant sur un thread d'arrière-plan par défaut. Il s'exécute en fait sur la file d'attente principale par défaut. J'ai ouvert un problème sur la page Github d'Alamofire et il a été résolu ici: https://github.com/Alamofire/Alamofire/issues/1922

La bonne façon de résoudre mon problème était de spécifier sur quel type de file d'attente je veux que ma demande soit exécutée en utilisant le paramètre " queue " sur le .responseJSON méthode (

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

)

Voici la version complète et corrigée de mon 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)
     }
27
SJCypher