【问题标题】:iOS Background Transfer - com.apple.nsurlsessiond folder full of tmp filesiOS 后台传输 - com.apple.nsurlsessiond 文件夹充满 tmp 文件
【发布时间】:2015-07-03 15:47:54
【问题描述】:

我们编写了一个媒体应用程序,允许您使用背景提取获取最新视频列表作为 json 列表

然后它使用背景传输告诉 iOS 一个接一个地下载视频并返回睡眠并在完成后唤醒应用程序。

它可以做到这一切,但我们注意到空间使用量正在不断增长。

我们添加了清除所有下载视频的代码,但空间使用率在设置中保持不变。

我们使用 Xcode > Organizer> Devices 下载了 app 文件夹,发现 BACKGROUND TRANSFER tmp 文件夹中的 tmp 文件很枯燥。

这些不应该被清除

这通常是我使用的代码。 我认为主要是我将多个下载任务(最多 30 个)附加到一个后台会话。文件的大小从电影到 pdf 不等。

NSURLSession * backgroundSession_ = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];


backgroundSession_ = [NSURLSession sessionWithConfiguration:urlSessionConfigurationBACKGROUND_
                                                   delegate:self
                                              delegateQueue:[NSOperationQueue mainQueue]];

NSOperationQueue *mainQueue_ = [NSOperationQueue mainQueue];



NSURLSessionDownloadTask * downloadTask_ = [backgroundSession_ downloadTaskWithURL:url_];

downloadStarted_ = TRUE;
[downloadTask_ resume];

【问题讨论】:

    标签: ios background-fetch


    【解决方案1】:

    在从didFinishDownloadingToURL返回之前尝试这样的事情:

    // App's Documents directory path
    NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
    
    // Creating the path for the downloaded file
    docsPath = [docsPath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
    
    // Moving the file from temp location to App's Documents directory
    [[NSFileManager defaultManager] moveItemAtPath:location.path toPath:docsPath error:NULL];
    

    documentation 声明您应该“在从此委托方法返回之前将文件移动到应用沙箱容器目录中的永久位置”(可能是 Documents目录)。

    在您从didFinishDownloadingToURL 返回(或下载失败)后清除的临时文件 - 由操作系统自行决定(通常在内存压力下)。

    【讨论】:

      【解决方案2】:

      我有同样的问题,但情况有点不同: 在较旧的设备(iPhone 4S 或更早版本)上,该应用程序通常在操作系统的后台获取期间被终止。可能是为了释放内存。在这种情况下,tmp 文件被保留(并且不被跟踪)。下次应用程序有机会获取时,会创建新文件...并且这个循环一直持续到用户识别出应用程序使用了 4GB 的存储空间 - 并将其删除。

      我还没有找到完美的解决方案 - 即使我将后台配置的 -NSURLSessionConfiguration URLCache 设置为自定义配置(文档说默认情况下它是 nil),路径相同的目录(defaultCacheDir /com.apple.nsurlsessiond/...) 被使用了——但是做了一个清理方法并在我确定没有正在进行的下载时使用它。

      + (BOOL)clearCache:(NSError * __autoreleasing *)error
      {
          __block BOOL successOnLegacyPath = NO;
          __block NSError *errorOnLegacyPath = nil;
      
          NSString *cacheDirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
      
          NSArray *allSubPaths = [[NSFileManager defaultManager] subpathsAtPath:cacheDirPath];
      
          if (!allSubPaths) {
              NSLog(@"No subpaths of cache:\n%@", cacheDirPath);
          } else {
              [allSubPaths enumerateObjectsUsingBlock:^(NSString *subpath, NSUInteger idx, BOOL *stop) {
      static NSString * const kNSURLSessionPathComponent = @"nsurlsession";  // this is a non-documented way, Uncle Apple can change the path at any time
                  if ([subpath containsString:kNSURLSessionPathComponent]) {
                      successOnLegacyPath = [[NSFileManager defaultManager] removeItemAtPath:[cacheDirPath stringByAppendingPathComponent:subpath]
                                                                                       error:&errorOnLegacyPath];
                      if (!successOnLegacyPath) {
                          NSLog(@"Error while deleting cache subpath:\n%@\nError:\n%@", subpath, errorOnLegacyPath);
                      }
                      // First we find is the root > bail out
                      *stop = YES;
                  }
              }];
          }
      
          if (!successOnLegacyPath && !errorOnLegacyPath) {
              // Couldn't find the nsurlsession's cache directory
              if (error) *error = [NSError errorWithDomain:NSCocoaErrorDomain
                                                      code:NSFileNoSuchFileError
                                                  userInfo:nil];
      
              // OR
              successOnLegacyPath = YES;
          }
      
          return successOnLegacyPath;
      }
      

      这不是解决方案,如果没有正在进行的下载,建议使用它。如果正在运行下载并尝试删除 tmp 文件,尚未测试会发生什么。

      即使我找到了解决方案,之前创建的 tmp 文件仍然无法跟踪,因此需要通过这样的方法将其删除。

      顺便说一句,this 似乎是同一个问题 - 没有结论。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-22
        • 2016-01-15
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 2017-12-03
        相关资源
        最近更新 更多