iOS – 多个NSURLConnection下载

我试图使用NSURLConnection下载一些文件:

 - (void)startDownload { NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; [req addValue:@"Basic XXXXXXXXXXXXXX=" forHTTPHeaderField:@"Authorization"]; connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES]; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response { filepath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:save_name]; [[NSFileManager defaultManager] createFileAtPath:filepath contents:nil attributes:nil]; file = [[NSFileHandle fileHandleForUpdatingAtPath:filepath] retain]; [file seekToEndOfFile]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [file seekToEndOfFile]; [file writeData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection*)connection { [file closeFile]; } 

我的文件是相当大的,所以我必须保存我下载到磁盘的每一块,不能将它们存储在RAM中。 问题是,我如何处理多个下载?

我想在下一个下载完成之后开始下一个下载- (void)connectionDidFinishLoading:但是我想这不是最好的方法。 有什么build议么?

如果你想使用NSURLConnection,我会build议你制作自己的下载对象来封装连接并处理写入磁盘。

你将用一个文件名来初始化你的对象,把完成的文件放进去,并从URL中获取文件,例如:

 MyDownloadObject *o = [[MyDownloadObject alloc] initWithFilename:filename URL:url]; o.delegate = self; 

每个下载对象将处理它自己的NSURLRequest和NSURLConnection,使用几乎相同的代码,在你的问题:)

当它完成后,它会告诉你的视图控制器,它下载(可能通过委托方法,但通知也可以工作)。 然后你可以从委托方法告诉哪个文件已经完成。

 - (void)myDownloadObjectFinishedDownload:(MyDownloadObject *)o { NSLog(@"File from %@ has been stored at %@", o.URL, o.filename); } 

如果您将MyDownloadObject作为NSOperation的子类,那么您可以使用NSOperationQueue来限制并发下载并监视整体进度等。


如果你不介意使用第三方库,那么ASIHTTPRequest是一个不错的select,但是会被警告,它不再被开发。 我怀疑堆栈溢出的其他人会build议更好,更新的库,你可以使用。

对于多个下载,请使用多个NSURLConnection

请注意,在每个委托方法中,您将传递它所引用的连接。 你只需要存储你创build的所有连接(作为属性,或在一个数组,或任何,取决于你的devise)。 然后,在实现connection: didReceiveData: ,可以通过比较(使用== )参数与每个存储的连接来检查哪个连接已经收到了一些数据,并且可以相应地处理这些数据。

这是我想出的:

  • 创build一个名为downloadQueue的可变数组
  • 检查你的下载连接是否正在运行,如果是的话,排队连接
  • 当连接结束时,检查队列,如果队列有成员,则运行队列

实现:(我要标记它的重要部分,请检查每一步的额外控制)

作为私人成员;

 ... @property (nonatomic, retain) NSURLConnection *downloadConnection; @property (nonatomic, retain) NSMutableArray *downloadQueue; ... 

修改你的function,如;

 - (void)startDownload { NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; [req addValue:@"Basic XXXXXXXXXXXXXX=" forHTTPHeaderField:@"Authorization"]; if (self.downloadConnection) { if (!self.downloadQueue) self.downloadQueue = [[NSMutableArray alloc] init]; [self.downloadQueue addObject:request]; return; } // else just run your connection self.downloadConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES]; } - (void)connectionDidFinishLoading:(NSURLConnection*)connection { [file closeFile]; // nil your connection self.downloadConnection = nil; // check the state of your queue [self checkQueue]; } -(void)checkQueue { if (self.downloadQueue) { if (self.downloadQueue.count > 0) { NSURLRequest *queueLastObject = [self.downloadQueue lastObject]; // call the request with downloadConnection and remove it from the queue... } } } 

注意:此代码只是为了指定实现的想法,应该被编辑以便使用。 如果您有任何问题,请告诉我,我会更新代码。