7

我有一个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; }
4

3 回答 3

6

好的,经过10多天的尝试和失败我找到了解决方案,首先有两种情况,用户关闭应用程序并且后台有活动下载,请考虑到这种情况下的下载任务绝不打算恢复。

场景 1. 当用户关闭应用程序但仍处于活动状态时,- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error调用 并且用于下载的临时文件直接进入应用程序的临时目录,在这种情况下- (void)applicationWillTerminate:(UIApplication *)application调用但下载任务的委托被首先调用。解决方案是这种情况下是实现代码每次打开应用程序时清理临时目录或让iOS清理临时文件夹,这里解释iOS何时清理临时文件:

iOS 何时清理本地应用程序 ./tmp 目录?

场景 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

下次有新下载时,临时文件将移动到应用程序的临时目录。

这里的解决方案是实现代码以Caches/com.apple.nsurlsessiond/Downloads/com.xxx.xxx/ 在启动后立即 删除所有临时文件- (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];
}
于 2015-08-04T11:34:16.243 回答
0

第一点是如果您使用后台配置类型配置 nsurlsession。如果用户杀死应用程序,那么这种类型的会话直到运行。第二点,如果要清除空间,则需要停止该会话并手动编写代码以从 tmp 文件夹中删除临时文件。

更改会话配置类型。

于 2015-07-28T17:15:50.647 回答
0

AppDelegate 中有一个名为- (void)applicationWillTerminate:(UIApplication *)application. 您可以尝试[NSURLSessionDownloadTask cancel];从那里拨打电话;或者尝试设置一个标志以指示应用程序在关闭应用程序时正在进行下载,并在下次打开应用程序时删除数据。

于 2015-07-30T22:17:11.977 回答