`[[response allHeaderFields] objectForKey:@“Content-Length”]`是零?

时间:2011-08-10 06:37:32

标签: iphone objective-c nsurlrequest

我想知道在什么条件下NSHTTPURLResponse对象没有密钥@“Content-Length”?没有那把钥匙通常/正常吗?

我正在尝试使用Dropbox SDK,我意识到了

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

返回nil并导致downloadProgress无限:

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

有什么方法可以让响应有那个键吗?

顺便说一句:这是我得到的回应

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

编辑(以工作为基础):

正如@Mitchell所说。服务器并不总是返回这样的密钥。 (奇怪的DropBox服务器,对于png是,对于txt文件有时没有:/) 所以,为了计算我修改过的文件的downloadProgress(work-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];
    }
}

由于我可以使用元数据中的文件大小:

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

2 个答案:

答案 0 :(得分:3)

如果您记得有时在safari或您选择的浏览器中下载也没有进度条,则不确定长度。在这种特殊情况下,装载旋转器是最好的展示方式。它完全取决于服务器返回的内容长度,这是可选的。

老实说,我不知道为什么它没有返回该信息,也许是因为内容范围或其他变量决定不透露它。

您可能需要寻找其他地方以获取该属性,但最好的建议是安全,而不是抱歉并避免所有NaN错误。

答案 1 :(得分: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.
}