2013-01-25 65 views
1

才刚刚调用一次我有一个问题,我真的可以做一些帮助,请didReceiveData就恢复下载

我使用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]; 

    } 

回答

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。如果您尝试此操作,请告知我们它是否有效。谢谢:) :)