El manejo de errores en Alamofire

Tengo el HTTP de código en un AngularJS controlador:

$http.post('/api/users/authenticate', {email: $scope.email, password: $scope.password})
    .success(function (data, status, headers, config) {
        authService.login($scope.email);
        $state.go('home');
    })
    .error(function (data, status, headers, config) {
        $scope.errorMessages = data;
        $scope.password = "";
    });

En el caso de éxito, el servidor responderá con una representación JSON de un usuario. En el caso de error el servidor responderá con una simple cadena de caracteres tales como User not found que se puede acceder a través de la data parámetro.

Estoy teniendo problemas para averiguar cómo hacer algo similar en Alamofire. He aquí lo que tengo ahora mismo:

@IBAction func LoginPressed(sender: AnyObject) {
    let params: Dictionary<String,AnyObject> = ["email": emailField.text, "password": passwordField.text]

    Alamofire.request(.POST, "http://localhost:3000/api/users/authenticate", parameters: params)
        .responseJSON {(request, response, data, error) in
            if error == nil {
                dispatch_async(dispatch_get_main_queue(), {
                    let welcome = self.storyboard?.instantiateViewControllerWithIdentifier("login") as UINavigationController;

                    self.presentViewController(welcome, animated: true, completion: nil);
                })
            }
            else{
                dispatch_async(dispatch_get_main_queue(), {
                    //I want to set the error label to the simple message which I know the server will return
                    self.errorLabel.text = "something went wrong"
                });
            }
    }
}

No tengo idea de si estoy manejando la no-caso de error correctamente y agradecería entrada en la así.

OriginalEl autor Paymahn Moghadasian | 2015-03-13

2 Kommentare

  1. 27

    Usted está en la pista derecha, pero se va a ejecutar en algunos temas cruciales con su aplicación actual. Hay un bajo nivel de Alamofire cosas que están pasando en el viaje hasta que me quiere ayudar con. He aquí una versión alternativa de su ejemplo de código que será mucho más efectivo.

    @IBAction func loginPressed(sender: AnyObject) {
        let params: [String: AnyObject] = ["email": emailField.text, "password": passwordField.text]
    
        let request = Alamofire.request(.POST, "http://localhost:3000/api/users/authenticate", parameters: params)
        request.validate()
        request.response { [weak self] request, response, data, error in
            if let strongSelf = self {
                let data = data as? NSData
    
                if data == nil {
                    println("Why didn't I get any data back?")
                    strongSelf.errorLabel.text = "something went wrong"
                    return
                } else if let error = error {
                    let resultText = NSString(data: data!, encoding: NSUTF8StringEncoding)
                    println(resultText)
                    strongSelf.errorLabel.text = "something went wrong"
                    return
                }
    
                var serializationError: NSError?
    
                if let json: AnyObject = NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments, error: &serializationError) {
                    println("JSON: \(json)")
                    let welcome = self.storyboard?.instantiateViewControllerWithIdentifier("login") as UINavigationController
                    self.presentViewController(welcome, animated: true, completion: nil)
                } else {
                    println("Failed to serialize json: \(serializationError)")
                }
            }
        }
    }

    Validación

    Primer lugar, la validate función en la solicitud de validar los siguientes:

    • HTTPStatusCode – Tiene que ser de 200…299
    • Content-Type – Este encabezado en la respuesta debe coincidir con el Accept encabezado en la solicitud original

    Usted puede encontrar más información acerca de la validación en Alamofire en el LÉAME.

    Weakify /Strongify

    Asegúrese débil auto y una fuerte auto de su cierre para asegurarse de que no terminan creando una retener ciclo.

    De envío a Cola Principal

    Su despacho llama de nuevo a la cola principal no son necesarias. Alamofire garantiza que su controlador de finalización en el response y responseJSON serializadores es llamada en la cola principal. En realidad se puede proporcionar su propio despacho de la cola para ejecutar los serializadores si lo desea, pero ni su solución o la mina que se está haciendo actualmente para hacer que el envío de llamadas a la cola principal completamente innecesario.

    Respuesta Serializador

    En su caso particular, usted realmente no desea utilizar el responseJSON serializador. Si usted lo hace, usted no acaban de obtener datos de vuelta si usted no pasa la validación. La razón es que la respuesta de la serialización JSON es lo que va a ser devuelto como el AnyObject. Si la serialización de falla, el AnyObject será nula, y usted no será capaz de leer los datos.

    En su lugar, utilice el response serializador y tratar de analizar los datos de forma manual con NSJSONSerialization. Si eso no funciona, entonces usted puede confiar en la buena ole NSString(data:encoding:) método para imprimir los datos.

    Esperemos que esto ayuda a arrojar algo de luz sobre algunos de los complicados caminos que se tropezó.

    Es el uso de [débiles auto] es necesario cuando no se hace referencia? Siempre he entendido que no es necesario si el cierre no es fuertemente que se hace referencia en cualquier lugar.
    Gran pregunta, imposible dar una respuesta sucinta. Depende del comportamiento que usted desea. Si desea que el propietario de la loginPressed método que se celebrará en la memoria sin importar si nada es mantener una referencia a ella, entonces usted no desea utilizar [weak self]. Sin embargo, siempre se corre el riesgo potencial de creación de una retener el ciclo si no se utiliza el weakify/strongify patrón. Más información de aquí y here.
    Buena explicación. En Swift 3 puede sustituir if let strongSelf = self { ... } con sólo guard let strongSelf = self else { return }
    guard se introdujo en Swift 2.

    OriginalEl autor cnoon

  2. 1

    Así Alamofire trata a todas las solicitudes de éxito. Esto realmente viene a ser el servidor de la API de encabezados http devuelto.

    Usted podría utilizar Alamofire.Solicitud.validar()

    Que te permitirá validar los encabezados http, etc. Retirar el ejemplo

    https://github.com/Alamofire/Alamofire#validation

    Estoy asumiendo el mensaje de error se mostrará en la data objeto.

    para acceder a los valores de los datos se podría hacer algo como

    No estoy realmente seguro de su respuesta api se ve, pero en este ejemplo

    {
         "message": "Could not authenticate"
    }
    let message: String? = data?.valueForKey("message") as String
    A la derecha, todo es tratado como un éxito. En un caso de error el código de estado podría ser de 500 y presumo que la error no será nulo. Cuando ese es el caso, data es un AnyObject y no estoy seguro de cómo acceder a la real User not found contenido.

    OriginalEl autor slik

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...