ios - 当用户关闭应用程序且任务仍处于事件状态时,NSURLSessionDownloadTask 不会删除文件

标签 ios xcode nsurlsession nsurlsessiondownloadtask

我有一个 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/

相关文章:

ios - 将 nsmutablearray 复制到另一个 viewcontroller 中的另一个 nsmutablearray 正在数组中显示空值

ios - 如何在 swift 4 中添加虚折线?

ios - Alamofire 与 XCode 8 Beta 6 的集成

xcode - 核心数据 - 拒绝删除规则导致错误

crash - NSURLSession崩溃

ios - 我正在构建一个带有 Instagram 集成的 iOS 应用程序。重定向网址应该包含什么?

ios - 重新启动游戏游戏中心

xcode - 在 Xcode 中启用测试覆盖率时,带有条纹的矩形区域是什么意思?

ios - Swift - NSURLSession 恢复后完成操作

iOS Swift 下载许多小文件的最快方式