AFNetworking 仅在请求成功时下载和保存数据
Posted
技术标签:
【中文标题】AFNetworking 仅在请求成功时下载和保存数据【英文标题】:AFNetworking Download & save data when request is successful only 【发布时间】:2016-02-04 13:10:44 【问题描述】:在我的 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];
虽然,这种方法有问题。如果正在取消下载(强制退出),该文件仍然可以在应用程序目录中找到。如何创建文件下载,仅在下载成功后将文件保存到documents目录?
【问题讨论】:
也许在 completionBlock 中你可以捕捉到 operation.error。如果为 nil,则下载完成。 【参考方案1】:我建议下载将文件保存在临时文件位置,然后在完成块中将生成的临时文件复制到“实时”位置。当应用启动时,临时位置的任何数据都可以被认为是不完整的并被删除
【讨论】:
这听起来像是一种解决方法...也许有更好的方法来处理下载操作? 您唯一的其他选择是不将文件在下载时写入磁盘,但将其保存在内存中。这确实意味着在下载大文件时,您将耗尽所有设备的内存。 @flaxicode 的建议被广泛使用并被普遍接受为一个很好的解决方案。【参考方案2】:使用 Foundation 框架本身的NSUrlSession 将自行处理失败的下载:
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
completionHandler:(void (^)(NSURL *location,
NSURLResponse *response,
NSError *error))completionHandler
你应该只在创建任务时传递一个 nil 完成处理程序 其代表包括 URLSession:downloadTask:didFinishDownloadingToURL: 方法。
您的应用可以通过两种方式获取 resumeData 对象:
如果您的应用通过调用取消现有传输 cancelByProducingResumeData:,会话对象传递一个resumeData 您在该调用中提供的完成处理程序的对象。
如果传输失败,会话对象提供一个 NSError 对象 给它的委托或任务的完成处理程序。在那里面 对象,userInfo 中的 NSURLSessionDownloadTaskResumeData 键 字典包含一个 resumeData 对象。
创建任务后,您必须通过调用它的简历来启动它 方法。
如果请求成功完成,则 完成处理程序块包含临时文件的位置, 并且错误参数为零。如果请求失败,位置 参数为 nil 并且错误参数包含有关 失败。
如果你想为此使用 AFNetworking,它应该是完全兼容的,因为它有 AFURLSessionManager
来处理 NSUrlSession
。
【讨论】:
你说的是按照例子下载:github.com/AFNetworking/AFNetworking? 我说的是一般的文件下载,正如我所说,Apple 已经在他们的框架中处理了您需要的内容,而无需创建临时文件。文档很清楚。以上是关于AFNetworking 仅在请求成功时下载和保存数据的主要内容,如果未能解决你的问题,请参考以下文章
AFNetworking 2.0,使用 CoreData (MagicalRecord) 保存下载状态
AFNetworking 文件下载错误 Error Domain=NSCocoaErrorDomain Code=260