我有一个 NSURLSession
和一个 NSURLSessionDownloadTask
配置为在后台下载文件,如果用户取消下载任务,所有数据和存储空间都会被删除正在使用的文件已被释放,但如果应用程序从多任务停靠栏关闭,下载任务将终止并给出错误但不会删除数据并且文件的临时数据仍在占用存储空间并且永远不会被释放。我需要做什么才能释放空间?
这是我的 NSURLSession
配置和错误处理:
- (NSURLSession *)backgroundSession {
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration;
if ([[UIDevice currentDevice].systemVersion hasPrefix:@"7"]) configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.visyon.pr"];
else configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.visyon.pr"];
configuration.sessionSendsLaunchEvents =YES;
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
});
return session; }
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if (error == nil) {
NSLog(@"Task: %@ completed successfully", task );
} else {
// [self hideActivity];
// [self showAlertBoxErrorDownload];
NSLog(@"Task: %@ completed with error: %@, %lu", task, [error localizedDescription], (long)error.code);
} self.downloadTask = nil; }
最佳答案
经过 10 多天的尝试和失败后,我找到了解决方案,首先有两种情况,当用户关闭应用程序并且后台有事件下载时,请考虑到这种情况下载任务永远不会被恢复。
场景 1. 当用户关闭应用程序但仍处于事件状态时,- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
被调用并且用于下载的临时文件直接进入应用程序的临时目录,在这种情况下 - (void)applicationWillTerminate:(UIApplication *)application
被调用但是委托(delegate)下载任务首先被调用。这种情况的解决方案是实现每次打开应用程序时清理临时目录的代码或者让iOS清理临时文件夹,这里解释一下当iOS要清理临时文件时:
When does iOS clean the local app ./tmp directories?
场景 2. 当用户在后台模式下关闭应用程序时,应用程序终止,下次打开应用程序时 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError :(NSError *)error
被调用,用于下载的临时文件存储在下一个目录的 NSCachesDirectory
中:
var/mobile/Containers/Data/Application/CA21-B6E8-3305A39/Library/Caches/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/CFNetworkDownload_M5o8Su.tmp
下次有新的下载时,临时文件将移动到应用程序的临时目录。
这里的解决方案是实现代码,一旦 - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
已启动。
这是从 NSCachesDirectory
中删除临时文件的代码:
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[path stringByAppendingPathComponent:@"/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/"] error:nil];
for (NSString *string in array) {
[[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:[NSString stringWithFormat:@"/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/%@", string]] error:nil];
}
但因为它只适用于这种情况,所以最好实现代码以在每次启动时清理应用程序的临时目录,或者让 iOS 清理临时文件夹,以便它适用于这两种情况。
这里是关于如何清理应用临时目录的代码:
NSString *path = NSTemporaryDirectory();
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
for (NSString *string in array) {
[[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:string] error:nil];
}
关于ios - 当用户关闭应用程序且任务仍处于事件状态时,NSURLSessionDownloadTask 不会删除文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31682514/