Reputation: 3854
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];
}
}
Upvotes: 0
Views: 1545
Reputation: 1623
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];
}
}
Upvotes: 1
Reputation: 22986
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.
Upvotes: 1