didReceiveData仅在恢复下载时被调用一次

时间:2013-01-25 08:07:34

标签: download nsurlconnection resume

我有一个问题,我可以帮忙做一些帮助

我正在使用NSURLconnection下载一个大文件(27MB)。没有网络中断时代码工作正常。为了允许网络问题和仅部分下载的文件,我添加了代码以检查下载了多少文件,然后使用服务器请求下载丢失的部分。

代码工作正常,如果我下载文件的一部分,停止程序运行然后再次运行 - 然后下载开始,它停止,我有完整的文件。

但是,如果我第二次点击下载按钮而不停止程序,那么didReceiveData只会被调用一次,只会向文件添加200KB,它会告诉我文件已经成功下载。

请帮助 - 我花了很多年时间试图弄清楚我做错了什么。

以下代码:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;

    NSLog(@"Response code = %d",httpResponse.statusCode );
     file = [NSFileHandle fileHandleForUpdatingAtPath:filename] ;// file is in .h


    if (file)   {
       [file seekToEndOfFile];
    }

}




- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{

    if (file)  {

        [file seekToEndOfFile];
        NSLog(@"file is %@",file);

    }

    [self.file writeData:data];
 }




- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{

    if([[NSFileManager defaultManager] fileExistsAtPath:filename])
    {
       [file closeFile];
        file = nil;
        theConnection = nil;
        filename = nil;
        theRequest = nil;
     }
     NSLog(@"Connection failed! Error - %@ %@",
     [error localizedDescription],
     [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    [file closeFile];
    file = nil;
    theConnection = nil;
    filename = nil;

}


- (IBAction)downloadFile:(id)sender {


    filename = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:movie1]; // filename is in .h file

    theRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:movieDownload1]                                          cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];

    NSUInteger downloadedBytes = 0;
    NSFileManager *fm = [NSFileManager defaultManager];
    if ([fm fileExistsAtPath:filename]) {
        NSError *error = nil;
        NSDictionary *fileDictionary = [fm attributesOfItemAtPath:filename error:&error];
        if (!error && fileDictionary)
        downloadedBytes = [fileDictionary fileSize];
    } else {
        [fm createFileAtPath:filename contents:nil attributes:nil];
    }

    if (downloadedBytes > 0) {
         NSString *requestRange = [NSString stringWithFormat:@"bytes=%d-",downloadedBytes];
        [theRequest setValue:requestRange forHTTPHeaderField:@"Range"];
    }

    theConnection = nil;
    theConnection = [NSURLConnection connectionWithRequest:theRequest delegate:self];

   }

1 个答案:

答案 0 :(得分:0)

您可以尝试以下代码段,而不是在didReceiveResponse和didReceiveData中使用seekToEndOfFile。它对我有用。

- (id)initWithURL:(NSString *)downloadString
{
    if (![super init])
        return nil;

    // Construct the URL to be downloaded
    self.downloadURL = [[NSURL alloc]initWithString:downloadString];
    self.downloadData = [[NSMutableData alloc] init];
    self.downloadedFilename   =   [[self.downloadURL path] lastPathComponent];

    [self downloadFile];

    return self;
}

-(void) downloadFile
{
    // set the filePath
    docFolderPath = [NSHomeDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"Documents/%@", self.downloadedFilename]];

    self.downloadStream = [NSOutputStream outputStreamToFileAtPath:docFolderPath append:NO];

    if (!self.downloadStream)
    {
        self.error = [NSError errorWithDomain:[NSBundle mainBundle].bundleIdentifier
                                         code:-1
                                     userInfo:@{@"message": @"Unable to create      NSOutputStream", @"function" : @(__FUNCTION__), @"path" : self.downloadedFilename}];

        return;
    }
    [self.downloadStream open];

    self.downloadConnection = [[NSURLConnection alloc] initWithRequest:downloadRequest delegate:self];
    [self.downloadConnection start];
}

//code snippet for the Resume functionality after your downloading gets paused/cancel

-(void) resumeInterruptedDownload
{
    NSFileManager *fm = [NSFileManager defaultManager];
    if ([fm fileExistsAtPath:docFolderPath])
    {
        NSError *error = nil;
        NSDictionary *fileDictionary = [fm attributesOfItemAtPath:docFolderPath
                                                            error:&error];
        if (!error && fileDictionary)
            self.downloadedBytes = [fileDictionary fileSize];


    } else
    {
        [fm createFileAtPath:docFolderPath contents:nil attributes:nil];
    }


    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.downloadURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];

    // Define the bytes we wish to download.

    if(self.downloadedBytes != 0)
    {
        NSString *range = [NSString stringWithFormat:@"bytes=%i-", self.downloadedBytes];
        [request setValue:range forHTTPHeaderField:@"Range"];
    }

    // Data should immediately start downloading after the connection is created.

    self.downloadConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:TRUE];
}

对于我来说,对于Mbs中的大文件,它非常适合,但对于Kbs中的小文件,它有时会失败。您不必在NSURLConnection的所有这些委托方法中尝试太多。您可以做的一件事是为每个状态设置宏,即取消,暂停,下载和下载,这样您就可以知道何时需要恢复下载。您也可以尝试以下http://nachbaur.com/blog/resuming-large-downloads-with-nsurlconnection

我知道回复为时已晚,但我刚进入IOS。如果你试试这个,请告诉我它是否有效。谢谢:) :))