0

在我的 iOS 应用程序中,我使用AFNetworking库来管理所需的 HTTP 操作。

我创建了一种下载文件的方法:

+ (void)downloadFile:(File *)file progress:(void (^)(NSUInteger receivedBytes, long long totalReceivedBytes, long long totalExpectedBytes))progress success:(void (^)())success failure:(void (^)(NSError *error))failure
{
    NSURLRequest *request = [NSURLRequest requestWithURL:file.url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:[FCFileManager pathForTemporaryDirectoryWithPath:file.key.lastPathComponent] append:NO];

    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead)
    {
        progress(bytesRead, totalBytesExpectedToRead, totalBytesExpectedToRead);
    }];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        success();
    }

    failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        failure(error);
    }];

    [operation start];
}

虽然,这种方法存在问题。如果正在取消下载(强制退出),该文件仍然可以在应用程序目录中找到。如何创建文件下载,仅在下载成功完成后将文件保存到文档目录?

4

2 回答 2

1

我建议下载将文件保存在临时文件位置,然后在完成块中将生成的临时文件复制到“实时”位置。当应用程序启动时,临时位置中的任何数据都可以被认为是不完整的并被删除

于 2016-02-04T13:26:27.260 回答
0

使用Foundation 框架本身的NSUrlSession将自行处理失败的下载:

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
                                   completionHandler:(void (^)(NSURL *location,
                                                               NSURLResponse *response,
                                                               NSError *error))completionHandler

只有在委托包含 URLSession:downloadTask:didFinishDownloadingToURL: 方法的会话中创建任务时,才应传递 nil 完成处理程序。

您的应用可以通过两种方式获取 resumeData 对象:

  • 如果您的应用通过调用 cancelByProducingResumeData: 取消现有传输,则会话对象会将 resumeData 对象传递给您在该调用中提供的完成处理程序。

  • 如果传输失败,会话对象会向其委托或任务的完成处理程序提供一个 NSError 对象。在该对象中,userInfo 字典中的 NSURLSessionDownloadTaskResumeData 键包含一个 resumeData 对象。

创建任务后,您必须通过调用其 resume 方法来启动它。

如果请求成功完成,completion handler 块的 location 参数包含临时文件的位置,error 参数为 nil。如果请求失败,location 参数为 nil,error 参数包含有关失败的信息。

如果你想为此使用 AFNetworking,它应该是完全兼容的,因为它必须AFURLSessionManager处理NSUrlSession.

于 2016-02-04T14:09:22.407 回答