0

I am facing an issue making a queue of asynchronous downloads of 3 files.

I would like when I finish to download and saved the first files to start to download the second one then third one ...

For the moment I am using 3 IBAction to download into Documents folder and it work perfectly, but to make it automatically for all files didn“t work.

What is the best way to implement the download queue of this files ? I know i have to had statements on didReceiveData but I need help to make it working.

This is the code I am using :

// Download song 1
- (IBAction)download {

[self performSelector:@selector(downloadmusic) withObject:nil afterDelay:0.0];

}


- (void)downloadmusic
{
self.log = [NSMutableString string];
[self doLog:@"1/13"];

// Retrieve the URL string
int which = [(UISegmentedControl *)self.navigationItem.titleView selectedSegmentIndex];
NSArray *urlArray = [NSArray arrayWithObjects: SONG1_URL, nil];
NSString *urlString = [urlArray objectAtIndex:which];

// Prepare for download
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

// Set up the Download Helper and start download
[DownloadHelper sharedInstance].delegate = self;
[DownloadHelper download:urlString];

}

// Download song 2
- (void)downloadmusic2 
{

self.log = [NSMutableString string];
[self doLog:@"2/13"];

// Retrieve the URL string
int which = [(UISegmentedControl *)self.navigationItem.titleView        selectedSegmentIndex];
NSArray *urlArray = [NSArray arrayWithObjects: SONG2_URL, nil];
NSString *urlString = [urlArray objectAtIndex:which];

// Prepare for download
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

// Set up the Download Helper and start download
[DownloadHelper sharedInstance].delegate = self;
[DownloadHelper download:urlString];


}


// Download song 3
- (void)downloadmusic3 
{

self.log = [NSMutableString string];
[self doLog:@"3/13"];

// Retrieve the URL string
int which = [(UISegmentedControl *)self.navigationItem.titleView selectedSegmentIndex];
NSArray *urlArray = [NSArray arrayWithObjects: SONG3_URL, nil];
NSString *urlString = [urlArray objectAtIndex:which];

// Prepare for download
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

// Set up the Download Helper and start download
[DownloadHelper sharedInstance].delegate = self;
[DownloadHelper download:urlString];


}



- (void) doLog: (NSString *) formatstring, ...
{
va_list arglist;
if (!formatstring) return;
va_start(arglist, formatstring);
NSString *outstring = [[[NSString alloc] initWithFormat:formatstring arguments:arglist] autorelease];
va_end(arglist);
[self.log appendString:outstring];
[self.log appendString:@"\n"];
[textView setText:self.log];
}

- (void) restoreGUI
{
self.navigationItem.rightBarButtonItem = BARBUTTON(@"Get Data", @selector(action:));
if ([[NSFileManager defaultManager] fileExistsAtPath:DEST_PATH])
    self.navigationItem.leftBarButtonItem = BARBUTTON(@"Play", @selector(startPlayback:));  
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
[(UISegmentedControl *)self.navigationItem.titleView setEnabled:YES];
[progress setHidden:YES];

}

- (void) dataDownloadAtPercent: (NSNumber *) aPercent
{
[progress setHidden:NO];
[progress setProgress:[aPercent floatValue]];
}

- (void) dataDownloadFailed: (NSString *) reason
{
[self restoreGUI];
if (reason) [self doLog:@"Download failed: %@", reason];
}

- (void) didReceiveFilename: (NSString *) aName
{
self.savePath = [DEST_PATH stringByAppendingString:aName];


}

- (void) didReceiveData: (NSData *) theData
{
if (![theData writeToFile:self.savePath atomically:YES])
    [self doLog:@"Error writing data to file"];

[theData release];
[self restoreGUI];
[self doLog:@"Download succeeded"];


//[self performSelector:@selector(downloadmusic2) withObject:nil afterDelay:1.0];


    //[self performSelector:@selector(downloadmusic3) withObject:nil afterDelay:1.0];


}
Ben
  • 1,031
  • 3
  • 17
  • 31

1 Answers1

2

From within your controller, create three blocks and copy them to an array, which will serve as your queue. This array will need to be stored as an instance variable so that it can be accessed by later invocations of methods in your controller class. Each of the three blocks should create and execute an NSURLConnection which asynchronously downloads the appropriate file. The delegate of each NSURLConnection can be your controller, and it should implement the -connectionDidFinishLoading: delegate method. From this method, call a method which pops the first block off the queue and executes it.

Then just call the method for the first time to start the process. Obviously there is some edge-case and error handling that you need to provide, but this is the basic idea.

erikprice
  • 6,240
  • 3
  • 30
  • 40