【问题标题】:totalBytesExpectedToWrite is -1 in NSURLSessionDownloadTaskNSURLSessionDownloadTask 中的 totalBytesExpectedToWrite 为 -1
【发布时间】:2014-06-28 10:08:31
【问题描述】:

我遇到了一个奇怪的问题。我使用 NSURLSessionNSURLSessionDownloadTask 从 Internet 加载文件。这是代码

NSURLSessionConfiguration *sessionConfiguration =
[NSURLSessionConfiguration backgroundSessionConfiguration:kSessionId];
self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
                                             delegate:self
                                        delegateQueue:[NSOperationQueue new]];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];
[downloadTask resume];

我的班级被声明为NSURLSessionDownloadDelegate,我得到了很好的回调。但是当系统调用委托方法时

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    NSLog(@"totalBytesExpectedToWrite: %lld", totalBytesExpectedToWrite);
    NSLog(@"%lld", totalBytesWritten);
}

totalBytesExpectedToWrite 总是等于-1,我无法向用户显示进度,因为我不知道下载文件的大小。

你能提示我哪里出错了吗?

【问题讨论】:

  • 这可能是一个服务器问题,它没有正确发送Content-Length 标头。如果您在浏览器中使用相同的 URL,您的浏览器是否显示正确的进度?

标签: ios nsurlsession


【解决方案1】:

-1NSURLSessionTransferSizeUnknown,表示http服务器没有提供 一个“Content-Length”标头(数据使用“Transfer-Encoding: chunked”发送)。

您可能无能为力。如果https://stackoverflow.com/a/12599242/1187415 的解决方法也适用于您的情况,您可以尝试:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:anURL];
[request addValue:@"" forHTTPHeaderField:@"Accept-Encoding"];

【讨论】:

    【解决方案2】:

    Web 服务可能未在标头字段 Content-Length 中提供总大小。

    如果未提供总大小,则您的应用无法知道长度,这会提供一个进度条。

    使用 Charles Proxy 等分析器检查来自 Web 服务器的内容。

    【讨论】:

      【解决方案3】:

      Content-Length 可以是非 0 和 totalBytesExpectedToWrite:-1

      //TRACK PROGRESS - MOVED DOWN as also used in BACKGROUND REFRESH > DOWNLOAD FILE > CALL DELEGATE
      -(void)URLSession:(NSURLSession *)session
           downloadTask:(NSURLSessionDownloadTask *)downloadTask
           didWriteData:(int64_t)bytesWritten
      totalBytesWritten:(int64_t)totalBytesWritten
      totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
      {
          //to see response header
           NSLog(@"downloadTask.response:%@\n", downloadTask.response);
      
      //    { status code: 200, headers {
      //        "Cache-Control" = "no-cache";
      //        "Content-Disposition" = "attachment; filename=Directory.zip";
      //        "Content-Encoding" = gzip;
      //        "Content-Length" = 33666264;
      //        "Content-Type" = "application/octet-stream";
      //        Date = "Tue, 27 Oct 2015 15:50:01 GMT";
      //        Expires = "-1";
      //        Pragma = "no-cache";
      //        Server = "Microsoft-IIS/8.5";
      //        "X-AspNet-Version" = "4.0.30319";
      //        "X-Powered-By" = "ASP.NET";
      //    } }
      
          NSDictionary *responseHeaders = ((NSHTTPURLResponse *)downloadTask.response).allHeaderFields;
          NSString * contentLengthString = responseHeaders[@"Content-Length"];
          double contentLengthDouble = 0.0f;
      
          if (contentLengthString) {
              NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
              NSNumber *contentLengthNumber = [f numberFromString:contentLengthString];
              contentLengthDouble = [contentLengthNumber doubleValue];
          }else{
      
          }
          NSLog(@"contentLengthString:[%@]", contentLengthString);
          //You can get progress her
      
          NSLog(@"bytesWritten:%lld", bytesWritten);
          NSLog(@"totalBytesWritten:%lld", totalBytesWritten);
      
          //DONT USE CAN BE ALWAYS -1 for Gzip
          NSLog(@"totalBytesExpectedToWrite:%lld", totalBytesExpectedToWrite);
      
          //avoid DIV by 0
          if (contentLengthDouble > 0.0) {
              double percentage1 = (totalBytesWritten / contentLengthDouble);
              double percentage = percentage1 * 100.0;
              NSLog(@"PERCENTAGE DOWNLOADED:[%f%%]", percentage);
          }else{
              NSLog(@"PERCENTAGE DOWNLOADED:[contentLengthDouble is 0]");
          }
      
          NSLog(@"=========");
      }
      

      以下是下载 zip 时反复输出的内容。

      但 totalBytesExpectedToWrite:-1

      所以你需要在 downloadTask.response 中检查 Content-Length

      2015-10-27 16:04:18.580 ClarksonsDirectory[89873:15495901] downloadTask.response:<NSHTTPURLResponse: 0x7f9eabaae750> { URL: http://asset10232:50/api/1/dataexport/ios/?lastUpdatedDate=01012014000000 } { status code: 200, headers {
          "Cache-Control" = "no-cache";
          "Content-Disposition" = "attachment; filename=Directory.zip";
          "Content-Encoding" = gzip;
          "Content-Length" = 33666264;
          "Content-Type" = "application/octet-stream";
          Date = "Tue, 27 Oct 2015 16:03:55 GMT";
          Expires = "-1";
          Pragma = "no-cache";
          Server = "Microsoft-IIS/8.5";
          "X-AspNet-Version" = "4.0.30319";
          "X-Powered-By" = "ASP.NET";
      } }
      
       contentLengthString:[33666264]
       bytesWritten:47278
       totalBytesWritten:33606690
       totalBytesExpectedToWrite:-1
       PERCENTAGE DOWNLOADED:[99.823045%]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-08
        • 1970-01-01
        • 2016-11-24
        • 1970-01-01
        • 2014-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多