Question

I'm new to iOS and I have trouble understanding and applying well dispatch ... I have an application I need to query a website (api) within a for loop, the end of that cycle I need to make further inquiries in another cycle, and finally, at the end of both cycles need to switch views.

I now have this code (after much trial and error but still does not work):

dispatch_queue_t queue = dispatch_queue_create("threadServicios", DISPATCH_QUEUE_SERIAL);

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);

    dispatch_async(queue, ^(void) {
        NSLog(@"llego a buscar servicios por local");
        for (NSDictionary *local in _arrLocalesTmp) {
            [self getListaServiciosPorLocal:[local objectForKey:@"idLocal"]];
            //this function calls another function that consumes a web service and get a json
        }

        procced = YES;

        NSLog(@"llego a buscar profesionales por local");
        for (NSDictionary *local in _arrLocalesTmp) {
            [self getListaProfesionalesPorLocal:[local objectForKey:@"idLocal"]];
            //this function calls another function that consumes a web service and get a json
        }

        procced2 = YES;

        dispatch_group_leave(group);
    });

    dispatch_group_notify(group, dispatch_get_main_queue(),^{
        NSLog(@"dispatch procced 1");
        if (procced && procced2) {
            [self setFormularioConsultaCompleto];
        }
    });

The function [self getListaServiciosPorLocal: [Local objectForKey: @ "idLocal"]]; is as follows:

dispatch_async(dispatch_get_main_queue(), ^(void) {
    NSURL *url = [NSURL URLWithString:urlConnection];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfiguration.timeoutIntervalForRequest = 30;
    sessionConfiguration.timeoutIntervalForResource = 60;

    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        __block NSError *jsonError;
        NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *) response;

        if(!error) {
            if(urlResponse.statusCode == 200) {
                NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&jsonError];

                if(response) {
                NSString *resp = [NSString stringWithFormat:@"%@", [dataResponse objectForKey:@"resp"]];
                if([resp isEqualToString:@"1"]) {
                    _json = [dataResponse objectForKey:@"data"];
                    [_arrServiciosTmp addObjectsFromArray:(NSArray *)_json];
                } else {
                    NSString *message = [dataResponse objectForKey:@"description"];
                }
            } else {
                self.lblMensaje.text = @"Ha ocurrido un error al obtener la información, por favor, vuelva a intentarlo en unos momentos.";
            }
            } else {
                completion(nil);
            }
        } else {
            NSLog(@"Error en Task");
        }                            
    });

And the function [self getListaProfesionalesPorLocal: [Local objectForKey: @ "idLocal"]]; is similar but obtains other information

The problem is that the app calls this function [self setFormularioConsultaCompleto]; (changing the view) but the above functions still do not quite get all the data from webservice.

Sorry for this, but I gave up, I hope can help me!

Thanks!

Était-ce utile?

La solution

The below uses dispatch groups to hold off starting another block till the groups work has been completed.

First change your data methods to not be wrapped in dispatch_async and accept a completion block, calling that at the end of the NSURLSessionDataTasks completionHandler:

-(void)getListaServiciosPorLocal:(id)whatEver withCompletionBlock:(dispatch_block_t)block
{
    NSURL *url = [NSURL URLWithString:urlConnection];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfiguration.timeoutIntervalForRequest = 30;
    sessionConfiguration.timeoutIntervalForResource = 60;

    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        __block NSError *jsonError;
        NSHTTPURLResponse *urlResponse = (NSHTTPURLResponse *) response;

        if(!error) {
            if(urlResponse.statusCode == 200) {
                NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&jsonError];

                if(response) {
                    NSString *resp = [NSString stringWithFormat:@"%@", [dataResponse objectForKey:@"resp"]];
                    if([resp isEqualToString:@"1"]) {
                        _json = [dataResponse objectForKey:@"data"];
                        [_arrServiciosTmp addObjectsFromArray:(NSArray *)_json];
                    } else {
                        NSString *message = [dataResponse objectForKey:@"description"];
                    }
                } else {
                    self.lblMensaje.text = @"Ha ocurrido un error al obtener la información, por favor, vuelva a intentarlo en unos momentos.";
                }
            } else {
                completion(nil);
            }
        } else {
            NSLog(@"Error en Task");
        }  
        block();  // Notify completion block                        
    });
}

Now when you call these methods:

dispatch_group_t group = dispatch_group_create();

dispatch_async(queue, ^(void) {

    NSLog(@"llego a buscar servicios por local");
    for (NSDictionary *local in _arrLocalesTmp) {
        dispatch_group_enter(group);
        [self getListaServiciosPorLocal:[local objectForKey:@"idLocal"] withCompletionBlock:^{
            dispatch_group_leave(group);
        }];
    }

    NSLog(@"llego a buscar profesionales por local");
    for (NSDictionary *local in _arrLocalesTmp) {
        dispatch_group_enter(group);
        [self getListaProfesionalesPorLocal:[local objectForKey:@"idLocal"] withCompletionBlock:^{
            dispatch_group_leave(group);
        }];
    }
});    

dispatch_group_notify(group, dispatch_get_main_queue(),^{

    [self setFormularioConsultaCompleto];
});

(Adapted from this answer)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top