0

I have found a way to queue JSON parsing operation to wait complete data parse, and this is the code:

- (void)LoadParse { // this method is called by a UIButton

    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:5.0];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        // PARSING SUCCESS CODE
        NSLog(@"operation completed"); <--- END OPERATION
        [self anotherMethod]; <--- CALL METHOD AFTER OPERATION IS FINISHED
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON {
        // PARSING FAILURE CODE
    }];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:operation]; <--- START OPERATION

    // I NEED TO SHOW A SORT OF INDICATOR TO ADVERT USER THAT OPERATION ARE STILL LOADING
    // EXAMPLE: [DejalBezelActivityView activityViewForView:self.view withLabel:@"LOADING..."].showNetworkActivityIndicator = YES;

    [queue waitUntilAllOperationsAreFinished];

}

The queue works perfectly: app waits the end of parsing operation, then it calls anotherMethod. But I need to show a sort of activityView to advert user when there is still loading operation: as u can see I've tried to add it between addOperation and waitUntilAllOperationsAreFinished but I cant see anything. IS IT THE RIGHT WAY? So, where is the RIGHT place to put activityView code to view it Until All Operations Are Finished, or another way to do that trick? Thanks!

SILminore
  • 509
  • 3
  • 10
  • 28
  • Calling `wait` functions is rarely the right way. Mattt discourages it [constantly](http://stackoverflow.com/questions/7969865/can-afnetworking-return-data-synchronously-inside-a-block/7970037#7970037) – Keith Smiley Feb 15 '13 at 17:50
  • Thank you Keith, is there a more correct way to do that (btw my parsing is very very simple)? – SILminore Feb 15 '13 at 17:57
  • I wouldn't worry so much about the simplicity of it it's more of what if you have a slow network connection? Try to put all the code you need to execute after your network connections finish into your success/failure blocks. – Keith Smiley Feb 15 '13 at 18:35

1 Answers1

1

Can use this code

- (void)LoadParse { // this method is called by a UIButton

    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:5.0];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        // PARSING SUCCESS CODE
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON {
        // PARSING FAILURE CODE
    }];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:operation];

    UIActivityIndicatorView *tempSpinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    [self.view addSubview:tempSpinner]; 
    [tempSpinner startAnimating];

    [queue waitUntilAllOperationsAreFinished];

    [tempSpinner stopAnimating]; 
    //release tempSpinner if not using arc using [tempSpinner release];
    [self anotherMethod];
}
  • Check if the code works, If it don't work then you are running your code on main thread and so main thread is blocked until process completes. run the processing code on other thread and then display spinner on the main thread. – Pushpak Narasimhan Feb 15 '13 at 17:00
  • Thank you, Pushpak, I know, main thread is blocked, and unluckly your code show *tempSpinner only AT THE END of the operation parsing, I can see it for an istant, not WHILE parsing operation is loading.. can you provide some code to process on secondary thread? Thanks! – SILminore Feb 15 '13 at 17:04
  • Create a spinner object as property. You can move the processing code to a method "processingMethod" and then start the spinner in the button clicked and then call it by [self performSelectorInBackground:@selector(processingMethod) withObject:nil]; And stop the spinner running on main thread after your process gets completed. – Pushpak Narasimhan Feb 15 '13 at 17:10
  • Ok, Pushpak, this is the solution! I have only a little problem because one of my "processingMethod" has two float values to pass, a sort of `(void)processingMethod :(float )lat :(float )lon` and I cannot use it into `@selector(processingMethod) withObject:nil];`... thanks! – SILminore Feb 15 '13 at 17:25
  • 1
    If so then add it into array and pass the array as argument else make the arguments as properties or class variables and you can access them anywhere within your class :) – Pushpak Narasimhan Feb 15 '13 at 17:27