Método de obtención de datos de AFNetworking no llamado

Estoy creando una aplicación en la que, en la primera vista, el usuario tiene la opción de iniciar sesión o registrarse. En la vista de registro hay un UITableViewCell que, cuando se hace clic, lleva al usuario a una vista que contiene un UITableView y UIPickerView. Las UITableView está funcionando correctamente, pero el UIPickerView, que se supone que extrae dinámicamente los datos que se supone que debe mostrar mediante una llamada web, se muestra pero aparece completamente en blanco. poniendo unos cuantos NSLog declaraciones, noté que los métodos en el Modelo que extraen los datos usando AFNetworking nunca son llamados. He publicado el código a continuación para el UIPickerViewDelegate y UIPickerViewDataSource métodos, así como el método que se supone que extraerá los datos en el Modelo. Gracias por adelantado.

UIPickerViewDelegate

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row 
            forComponent:(NSInteger)component {
    return [[self.brain classChoicesForSignUp] objectAtIndex:row];
}

UIPickerViewDataSource

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView 
numberOfRowsInComponent:(NSInteger)component {
    size_t numberOfRows = [self.brain classChoicesForSignUp].count;

    NSLog(@"Number of Rows: %@", [[NSNumber numberWithFloat:numberOfRows] stringValue]);

    return numberOfRows;
}

SignUpPickerBrain.m

#import "SignUpPickerBrain.h"
#import "AFJSONRequestOperation.h"

@implementation SignUpPickerBrain

#pragma mark - Picker Data

- (NSArray *)classChoicesForSignUp {
    NSLog(@"Class choices method called");
    // Note that in my code, the actual URL is present here.
    NSURL *url = [NSURL URLWithString:@"the URL"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        NSLog(@"Success!");
        NSLog([JSON description]);
    } failure:nil];

    [operation start];
    [operation waitUntilFinished];
    NSLog([operation responseJSON]);
    return [operation responseJSON];
}

@end

preguntado el 12 de junio de 12 a las 18:06

1 Respuestas

Hay muchos antipatrones en este ejemplo de código. Recomiendo enfáticamente en contra de su enfoque actual, y considere los siguientes puntos:

  • hacer networking de forma asíncrona, es decir, no usar [operation waitUntilFinished];. Cada vez que esté creando un método que realice una solicitud de red, asígnele un parámetro de bloque que se pueda usar como una devolución de llamada una vez que lleguen los resultados.
  • Almacene sus resultados en una propiedad de matriz en el controlador, o similar, y utilícelo para controlar sus delegados y fuentes de datos. En su enfoque actual, realizará una solicitud de red cada vez que se muestre una fila (!). Entonces, en su lugar, inicialice en una matriz vacía y, una vez que los nuevos resultados se establezcan en esa propiedad, vuelva a cargar la fuente de datos. Una solicitud asíncrona. Fácil.
  • Deshacerse de SignUpPickerBrain. Use un modelo adecuado o simplemente haga la llamada en el controlador. El proyecto iOS de ejemplo tiene algunos grandes patrones a seguir.
  • Utiliza AFHTTPClient. Si está interactuando con un servicio web en particular, puede ser muy útil tener un AFHTTPClient subclase para manejar todas esas solicitudes.

Respondido el 13 de junio de 12 a las 16:06

Muchas gracias por su respuesta. Aunque tengo un par de preguntas. Pensé que cuando se trata de obtener datos y cosas así, usa un archivo como SignUpPickerBrain. ¿Podría elaborar un poco más sobre lo que quiere decir con un "Modelo adecuado"? También estoy un poco confundido en cuanto a por qué le daría un parámetro de bloque al método de solicitud de red, ya que no estoy haciendo nada más que devolver los datos. Sin embargo, soy bastante nuevo en los bloques, por lo que fácilmente podría ser la razón por la que no veo la utilidad aquí. Gracias de nuevo por todas tus recomendaciones. - sethfri

El bloque pasado como parámetro de método se ejecutaría en el bloque de finalización (o éxito/fracaso) de la operación de solicitud de red. De esta manera es asíncrono. Una vez más, consulte el proyecto de ejemplo de iOS en AFNetworking para ver esto en acción. - Mattt

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.