totalBytesExpectedToWrite is -1 in NSURLSessionDownloadTask

后端 未结 3 1007
情深已故
情深已故 2021-01-12 12:34

I faced with a strange problem. I load file from the Internet using NSURLSession and NSURLSessionDownloadTask. Here is the code

NSU         


        
相关标签:
3条回答
  • 2021-01-12 12:57

    The Content-Length can be non 0 and 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(@"=========");
    }
    

    The following is Output over and over as zip is downloaded.

    but totalBytesExpectedToWrite:-1

    So you need to check Content-Length in downloadTask.response

    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%]
    
    0 讨论(0)
  • 2021-01-12 13:05

    The web service may not be providing the total size in the header field Content-Length.

    If the total size is not provided there is no way for your app to know the length and this provide a progress bar.

    Check what is coming from the web server with a analyzer such as Charles Proxy.

    0 讨论(0)
  • 2021-01-12 13:12

    -1 is NSURLSessionTransferSizeUnknown, which means that the http server did not provide a "Content-Length" header (and the data is sent using "Transfer-Encoding: chunked").

    There is probably not much that you can do. You could try if the workaround from https://stackoverflow.com/a/12599242/1187415 works in your case as well:

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:anURL];
    [request addValue:@"" forHTTPHeaderField:@"Accept-Encoding"];
    
    0 讨论(0)
提交回复
热议问题