代码之家  ›  专栏  ›  技术社区  ›  Grzegorz Adam Hankiewicz

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

  •  8
  • Grzegorz Adam Hankiewicz  · 技术社区  · 15 年前

    我正在写一个从网上下载东西的iPhone客户端。由于蜂窝网络速度不太快,文件可能很大,所以我想用一个进度条改进活动微调器。

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

    在您拥有支持gzip压缩的服务器之前,这一切都可以工作。使用gzip压缩的服务器将公布x字节作为内容大小。但是,由于nsurlconnection在后台执行解压缩,因此将数据传递给 didReceiveData 回调已展开。因此,预期下载的字节比实际接收的字节小,占文件压缩比的比例。

    这意味着进度条 溢流 ,因为预期的字节数比预期的要早得多。当我控制服务器时,我可以做的事情是为gzip内容发送特殊的头,以避免nsurlconnection进行解压缩,但我不能控制Web上的所有服务器。

    NSURLConnection是否有隐藏方法来报告传输的字节而不是扩展的字节?我是否需要对自己的nsurlconnection进行编码以跟踪传输的字节,并自己解压缩gzip数据以获得准确的进度条指示器?也许有一个可替代的底层核心基础API?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Wevah    15 年前

    使用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
    }
    

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

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

        2
  •  5
  •   Wevah    15 年前

    IIRC,你应该使用 -expectedContentLength 方法 NSURLResponse ,在我的测试中,它返回 NSURLResponseUnknownLength (-1)对于gzip内容。

    解决方法之一是通过手动设置 Accept-Encoding 页眉:

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

    但是,这当然会破坏gzip内容的要点。:

    (如果有更好的解决方案(希望不包括降低级别) NSURL* 我也很想知道这件事