0

I want to implement a progress bar in my application. The process happening is the app copying a directory into the iOS documents directory. Usually takes anywhere from 7-10 seconds (iPhone 4 tested). My understanding of progress bars is you update the bar as things are happening. But based on the copying of the directory code, I am not sure how to know how far along it is.

Can anyone offer any suggestions or examples on how this can be done? Progress bar code are below and the copying of the directory code.

Thanks!

UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:  UIProgressViewStyleBar];
progressView.progress = 0.75f;
[self.view addSubview: progressView];
[progressView release];


 //Takes 7-10 Seconds. Show progress bar for this code
if (![fileManager fileExistsAtPath:dataPath]) {
    NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
    NSString *imageDataPath = [bundlePath stringByAppendingPathComponent:_dataPath];
    if (imageDataPath) {
        [fileManager copyItemAtPath:imageDataPath toPath_:dataPath error:nil];
    }
}
Teddy13
  • 3,824
  • 11
  • 42
  • 69
  • See this thread: http://stackoverflow.com/questions/10414802/how-to-show-the-progress-of-copying-a-large-file-in-ios – Amit May 06 '13 at 06:12
  • @amit3117 Thanks amit! I am new to objective-c, how can I start separate threads based on the suggestion from the link? Thanks – Teddy13 May 06 '13 at 06:14
  • 1
    Start a timer by calling : [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(targetMethod:) userInfo:nil repeats:YES]; this will give a call back in the targetMethod every o.5 seconds. then you can update progress bar calculating percentage copied in targetMethod as shown in below answers. – Amit May 06 '13 at 06:24

2 Answers2

1

If it takes this long because there are many files in that directory, you could copy the files one by one in a loop. To determine the progress, you could/should simply assume that copying each files takes the same amount of time.

Note that you don't want to block the UI for this 7-10 seconds, so you need to copy on a separate non-main thread. Setting the progress bar, like all UI code, needs to be done on the mean thread using:

dispatch_async(dispatch_get_main_queue(), ^
{
    progressBar.progress = numberCopied / (float)totalCount;
});

The cast to float gives you slightly (depending on number of files) better accuracy, because a pure int division truncates the remainder.

meaning-matters
  • 21,929
  • 10
  • 82
  • 142
1

define NSTimer *timer in your .h file

if (![fileManager fileExistsAtPath:dataPath]) {
    NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
    NSString *imageDataPath = [bundlePath stringByAppendingPathComponent:_dataPath];
    timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(updateProgressView) userInfo:nil repeats:YES];
    [timer fire];  
    if (imageDataPath) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [fileManager copyItemAtPath:imageDataPath toPath_:dataPath error:nil];
        };
    }
}

and add this method

- (void) updateProgressView{
    NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
    NSString *imageDataPath = [bundlePath stringByAppendingPathComponent:_dataPath];
    NSData *allData = [NSData dataWithContentsOfFile:imageDataPath];
    NSData *writtenData = [NSData dataWithContentsOfFile:dataPath];
    float progress = [writtenData length]/(float)[allData length];
    [pro setProgress:progress];
    if (progress == 1.0){
         [timer invalidate];
    }
}
Ushan87
  • 1,608
  • 8
  • 15
  • Thank you! I am getting error for the float *progress. The error is "Initializing float with with an incompatible type of float". Any suggestions? – Teddy13 May 06 '13 at 06:31