首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSURLSessionDownloadTask -下载,但以错误结束

NSURLSessionDownloadTask -下载,但以错误结束
EN

Stack Overflow用户
提问于 2014-03-09 12:29:21
回答 3查看 12.7K关注 0票数 10

我正在尝试下载一个pdf文件。早些时候,当我使用完成处理程序块时,我能够看到tmp位置中的文件。然后我想显示下载进度,所以我实现了委托方法。但我现在可以看到进度条在工作,文件正在下载。但是一旦下载完成(写入的字节数/总字节数= 1),就会调用错误委托,并且在tmp位置中没有文件。我错过了什么?下面是我的代码。我已经在https://www.dropbox.com/s/vn5zwfwx9izq60a/trydownload.zip上载了这个项目

代码语言:javascript
复制
@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:[NSURL URLWithString:@"http://aayudham.com/URLLoadingSystem.pdf"]];
    [downloadTask resume];

}

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    NSLog(@"%@",[error localizedDescription]);
}
-(void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    dispatch_async(dispatch_get_main_queue(), ^{
        _progressBar.progress = (double)totalBytesWritten/(double)totalBytesExpectedToWrite;
        double value =(double)totalBytesWritten/(double)totalBytesExpectedToWrite;
        NSLog(@"%f",value);
    });
}

-(void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{

}

-(void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
       NSError *error;
//getting docs dir path
NSArray * tempArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [tempArray objectAtIndex:0];

//adding folder path
NSString *appDir = [docsDir stringByAppendingPathComponent:@"/Reader/"];

NSFileManager *fileManager = [NSFileManager defaultManager];

if(![fileManager fileExistsAtPath:appDir])
{
    [fileManager createDirectoryAtPath:appDir withIntermediateDirectories:NO attributes:nil error:&error];
}


BOOL fileCopied = [fileManager moveItemAtPath:[location path] toPath:[appDir stringByAppendingString:@"/demo.pdf"] error:&error];

NSLog(fileCopied ? @"Yes" : @"No");
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-09 20:30:12

@Rob感谢你的及时回复,这对我帮助很大。下面是我的代码。希望这能帮助到别人。我能够获得实际的文件名,并使用原始名称将该文件移动到我的文档目录中。

代码语言:javascript
复制
-(void) URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;

    //getting application's document directory path
    NSArray * tempArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docsDir = [tempArray objectAtIndex:0];

    //adding a new folder to the documents directory path
    NSString *appDir = [docsDir stringByAppendingPathComponent:@"/Reader/"];

    //Checking for directory existence and creating if not already exists
    if(![fileManager fileExistsAtPath:appDir])
    {
        [fileManager createDirectoryAtPath:appDir withIntermediateDirectories:NO attributes:nil error:&error];
    }

    //retrieving the filename from the response and appending it again to the path
    //this path "appDir" will be used as the target path 
    appDir =  [appDir stringByAppendingFormat:@"/%@",[[downloadTask response] suggestedFilename]];

    //checking for file existence and deleting if already present.
    if([fileManager fileExistsAtPath:appDir])
    {
        NSLog([fileManager removeItemAtPath:appDir error:&error]?@"deleted":@"not deleted");
    }

    //moving the file from temp location to app's own directory
    BOOL fileCopied = [fileManager moveItemAtPath:[location path] toPath:appDir error:&error];
    NSLog(fileCopied ? @"Yes" : @"No");

}
票数 11
EN

Stack Overflow用户

发布于 2014-03-09 12:56:42

didFinishDownloadingToURL中,您应该将文件从location移动到某个更永久的位置(例如,您的Documents文件夹)。如果您稍后要在临时位置查找该文件,那么它不再存在也就不足为奇了。

正如the documentation所说,location是这样定义的:

临时文件的文件URL。由于该文件是临时文件,因此在从此委托方法返回之前,必须打开该文件以供读取,或者将其移动到应用程序的沙箱容器目录中的永久位置。

didFinishDownloadingToURL返回之前,必须将文件移动到新位置。

票数 7
EN

Stack Overflow用户

发布于 2015-06-23 18:36:00

为了防止有人遇到和我一样的问题,我想我会在这里发布我的解决方案。

我的问题是谓词方法是在后台线程上触发的,所以我将其分派到我的"file io“线程,该线程处理应用程序中的任何文件写入、删除等操作。

这样做的问题是,委托方法一结束,临时文件就会被删除,而这正是我切换线程的时刻。所以当我试图访问我的文件io线程中的文件时,它已经被删除了。

我的解决方案是在委托方法中将文件解析为NSData,然后使用NSData写入我的文件io线程中的文件系统。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22278407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档