【问题标题】:didReceiveData only getting called once on resuming downloaddidReceiveData 仅在恢复下载时被调用一次
【发布时间】:2013-01-25 08:07:33
【问题描述】:

我有一个问题,我真的可以通过一些帮助来解决

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

   }

【问题讨论】:

    标签: download nsurlconnection resume


    【解决方案1】:

    不要在didReceiveResponse和didReceiveData中使用seekToEndOfFile,你可以试试下面的代码sn-p。对我来说效果很好。

    - (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。如果你尝试这个,请让我知道它是否有效。谢谢:) :)

    【讨论】:

      猜你喜欢
      • 2013-09-10
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 2020-12-31
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多