How to use the AFNetworking 2.0 library synchronously?

5

I would like to call a rest service using the AFNetworking library. How to make a call synchronously, ie wait for the return of the webservice?

For example:

Method that will return a carriage object:

Carro *carro = [self findCarroById:idCarro];
//restante do código... preciso ter a variável carro carregada antes de prosseguir.

Method that will be called:

- (Carro *)findCarroById:(NSString *)idCarro {

    NSString *url = [NSString stringWithFormat: @"%@%@", @"http://www.site.com/rest/carro/", idCarro];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    manager.responseSerializer = [AFJSONResponseSerializer serializer];

    [manager GET:url parameters:nil
         success:^(AFHTTPRequestOperation *operation, id json) {
            Carro *carro = [[Carro alloc] init];

            carro.idCarro = [json objectForKey:@"id"];
            carro.descricao = [json objectForKey:@"descricao"];

            //talvez poderia colocar o return aqui
         }
         failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Erro: \n\n%@", error);
         }
     ];

    return carro;
}
    
asked by anonymous 15.02.2014 / 22:17

2 answers

2

This is not the correct way to proceed. Because you're dealing with an HTTP call, you can not assume that the application will wait for it to end.

Implementations in this way would block the user interface if used on the main thread (the application would appear to be locked to the user), so the AFNetworking library does not even care about performing synchronous requests.

Imagine that you are loading the information of a car to be displayed on a screen in an iPhone app, what you should do is request the car information in - (void) viewDidLoad; , and present the user with a loading indicator "Loading ... "for example.

When the load is finished, that is, in the success block, you must then change the views with the new data loaded. Here is an example:

- (void) viewDidLoad {
    // Solicita o carregamento do carro, porém não espera um retorno.
    [self loadCarWithId:carId];
    // Exibe indicador de progresso para o usuário.
    [ProgressHUD show:@"Loading..."];
}

- (void) loadCarWithId:(NSInteger)carId {
    NSString *url = [NSString stringWithFormat: @"%@%@", @"http://www.site.com/rest/carro/", carId];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    manager.responseSerializer = [AFJSONResponseSerializer serializer];

    [manager GET:url parameters:nil
         success:^(AFHTTPRequestOperation *operation, id json) {
            // Lida com os dados após o carregamento.
            Carro *carro = [[Carro alloc] init];
            carro.idCarro = [json objectForKey:@"id"];
            carro.descricao = [json objectForKey:@"descricao"];


            // Atualiza a tela com os dados do carro
            self.carIdLabel.text = carr.idCarro; // Assumindo que existe uma label "carIdLabel" na sua view.
            self.carDescriptionLabel.text = carro.descricao;  // Assumindo que existe uma label "carDescriptionLabel" na sua view.

            // Você também pode chamar um médoto quando esta requisição for concluída.
            [self saveCar:carro];
            // Remove o indicador de progresso pois o carregamento já foi concluído.
            [ProgressHUD dismiss];
         }
         failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Erro: \n\n%@", error);
            // Remove o indicador de progresso pois o carregamento falhou.
            [ProgressHUD dismiss];
            // Avisa o usuário que o carregamento falhou ou tenta denovo.
         }
     ];

    // Não há retorno pois essa requisição é assíncrona.

}

// Isso só vai ser executado depois que a requisição for concluída
// já que está sendo chamado dentro do block de success.
- (void) saveCar:(Carro)carro {
    [[NSUserDefaults standartUserDefaults] setObject:carro forKey:@"savedCar"]; 
    //Isso é apenas um exemplo, não funciona pois o objeto Carro precisa ser desserializado para ser salvo no user defaults.
}

EDIT:

Added activity indicator example through ProgressHUD: link

    
16.02.2014 / 18:55
1

Man, I think your question has already been answered .. but to complete and help future questions ... Ray Wenderlich's staff posted this week a tutorial on AFNetworking 2.0 ... follow the link:

link

    
18.02.2014 / 04:11