简体   繁体   English

如何将NSURLConnection与UIProgressView集成?

[英]How to integrate NSURLConnection with UIProgressView?

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. 我创建了一个单独的对象来在后台下载文件,我在确定如何使用正确的值更新UIProgressView对象中的progress属性时遇到了问题。 It's probably something very simple, but I cannot figure it out with Googling around. 这可能是非常简单的事情,但我无法通过谷歌搜索来解决这个问题。

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 resourceData member variable holds the file data as it is being downloaded. 如您所见, resourceData成员变量在下载文件数据时保存文件数据。 The filesize member variable holds the full size of the file, as returned by my web service in its Content-Length header. filesize成员变量保存文件的完整大小,由我的Web服务在其Content-Length标头中返回。

It all works sort of OK, I keep getting the downloaded data with multiple executions of didReceiveData as I should, but when I try to calculate the progress value, no proper value is returned. 这一切都很好,我继续按照我的意愿多次执行didReceiveData下载的数据,但是当我尝试计算进度值时,没有返回正确的值。 See below for a small sample of what I get in my console log: 请参阅下面的示例,了解我在控制台日志中获得的一小部分示例:

content-length: 4687472 bytes
resourceData length: 2904616
filesize: 4687472
float filesize: -1.000000
progress: -2904616.000000

For reference, progressView.progress is a float. 作为参考, progressView.progress是一个浮点数。 filesize is a NSNumber that holds a long long. filesize是一个持有很长时间的NSNumber。 Finally, resourceLength is a NSNumber that holds a NSUInteger. 最后, resourceLength是一个拥有NSUInteger的NSNumber。

What am I missing here? 我在这里错过了什么?

Not sure what I'm missing here, but your filesize being -1 seems to be your problem. 不知道我在这里缺少什么,但你的filesize为-1似乎是你的问题。 The API docs clearly state that expectedContentLength may not be available and that NSURLResponseUnknownLength is returned in these cases. API文档明确指出expectedContentLength可能不可用,并且在这些情况下返回NSURLResponseUnknownLength NSURLResponseUnknownLength is defined as: 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. 您需要处理此问题并显示某种不确定的进度表。

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确实是NSNumber ,则使用%@格式打印它,因为它是一个对象,而不是一个基元:

NSLog(@"filesize: %@", self.filesize);

By using the %d , your are just printing the pointer value of self.filesize. 通过使用%d ,您只需打印self.filesize的指针值。 To print out the actual long long value, use %lli ( %d is only for 32-bit values): 要打印出实际的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,而且除法是正确的。

In your code, filesize appears to be an NSNumber object (!). 在您的代码中,filesize似乎是一个NSNumber对象(!)。 So 所以

NSLog(@"filesize: %d", self.filesize);

and

NSLog(@"content-length: %d bytes", self.filesize);

will likely report something like the address (id) of that object (or something else). 可能会报告类似该对象的地址(id)(或其他内容)。 This is the 这是

filesize: 4687472

you see. 你看。 As pointed out by others, the file size returned by the response is indeed -1, ie, 正如其他人所指出的,响应返回的文件大小确实为-1,即

NSURLResponseUnknownLength

ie, the server did not return the file size. 即,服务器没有返回文件大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM