De haber utilizado el AlamoFire marco me he dado cuenta de que la completionHandler se ejecuta en el hilo principal. Me pregunto si el código de abajo es una buena práctica para la creación de un Núcleo de importación de Datos de tarea dentro del controlador de finalización:

Alamofire.request(.GET, "http://myWebSite.com", parameters: parameters)
            .responseJSON(options: .MutableContainers) { (_, _, JSON, error) -> Void in
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { () -> Void in
                    if let err = error{
                        println("Error:\(error)")
                        return;
                    }

                    if let jsonArray = JSON as? [NSArray]{                       
                        let importer = CDImporter(incomingArray: jsonArray entity: "Artist", map: artistEntityMap);

                    }
                });
            }
InformationsquelleAutor TheM00s3 | 2015-04-24

3 Comentarios

  1. 154

    Esta es una muy buena pregunta. Su enfoque es perfectamente válido. Sin embargo, Alamofire en realidad puede ayudar a agilizar aún más.

    Su Código De Ejemplo De Envío De La Cola De Desglose

    En el ejemplo de código, se están saltando entre las siguientes despacho de colas:

    1. NSURLSession despacho de la cola de
    2. TaskDelegate despacho de la cola para la validación y el serializador de procesamiento de
    3. Principal despacho de la cola para llamar a su controlador de finalización
    4. Cola de alta prioridad para el manejo de JSON
    5. Principal despacho de la cola a la actualización de la interfaz de usuario (si es necesario)

    Como usted puede ver, usted está saltando por todo el lugar. Echemos un vistazo a un enfoque alternativo al aprovechar una característica de gran alcance dentro de Alamofire.

    Alamofire Respuesta Despacho Colas

    Alamofire tiene un enfoque óptimo incorporada en su propio bajo nivel de procesamiento. El único response método que consigue en última instancia llamada por toda respuesta personalizada serializadores tiene soporte para un envío personalizado de cola si lo que usted elija.

    Mientras que el MCD es increible en un salto entre el envío de las colas, desea evitar saltar a una cola que está ocupado (por ejemplo, el hilo principal). Al eliminar el salto de nuevo a la principal hilo en el centro de la async procesamiento, puede potencialmente acelerar las cosas considerablemente. El siguiente ejemplo muestra cómo hacer esto utilizando Alamofire lógica de la hacia fuera-de-la-caja.

    Alamofire 1.x

    let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)
    
    let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
    request.response(
        queue: queue,
        serializer: Request.JSONResponseSerializer(options: .AllowFragments),
        completionHandler: { _, _, JSON, _ in
    
            //You are now running on the concurrent `queue` you created earlier.
            println("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
    
            //Validate your JSON response and convert into model objects if necessary
            println(JSON)
    
            //To update anything on the main thread, just jump back on like so.
            dispatch_async(dispatch_get_main_queue()) {
                println("Am I back on the main thread: \(NSThread.isMainThread())")
            }
        }
    )

    Alamofire 3.x (Swift 2.2 y 2.3)

    let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)
    
    let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
    request.response(
        queue: queue,
        responseSerializer: Request.JSONResponseSerializer(options: .AllowFragments),
        completionHandler: { response in
            //You are now running on the concurrent `queue` you created earlier.
            print("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")
    
            //Validate your JSON response and convert into model objects if necessary
            print(response.result.value)
    
            //To update anything on the main thread, just jump back on like so.
            dispatch_async(dispatch_get_main_queue()) {
                print("Am I back on the main thread: \(NSThread.isMainThread())")
            }
        }
    )

    Alamofire 4.x (Swift 3)

    let queue = DispatchQueue(label: "com.cnoon.response-queue", qos: .utility, attributes: [.concurrent])
    
    Alamofire.request("http://httpbin.org/get", parameters: ["foo": "bar"])
        .response(
            queue: queue,
            responseSerializer: DataRequest.jsonResponseSerializer(),
            completionHandler: { response in
                //You are now running on the concurrent `queue` you created earlier.
                print("Parsing JSON on thread: \(Thread.current) is main thread: \(Thread.isMainThread)")
    
                //Validate your JSON response and convert into model objects if necessary
                print(response.result.value)
    
                //To update anything on the main thread, just jump back on like so.
                DispatchQueue.main.async {
                    print("Am I back on the main thread: \(Thread.isMainThread)")
                }
            }
        )

    Alamofire Despacho De La Cola De Desglose

    Aquí está el desglose de los diferentes envío de las colas de los involucrados con este enfoque.

    1. NSURLSession despacho de la cola de
    2. TaskDelegate despacho de la cola para la validación y el serializador de procesamiento de
    3. Personalizado del administrador de concurrentes envío de cola para el manejo de JSON
    4. Principal despacho de la cola a la actualización de la interfaz de usuario (si es necesario)

    Resumen

    Por la eliminación de la primera saltar de nuevo a la principal despacho de la cola, se han eliminado un cuello de botella potencial así como se han hecho toda su solicitud y procesamiento asincrónico. Impresionante!

    Con eso dicho, no puedo enfatizar lo suficiente lo importante que es para familiarizarse con el funcionamiento interno de cómo Alamofire realmente funciona. Usted nunca sabe cuándo usted puede encontrar algo que realmente puede ayudarle a mejorar su propio código.

    • Gracias por la explicación detallada, @cnoon. Parece que el segundo parámetro de la response método que ahora se llama responseSerializer en lugar de serializer (en Alamofire 3.0). Que causó una Cannot call value of non-function type 'NSHTTPURLResponse?' error que me había confundido un poco.
    • por favor, subir los cambios, el código no es viable. Swift 2.1, XCode 7.1
    • Actualizado @Beraliv.
    • Gracias, @cnoon
    • ¿qué acerca de responseJSON? ¿Cómo puedo pasar en la cola del parámetro
    • muchas gracias, me he pasado el día entero en esta
    • puede ser agradable si usted añadir actualización para swift 3 también.
    • Todo actualizado @Mike.R.
    • Ahora trabaja para Swift 3 también. Brillante
    • podría usted por favor me ayude a solucionar mi alamofire solicitud de carga stackoverflow.com/questions/42042860/…
    • Gran post!!!

  2. 2

    Pequeña Actualización para Swift 3.0 ,Alamofire (4.0.1),Edición de @cnoon respuesta:

    let queue = DispatchQueue(label: "com.cnoon.manager-response-queue",
                              qos: .userInitiated,
                              attributes:.concurrent)
    Alamofire?.request(SERVER_URL, method: .post,
    parameters: ["foo": "bar"], 
    encoding: JSONEncoding.default,//by default
    headers: ["Content-Type":"application/json; charset=UTF-8"])
    .validate(statusCode: 200..<300).//by default
    responseJSON(queue: queue, options: .allowFragments, 
    completionHandler: { (response:DataResponse<Any>) in
    
            switch(response.result) {
            case .success(_):
                break
            case .failure(_):
                print(response.result.error)
                if response.result.error?._code == NSURLErrorTimedOut{
                    //TODO: Show Alert view on netwok connection.
                }
                break
            }
        })
  3. 1

    Sólo complementando la respuesta perfecta de @cnoon, si que me gusta es el uso de ResponseObjectSerializable puede incrustar este concurrente sobre el comportamiento de solicitud de extensión de sí mismo:

    extension Request {
        public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, NSError> -> Void) -> Self {
            let responseSerializer = ResponseSerializer<T, NSError> { request, response, data, error in
                guard error == nil else { return .Failure(error!) }
    
                let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
                let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
    
                switch result {
                case .Success(let value):
                    if let
                        response = response,
                        responseObject = T(response: response, representation: value)
                    {
                        return .Success(responseObject)
                    } else {
                        let failureReason = "JSON could not be serialized into response object: \(value)"
                        let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
                        return .Failure(error)
                    }
                case .Failure(let error):
                    return .Failure(error)
                }
            }
    
            let queue = dispatch_queue_create("my.queue", DISPATCH_QUEUE_CONCURRENT)
            return response(queue: queue, responseSerializer: responseSerializer) { response in
                dispatch_async(dispatch_get_main_queue()) {
                    completionHandler(response)
                }
            }
        }
    }

Dejar respuesta

Please enter your comment!
Please enter your name here