2014-05-10 11 views
6

Tôi gặp phải vấn đề lạ. Tôi tải tệp từ Internet bằng cách sử dụng NSURLSessionNSURLSessionDownloadTask. Đây là mã sốtotalBytesExpectedToWrite là -1 trong NSURLSessionDownloadTask

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]; 

Lớp học của tôi được khai báo là NSURLSessionDownloadDelegate và tôi nhận được cuộc gọi lại tốt. Nhưng khi hệ thống gọi là phương pháp đại biểu

- (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 luôn bằng -1 và tôi không có khả năng hiển thị một tiến trình để sử dụng bởi vì tôi không biết kích thước tập tin tải xuống của.

Bạn có thể nhắc tôi đã nhầm lẫn không?

+1

Nó có thể là một vấn đề máy chủ nơi đó không được gửi 'Content-Length' tiêu đề . Nếu bạn sử dụng cùng một URL trong trình duyệt, trình duyệt của bạn có hiển thị đúng tiến trình không? – rmaddy

Trả lời

10

-1NSURLSessionTransferSizeUnknown, có nghĩa là máy chủ http đã không cung cấp một "Content-Length" tiêu đề (và dữ liệu được gửi bằng "Transfer-Encoding: chunked").

Có thể không có nhiều việc bạn có thể làm. Bạn có thể thử nếu workaround từ https://stackoverflow.com/a/12599242/1187415 làm việc trong trường hợp của bạn cũng như:

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

Các dịch vụ web có thể không được cung cấp tổng kích thước trong lĩnh vực tiêu đề Content-Length.

Nếu tổng kích thước không được cung cấp thì không có cách nào để ứng dụng của bạn biết chiều dài và điều này cung cấp thanh tiến trình.

Kiểm tra những gì đến từ máy chủ web với máy phân tích như Charles Proxy.

0

Các Content-Length có thể phi 0 và 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(@"========="); 
} 

Sau đây là Output hơn và hơn như zip được tải về.

nhưng totalBytesExpectedToWrite: -1

Vì vậy, bạn cần phải kiểm tra Content-Length trong 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%] 
Các vấn đề liên quan