alockrem
alockrem

Reputation: 767

UIProgressView does not update

If it matters: - I am using storyboards - Core data - xcode 4.6

My app has a UITableViewController for a specific view. On that view, if the user clicks a button the software goes through a few processes where data is downloaded from an Internet API and saved into core data. I'm confident this is a resource hog, which is why I am attempting to complete those processes in separate threads.

Note: - There is an order of operations because legs are dependent on exchanges. Exchanges are dependent on the race and positions. Positions are dependent on the race. Otherwise I would have executed everything asynchronously.

Issues: - This is my first time working with Grand Central Dispatch. I'm not sure I am doing it correctly. - If I comment out the data processing the UIProgressView is visible and updates as expected. With the data processing in place the system seems too bogged down to even display the UIProgressView.

The methods managing the downloads and progress is below.


- (IBAction)downloadNow:(id)sender {

[progressView setHidden:NO];
[progressView setProgress:0.1 animated:YES];

dispatch_sync(backgroundQueue, ^(void){
    [self saveRace];
    [self updateProgress:0.2];
});

dispatch_sync(backgroundQueue, ^(void){
    [self savePositions];
    [self updateProgress:0.3];
});

dispatch_sync(backgroundQueue, ^(void){
    [self downloadExchanges];
    [self saveExchanges];
    [self updateProgress:0.4];
});

dispatch_sync(backgroundQueue, ^(void){
    [self downloadLegs];
    [self saveLegs];
    [self updateProgress:0.5];
});

dispatch_sync(backgroundQueue, ^(void){
    Utilities *utilities = [[Utilities alloc] init];
    [utilities calculateStartTimes:race with:managedObjectContext];
    [self updateProgress:1.0];
});

}

  • (void)updateProgress:(double)completedPercentage { if (completedPercentage == 1.0) { [self goHome]; } else if ([importExchanges count] > 0) { [progressView setProgress:completedPercentage animated:YES]; } }

Any help is greatly appreciated.

Upvotes: 0

Views: 610

Answers (1)

Valent Richie
Valent Richie

Reputation: 5226

The method dispatch_sync will block the calling thread, which I believe in your case is the main thread. So I think it is better to wrap those dispatch_sync blocks into one dispatch_async block.

As an example:

dispatch_async(backgroundQueue, ^(void){
    [self saveRace];
    [self updateProgress:0.2];

    [self savePositions];
    [self updateProgress:0.3];

    [self downloadExchanges];
    [self saveExchanges];
    [self updateProgress:0.4];

    [self downloadLegs];
    [self saveLegs];
    [self updateProgress:0.5];

    Utilities *utilities = [[Utilities alloc] init];
    [utilities calculateStartTimes:race with:managedObjectContext];
    [self updateProgress:1.0];
});

After that you can wrap the updating of the progressView to be done in main thread because it is a UI update.

- (void)updateProgress:(double)completedPercentage {
    if (completedPercentage == 1.0) {
        [self goHome];
    } else if ([importExchanges count] > 0) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [progressView setProgress:completedPercentage animated:YES];
        });
    }
}

Upvotes: 2

Related Questions