iOS AFNetworking downloadProgressBlock计算返回负数

我正在使用AFNetworking下载与第三方类分析的数据。 我之前使用过AFNetworking多次执行类似的操作,但由于某种原因,当我调用downloadProgressBlock并使用我的进度条进行计算时,数字会返回负值。 见下文:

2013-09-22 16:04:06.036 Portland Police[2228:60b] Download = -31849.000000 2013-09-22 16:04:06.041 Portland Police[2228:60b] Download = -40537.000000 2013-09-22 16:04:06.042 Portland Police[2228:60b] Download = -44881.000000 2013-09-22 16:04:06.044 Portland Police[2228:60b] Download = -53569.000000 2013-09-22 16:04:06.046 Portland Police[2228:60b] Download = -62257.000000 2013-09-22 16:04:06.048 Portland Police[2228:60b] Download = -63705.000000 2013-09-22 16:04:06.085 Portland Police[2228:60b] Download = -70945.000000 2013-09-22 16:04:06.087 Portland Police[2228:60b] Download = -89769.000000 2013-09-22 16:04:06.089 Portland Police[2228:60b] Download = -94113.000000 2013-09-22 16:04:06.100 Portland Police[2228:60b] Download = -98457.000000 2013-09-22 16:04:06.104 Portland Police[2228:60b] Download = -102801.000000 2013-09-22 16:04:06.111 Portland Police[2228:60b] Download = 1.000000 

以下是我的代码:

 // Get the URL we are going to use to parse with AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.portlandonline.com/scripts/911incidents.cfm"]]; NSURLRequest *request = [httpClient requestWithMethod:@"GET" path:nil parameters:nil]; AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"Response = %@", operation); // Empty our calls out [self.originalArray removeAllObjects]; // Initiate our parser MWFeedParser *parser = [[MWFeedParser alloc] init]; parser.delegate = self; [parser startParsingData:responseObject textEncodingName:[operation.response textEncodingName] withCompletionHandler:^(NSError *error, MWFeedParser *parser) { // If theres no error if (!error) { // Return the success block success(operation.request, operation.request.URL, self.calls); } else { // Return the failure block failure(operation.request, operation.request.URL, error); } }]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"AFHTTPRequestOperation Failure: %@", error); // Return our failure block failure(operation.request, operation.request.URL, error); }]; [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { NSLog(@"Download = %f", (float)totalBytesRead / totalBytesExpectedToRead); }]; [operation start]; 

我怀疑你会发现问题是totalBytesExpectedToRead 。 具体来说,这来自NSURLResponse属性expectedContentLength , 正如文档所说 :

返回值

接收者的期望内容长度,或者NSURLResponseUnknownLength如果长度不能确定。

讨论

一些协议实现将内容长度报告为响应的一部分,但并非所有的协议都保证提供这些数据量。 客户应该准备好处理更多或更less的数据。

顺便说一句,这个常量NSURLResponseUnknownLength等于-1,这将解释您的计算值。 这只是系统通知您无法确定响应时间的方式。

所以,在最坏的情况下,你会得到-1作为预期的字节数。 即使它不是-1,也不是完全可靠的(尤其是如果你写了你自己的服务器代码的问题)。 您的应用程序必须优雅地处理任何expectedContentLength的ContentLength报告给您的应用程序。 大多数时候,如果你得到一个非负值,你通常会得到一个可以有效用于“完成百分比”计算的值,但不要依赖它(例如,你可能会收到更多的字节或比expectedContentLength报告更less的字节)。 优雅地处理特殊的价值。

例如,在设置我的进度条时,我做了如下的操作:

 CGFloat progress; if (expectedContentLength > 0 && progressContentLength <= expectedContentLength) progress = (CGFloat) progressContentLength / expectedContentLength; else progress = (progressContentLength % 1000000l) / 1000000.0f; 

这给了我一个进度条,如果我的预期内容长度值很好,下载过程将会缓慢地进行到100%,否则会显示一个进度条,每下载一个1,000,000字节,进度条从0%到100%。 后一种情况并不理想,但除非您的服务器报告准确的预期内容长度,否则您可以做的不多。

另外,如果你从来没有得到一个可靠的expectedContentLength ,你可能会select使用一个不确定的进度视图(例如UIActivityIndicatorView ),这样可以完全避免这个问题。

底线,进展的成功计算取决于您的服务器是否提供预期字节的合法值。 如果您查看totalBytesExpectedToRead ,我敢打赌你会得到-1,并看到你的好奇的计算进度百分比值。