如何跟踪gzip编码的Web内容的下载进度?

时间:2010-08-05 10:21:41

标签: iphone objective-c gzip nsurlconnection

我正在写一个从网上下载内容的iPhone客户端。由于蜂窝网络不是那么快,文件可能很大,我想通过进度条改进活动微调器。

到目前为止,我正在使用NSURLConnection并检查Content-Length标头以查看我将下载多少字节。然后,在-connection:didReceiveData:回调中,我将收到的数据附加到我的NSMutableData对象,在那里我可以跟踪到目前为止下载内容的大小与预期的字节数。

这一切都有效,直到你有一台支持gzip压缩的服务器。使用gzip压缩的服务器将x字节作为内容的大小。但是,由于NSURLConnection在后台进行解压缩,因此传递给didReceiveData回调的数据已经扩展。因此,预期下载的字节小于实际接收的字节,以文件的压缩比例。

这意味着进度条溢出,因为预期的字节数比预期的要早得多。我控制服务器时可以执行的操作是为gzip内容发送特殊标头以避免NSURLConnection进行解压缩,但我无法控制Web上的所有服务器。

NSURLConnection是否有任何隐藏方法来报告传输的字节而不是扩展的字节?我是否必须编写自己的NSURLConnection来跟踪传输的字节并自行解压缩gzip数据以获得准确的进度条指示器?也许还有一个替代的低级Core Foundation API?

2 个答案:

答案 0 :(得分:5)

IIRC,您应该使用-expectedContentLength NSURLResponse方法,在我的测试中,该方法会返回NSURLResponseUnknownLength( - 1)的gzip压缩内容。

一种解决方法是通过手动设置Accept-Encoding标头禁用发送gzip压缩内容:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:yourURL];
[request setValue:@"" forHTTPHeaderField:@"Accept-Encoding"];

但当然,这会破坏内容的压缩性。 :/

(如果有一个更好的解决方案(希望不会涉及低于NSURL*的东西),我也很想知道它...)

答案 1 :(得分:1)

使用ASIHTTPRequest库。这是我对“我如何成为iPhone上的Web客户端”问题的通用答案,但在这种情况下它特别有用。

检查一下:

-(void)viewDidLoad {
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:myNSURLObject];
    request.delegate = self;
    request.downloadProgressDelegate = self.myUIProgressViewInstance; 
      //it'll update that progress bar with a percentage complete automatically!
      //or give it any custom class that responds to -progress!
    [request startAsynchronous];
}

- (void)requestFinished:(ASIHTTPRequest *)request
{
    //do whatever to process the data you just got
}

ASIHTTP使许多强大的网络操作变得非常简单。我是个粉丝。

http://allseeing-i.com/ASIHTTPRequest/