0

my problem is this:

I want to show ProgressView for files downloading.For some reason the ProgressView gradually rises, showing how much file is already downloaded , and just immediately fills up when files are still not downloaded! What do I need to fix or how to implement it?

Here is my source code:

- (IBAction)download:(id)sender {


    // Determile cache file path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    progressSlider.progress = 0.0;

    for (i=0;i<=7;i++) {

        //Updating progressView and progressLabel
        progressLabel.text = [NSString stringWithFormat:@"Загружено: %d из 7",i];
        progressView.progress = (float)i/(float)7;

        NSString *filePath = [NSString stringWithFormat:@"%@/avto-0-%d.html", [paths objectAtIndex:0],i];

        // Download and write to file
        NSString *mustUrl = [NSString stringWithFormat:@"http://www.mosgortrans.org/pass3/shedule.php?type=avto&%@", [listOfAvtoUrl objectAtIndex:i]];
        NSURL *url = [NSURL URLWithString:mustUrl];
        NSData *urlData = [NSData dataWithContentsOfURL:url];


        [urlData writeToFile:filePath atomically:YES];
    }
 }
Pratyusha Terli
  • 2,343
  • 19
  • 31
IlyaKharlamov
  • 479
  • 1
  • 4
  • 10
  • 1
    Two questions: is this done on the main thread? It could be either preventing the main thread from refreshing, or if not done on the main thread, then your call to progress should be dispatched on the main thread. Also, try to use setProgress:animated: instead of simply assigning a value. – Resh32 Nov 22 '12 at 12:42
  • @Resh32 Yes, on the main thread! And how do I send a call for progress on the main thread? – IlyaKharlamov Nov 22 '12 at 12:46
  • @Resh32 setProgress: animated: just at the end of downloading files smoothly moves right to the end, but only after loading all the files! – IlyaKharlamov Nov 22 '12 at 12:48
  • ok, then I modified my answer to do the complete stuff on a background queue, and only call the main queue to refresh the progress view. Try it – Resh32 Nov 22 '12 at 12:50
  • This requires iOS 5 BTW. – Resh32 Nov 22 '12 at 12:50

1 Answers1

2

I think that it is related to threads and how the main thread will refresh the view.

Two cases can occur:

You are on the main thread when calling this method

In such case, you do not allow the main thread to execute refresh routines. Move all this download to a background queue using GCD, and call back the main thread like explained in pt.2.

To put everything in a background queue, you could call:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
        // your download code goes here


    });

Or, You are already on the background thread, then use the following lines to call back to the main thread:

dispatch_async(dispatch_get_main_queue(), ^ {
            progressView.progress = (float)i/(float)7;
        });

Final answer:

- (IBAction)download:(id)sender {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
    // Determile cache file path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    progressSlider.progress = 0.0;

    for (i=0;i<=7;i++) {

        //Updating progressView and progressLabel
        progressLabel.text = [NSString stringWithFormat:@"Загружено: %d из 7",i];
dispatch_async(dispatch_get_main_queue(), ^ {
        progressView.progress = (float)i/(float)7;
});

        NSString *filePath = [NSString stringWithFormat:@"%@/avto-0-%d.html", [paths objectAtIndex:0],i];

        // Download and write to file
        NSString *mustUrl = [NSString stringWithFormat:@"http://www.mosgortrans.org/pass3/shedule.php?type=avto&%@", [listOfAvtoUrl objectAtIndex:i]];
        NSURL *url = [NSURL URLWithString:mustUrl];
        NSData *urlData = [NSData dataWithContentsOfURL:url];


        [urlData writeToFile:filePath atomically:YES];
    }
});
 }
Resh32
  • 6,500
  • 3
  • 32
  • 40