2011-08-10 10 views
2

NSHTTPURLResponseオブジェクトにkey @ "Content-Length"が設定されていないのはなぜですか?その鍵を持っていないのはいつものことですか?`[[response allHeaderFields] objectForKey:@" Content-Length "]`はnilですか?

私はDropboxのSDKに何かをしようとしていますし、私は

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

戻りnildownloadProgressが無限であることを引き起こしていることに気付きました:

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

は私が作ることができますどのような方法があります応答にはその鍵がありますか?

ところで:@Mitchellが言ったように

:これは私が

(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; 
} 

EDIT(ワーク・arounded)を取得しています応答です。サーバーは常にそのようなキーを返すわけではありません。 (はい、TXTファイルのため、時にはなしpngのための奇妙なDropboxのサーバ、:/)だから、 は、私が変更したファイルのdownloadProgress(作業-arounded)を計算するために、ソース:

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

、以来、あなたはどちらかのプログレスバーを持たない時々Safariでダウンロードや好みのブラウザをリコールする場合は

- (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

NSDictionaryにプリミティブ型を格納することはできないので、NSNumberのポインタ値からNSInteger contentLengthを割り当てているようです。これをNSNumber *に変更してください。 –

答えて

3

、長さが決定されていません。私は私が行うことができますメタデータからのファイルのサイズを持っています。この特定のケースではローディングスピナーが最高のものです。これは、content-lengthを返すサーバーに完全に依存します。これはオプションです。

正直なところ、その情報が返されていないことはわかりません。おそらくコンテンツ範囲やそれを明らかにしないと決めた他の変数によるものでしょうか。

このプロパティを取得するには、別の場所を参照する必要がありますが、残念ながらすべてのNaNエラーを避けるのではなく、安全にすることをお勧めします。

+0

または、dropBoxディレクトリのインデックスがファイルサイズを表示する必要があるため、理想的にはcontent-lengthを強制しないでください。 –

+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では、 が転送される前にメッセージの長さを判断できるときは必ず を送信する必要があります」*:アプリケーションが送信するデータの量を知ることができない場合があります。は除外されます。これは、たとえばストリーミングメディアに使用されます。 – DarkDust

関連する問題