2011-08-10 17 views
2

我不知道NSHTTPURLResponse對象在什麼條件下沒有key @「Content-Length」?沒有那個鑰匙是否正常/正常?`[[allHeaderFields] objectForKey:@「Content-Length」]`是否爲零?

我試圖與Dropbox的SDK的東西,我已經意識到

[[response allHeaderFields] objectForKey:@"Content-Length"] 

回報nil,並導致downloadProgress是無限的:

NSInteger contentLength = [[[response allHeaderFields] objectForKey:@"Content-Length"] intValue]; 
    downloadProgress = (CGFloat)bytesDownloaded/(CGFloat)contentLength; 

有沒有什麼辦法可以使迴應有那個關鍵?

BTW:這是我得到

(gdb) po [response allHeaderFields] 
{ 
    "Cache-Control" = "max-age=0"; 
    Connection = "keep-alive"; 
    "Content-Encoding" = gzip; 
    "Content-Type" = "text/plain; charset=UTF-16LE"; 
    Date = "Wed, 10 Aug 2011 06:21:43 GMT"; 
    Etag = 228n; 
    Pragma = public; 
    Server = dbws; 
    "Transfer-Encoding" = Identity; 
} 

編輯響應(工作arounded):

正如@Mitchell說。服務器並不總是返回這樣的密鑰。 (奇怪的DropBox的服務器,有時不爲png是,對於TXT文件:/) 因此,爲了計算我修改(工作arounded)的源文件的downloadProgress:

//In DBRequest.m 
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { 
    ... 
    bytesDownloaded += [data length]; 
    //start of modification 
    //Server might not contain @"Content-Length" key, 
    //in that case use the downloadedBytes. Is better 
    //than having an infinite value because it could 
    //be handled by DBRestClient's delegate. (If not 
    //it will have the same effect as infinite) 
    if ([response expectedContentLength] == NSURLResponseUnknownLength) { 
     downloadProgress = (CGFloat)bytesDownloaded; 
    }else{ 
     NSInteger contentLength = [[[response allHeaderFields] objectForKey:@"Content-Length"] intValue]; 
     downloadProgress = (CGFloat)bytesDownloaded/(CGFloat)contentLength; 
    } 
    //end of modification 
    if (downloadProgressSelector) { 
     [target performSelector:downloadProgressSelector withObject:self]; 
    } 
} 

而且,由於我已經從元數據文件的大小,我可以這樣做:

- (void)restClient:(DBRestClient *)client loadProgress:(CGFloat)progress forFile:(NSString *)destPath { 
    if (progress > 1) {//Work-around: This means the progress is not a 
     progress = progress/((CGFloat)(metadataOfTheFile.totalBytes)); 
    } 
    ... update the progress bar here 
} 
+3

從技術文檔,我們可以看到有可能返回NSURLResponseUnknownLength如果長度無法確定的方法expectedContentLength。你嘗試過嗎? –

+0

它也看起來像你從NSNumber的指針值分配NSInteger contentLength,因爲你不能在NSDictionary中存儲基元類型。將其更改爲NSNumber *。 –

回答

3

如果你還記得,有時在Safari下載或您選擇的瀏覽器沒有一個進度條,要麼,長度沒有確定。在這種特殊情況下,加載微調器是最好的展示。它完全取決於服務器返回的內容長度,這是可選的。

我真的不知道爲什麼它沒有返回這個信息,也許是由於內容範圍或其他一些決定不透露它的變量。

你可能不得不在別處尋找那個屬性,但最好的建議是安全的,而不是抱歉,避免所有的NaN錯誤。

+0

理想地強制內容長度,因爲dropBox目錄索引應該顯示文件大小。 –

+0

事實上,服務器可能不會返回該信息。我已經意識到,Dropbox服務器返回「Content-Length」的圖像,但不是文本文件(* .txt),至少與我試圖的文件不同。我已實施瞭解決方法以獲取下載的百分比:) – nacho4d

1

它允許HTTP沒有Content-Length字段,它是可選的。所以,你需要處理:

NSNumber *lengthNumber = [[response allHeaderFields] objectForKey:@"Content-Length"]; 
NSUInteger contentLength = [lengthNumber unsignedIntegerValue]; 
if (contentLength == 0) { 
    // Calculate progress. 
} else { 
    // Can't calculate progress. 
} 
+0

您確定這是正確的嗎? Contentlength應該是非零來計算進度。 –

+0

@Mitchell Currie:請參閱[RFC 2616](http://www.ietf.org/rfc/rfc2616.txt),關於血腥細節的部分4.4或僅用於'Content-Length'字段的部分14.13。關鍵部分是:*「在HTTP中,只要消息的長度可以在 之前被確定,就應該被髮送,」 應該被髮送「*:有時應用程序不知道它將發送多少數據,並且當Content-Length字段被排除在外。這用於例如流媒體。 – DarkDust