iOS AFNetworking downloadProgressBlock计算返回负数 [英] iOS AFNetworking downloadProgressBlock calculation returning negative numbers

查看:140
本文介绍了iOS AFNetworking downloadProgressBlock计算返回负数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用AFNetworking下载使用第三方类解析的数据。我曾经多次使用AFNetworking做类似的动作,但出于某种原因,当我调用downloadProgressBlock并进行计算以使用我的进度条时,数字会返回负数。见下文:

I am using AFNetworking to download data that is parsed with a third party class. I have used AFNetworking to do similar actions many times before but for some reason, when I call the downloadProgressBlock and do the calcuation to use with my progress bar, the numbers are returning negative. See below:

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 ,其中正如文档所说

I suspect you'll find the problem is totalBytesExpectedToRead. Specifically, this comes from the NSURLResponse property, expectedContentLength, which as the docs say:


返回值

收件人的预期内容长度,或 NSURLResponseUnknownLength 如果无法确定长度。

The receiver’s expected content length, or NSURLResponseUnknownLength if the length can’t be determined.

讨论

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

Some protocol implementations report the content length as part of the response, but not all protocols guarantee to deliver that amount of data. Clients should be prepared to deal with more or less data.

顺便说一下,这个常量, NSURLResponseUnknownLength ,等于-1,这将解释您的计算值。这就是系统通知你它无法确定响应长度的方式。

By the way, this constant, NSURLResponseUnknownLength, is equal to -1, which would explain your calculated values. This is just the way the system informs you that it was unable to determine the length of the response.

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

So, in the worst case scenario, you'll be getting -1 as a number of bytes expected. Even if it's not -1, it is not entirely reliable (especially an issue if you have written your own server code). Your app must gracefully handle whatever expectedContentLength is reported to your app. Most of the time, if you're getting a non-negative value, you're generally getting a value that can be used effectively for a "percent complete" calculation, but don't rely upon it (e.g. you may receive more bytes or less bytes than expectedContentLength reports). Gracefully handle exceptional values.

例如,在设置我的进度条时,我做了类似的事情:

For example, when setting my progress bar, I've done something like:

CGFloat progress;

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

这给了我一个进度条,如果我有下载,下载进展缓慢到100%良好的预期内容长度值,但在其他方面显示了一个进度条,每下载1,000,000字节从0%进展到100%。后一种情况并不理想,但除非您的服务器报告准确的预期内容长度,否则您无法做很多事情。

This gives me a progress bar that progresses slowly to 100% as the download proceeds if I've got good expected content length value, but otherwise shows me a progress bar that progresses from 0% to 100% for every 1,000,000 bytes downloaded. This latter scenario is not ideal, but there's not a lot you can do unless your server reports an accurate expected content length.

或者,如果您从未获得可靠的 expectedContentLength ,您可以选择使用不确定的进度视图(例如 UIActivityIndi​​catorView )完全避免了这个问题。

Alternatively, if you never get a reliable expectedContentLength, you might choose to use an indeterminate progress view (e.g. UIActivityIndicatorView) which avoids this problem altogether.

最重要的是,成功的进度计算取决于您的服务器是否为预期的字节提供合法值。如果你看 totalBytesExpectedToRead ,我打赌你得到-1,结果看到你好奇的计算进度百分比值。

Bottom line, the successful calculation of progress is contingent upon your server is providing a legitimate value for bytes expected. If you look at totalBytesExpectedToRead, I'd bet you're getting -1, and seeing your curious calculated progress percentage values as a result.

这篇关于iOS AFNetworking downloadProgressBlock计算返回负数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆