繁体   English   中英

iOS-多个NSURLConnection下载

[英]iOS - multiple NSURLConnection downloads

我正在尝试使用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:完成上一个下载后开始下一个下载,但是我想这并不是最好的下载方式。 有什么建议么?

要进行多次下载,请使用多个NSURLConnection

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

如果要使用NSURLConnection,我建议您创建自己的下载对象,该对象可以包装连接并将其写入磁盘。

您可以使用文件名初始化对象以放入完成的文件,并使用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是一个不错的选择,但请注意,它不再开发。 我怀疑堆栈溢出的其他人会建议可以使用的更好,最新的库。

这是我想出的:

  • 创建一个名为downloadQueue的可变数组
  • 检查您的下载连接当前是否正在运行,如果有,则将其排队
  • 连接结束后,检查队列,如果队列中有成员,请运行队列

实施:(我要标记其中的重要部分,请检查每个步骤以获取其他控件)

作为私人会员;

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

修改您的功能,例如;

- (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...
          }
    }
}

注意:此代码仅用于指定实现的思想,应进行编辑以便使用。 如果您有任何问题,请随时告诉我,我将更新代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM