Jon*_*son 3 ios afnetworking progress-bar afhttprequestoperation
我正在使用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
Run Code Online (Sandbox Code Playgroud)
以下是我的代码:
// 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];
Run Code Online (Sandbox Code Playgroud)
我怀疑你会发现问题所在totalBytesExpectedToRead.具体而言,这来自于NSURLResponse财产,expectedContentLength,其作为文档说:
回报价值
接收方的预期内容长度,或者
NSURLResponseUnknownLength如果长度无法确定.讨论
一些协议实现报告内容长度作为响应的一部分,但并非所有协议都保证提供该数量的数据.客户应该准备好处理更多或更少的数据.
顺便说一下,这个常数NSURLResponseUnknownLength等于-1,这可以解释你的计算值.这只是系统通知您无法确定响应长度的方式.
因此,在最坏的情况下,您将获得-1作为预期的字节数.即使它不是-1,它也不完全可靠(特别是如果你编写了自己的服务器代码就会出现问题).您的应用必须优雅地处理expectedContentLength报告给您的应用的任何内容.大多数情况下,如果你得到一个非负值,你通常得到的值可以有效地用于"完成百分比"计算,但不要依赖它(例如,你可能会收到更多字节或者比expectedContentLength报告少的字节数).优雅地处理特殊的价值观.
例如,在设置我的进度条时,我做了类似的事情:
CGFloat progress;
if (expectedContentLength > 0 && progressContentLength <= expectedContentLength)
progress = (CGFloat) progressContentLength / expectedContentLength;
else
progress = (progressContentLength % 1000000l) / 1000000.0f;
Run Code Online (Sandbox Code Playgroud)
这给了我一个进度条,如果我有一个很好的预期内容长度值,随着下载的进展缓慢进展到100%,但另外显示我进度条从下载的每1,000,000字节的0%进展到100%.后一种情况并不理想,但除非您的服务器报告准确的预期内容长度,否则您无法做很多事情.
或者,如果您从未获得可靠expectedContentLength,您可以选择使用不确定的进度视图(例如UIActivityIndicatorView),这完全避免了这个问题.
最重要的是,成功的进度计算取决于您的服务器是否为预期的字节提供合法值.如果你看一下totalBytesExpectedToRead,我敢打赌你得到-1,结果看到你好奇的计算进度百分比值.
| 归档时间: |
|
| 查看次数: |
3280 次 |
| 最近记录: |