2014-05-10 6 views
6

Zmierzyłem się z dziwnym problemem. Załaduję plik z Internetu, używając NSURLSession i NSURLSessionDownloadTask. Oto kodtotalBytesExpectedToWrite jest -1 w 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]; 

Moja klasa jest zadeklarowana jako NSURLSessionDownloadDelegate i uzyskać wywołania zwrotne dobrze. Ale gdy system wywołuje metodę delegata

- (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 zawsze równe -1 i nie mam możliwości, aby pokazać postęp dla użytkownika, ponieważ nie wiem rozmiar pobieranego pliku jest.

Czy możesz mi podpowiedzieć, gdzie popełniłem błąd?

+1

To może być problem serwer gdzie nie jest prawidłowo wysłaniu 'nagłówek Content-Length' . Jeśli używasz tego samego adresu URL w przeglądarce, czy Twoja przeglądarka wyświetla właściwy postęp? – rmaddy

Odpowiedz

10

-1 jest NSURLSessionTransferSizeUnknown, co oznacza, że ​​serwer HTTP nie przewiduje się "Content-Length" nagłówek (a dane są przesyłane za pomocą "Transfer-Encoding: pakietowego").

Prawdopodobnie niewiele można zrobić. Można spróbować, czy obejście od https://stackoverflow.com/a/12599242/1187415 działa w Twoim przypadku, a także:

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

Usługa internetowa nie może być zapewnienie całkowitego rozmiaru w polu nagłówka Content-Length.

Jeśli całkowity rozmiar nie zostanie podany, aplikacja nie będzie znała długości, a to zapewni pasek postępu.

Sprawdź, co dzieje się z serwerem sieciowym za pomocą analizatora takiego jak Charles Proxy.

0

Content-Length może nie być 0 i 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(@"========="); 
} 

Poniżej Wyjście kółko jak zip zostanie pobrany.

ale totalBytesExpectedToWrite: -1

Więc trzeba sprawdzić Content-Length w 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%] 
Powiązane problemy