ios 如何将 NSURLConnection 与 UIProgressView 集成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/312796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to integrate NSURLConnection with UIProgressView?
提问by jpm
I'm trying to integrate a NSURLConnection object with UIProgressView, so I can update the user while a file download is happening in the background.
我正在尝试将 NSURLConnection 对象与 UIProgressView 集成,因此我可以在后台进行文件下载时更新用户。
I created a separate object to download the file in the background, and I'm having problems figuring out how to update the progress property in the UIProgressView object with the correct value. It's probably something very simple, but I cannot figure it out with Googling around.
我创建了一个单独的对象来在后台下载文件,但在弄清楚如何使用正确的值更新 UIProgressView 对象中的进度属性时遇到了问题。这可能是非常简单的事情,但我无法通过谷歌搜索弄清楚。
Here's the code that I have:
这是我拥有的代码:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.resourceData setLength:0];
self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
NSLog(@"content-length: %d bytes", self.filesize);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.resourceData appendData:data];
NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]];
NSLog(@"resourceData length: %d", [resourceLength intValue]);
NSLog(@"filesize: %d", self.filesize);
NSLog(@"float filesize: %f", [self.filesize floatValue]);
progressView.progress = [resourceLength floatValue] / [self.filesize floatValue];
NSLog(@"progress: %f", [resourceLength floatValue] / [self.filesize floatValue]);
}
As you can see, the resourceDatamember variable holds the file data as it is being downloaded. The filesizemember variable holds the full size of the file, as returned by my web service in its Content-Length header.
如您所见,resourceData成员变量保存正在下载的文件数据。该文件大小成员变量保存文件的完整尺寸,在其Content-Length头我的web服务返回。
It all works sort of OK, I keep getting the downloaded data with multiple executions of didReceiveDataas I should, but when I try to calculate the progress value, no proper value is returned. See below for a small sample of what I get in my console log:
一切正常,我一直按照我应该的方式通过多次执行didReceiveData来获取下载的数据,但是当我尝试计算进度值时,没有返回正确的值。有关我在控制台日志中获得的内容的小样本,请参见下文:
content-length: 4687472 bytes
resourceData length: 2904616
filesize: 4687472
float filesize: -1.000000
progress: -2904616.000000
For reference, progressView.progressis a float. filesizeis a NSNumber that holds a long long. Finally, resourceLengthis a NSNumber that holds a NSUInteger.
作为参考,progressView.progress是一个浮点数。filesize是一个保存 long long 的 NSNumber。最后,resourceLength是一个保存 NSUInteger 的 NSNumber。
What am I missing here?
我在这里缺少什么?
回答by Dave Dribin
Not sure what I'm missing here, but your filesize
being -1 seems to be your problem. The API docsclearly state that expectedContentLength
may not be available and that NSURLResponseUnknownLength
is returned in these cases. NSURLResponseUnknownLength
is defined as:
不确定我在这里遗漏了什么,但你的filesize
身分 -1 似乎是你的问题。该API文档明确指出,expectedContentLength
可能无法使用,并且NSURLResponseUnknownLength
在这种情况下返回。 NSURLResponseUnknownLength
定义为:
#define NSURLResponseUnknownLength ((long long)-1)
In these cases, you cannot get an accurate progress. You'll need to handle this and display an indeterminate progress meter of some sort.
在这些情况下,您无法获得准确的进度。您需要处理此问题并显示某种不确定的进度表。
回答by Dave Dribin
I think you are printing out the file size wrong. If self.filesize
is indeed an NSNumber
, you print it using the %@
format, because it is an object, not a primitive:
我认为您打印的文件大小错误。如果self.filesize
确实是 an NSNumber
,则使用%@
格式打印它,因为它是一个对象,而不是原始类型:
NSLog(@"filesize: %@", self.filesize);
By using the %d
, your are just printing the pointervalue of self.filesize. To print out the actual long long value, use %lli
(%d
is only for 32-bit values):
通过使用%d
,您只是在打印self.filesize的指针值。要打印出实际的 long long 值,请使用%lli
(%d
仅适用于 32 位值):
NSLog(@"filesize: %lli", [self.filesize longLongValue]);
So your self.filesize is actually-1 and the division is correct.
所以你的 self.filesize实际上是-1 并且划分是正确的。
回答by Christian Fries
In your code, filesize appears to be an NSNumber object (!). So
在您的代码中,文件大小似乎是一个 NSNumber 对象(!)。所以
NSLog(@"filesize: %d", self.filesize);
NSLog(@"filesize: %d", self.filesize);
and
和
NSLog(@"content-length: %d bytes", self.filesize);
NSLog(@"content-length: %d bytes", self.filesize);
will likely report something like the address (id) of that object (or something else). This is the
可能会报告类似于该对象(或其他内容)的地址(id)的内容。这是
filesize: 4687472
filesize: 4687472
you see. As pointed out by others, the file size returned by the response is indeed -1, i.e.,
你看。正如其他人所指出的,响应返回的文件大小确实是-1,即
NSURLResponseUnknownLength
NSURLResponseUnknownLength
i.e., the server did not return the file size.
即,服务器没有返回文件大小。