首页 > 代码库 > iOS客户端的gzip解压

iOS客户端的gzip解压

服务端使用gzip压缩,可以大幅度减小传输包的体积,加快客户端网络请求速度,为用户节省流量。当服务器返回的httpHeader的"Content-Encoding" 属性的值是gzip时,数据会自动被解压缩,但有时候在客户端还没拿到数据的时候,就已经被某些网关解压了,这样gzip就没有起到作用。因此可以约定其他策略,防止网关解压,例如在别的头属性中标记gzip。

如此,就需要我们自己来解压gzip数据。方法如下:添加framework库中的libbz2.1.0.dylib;给nsdata添加方法:

 

- (NSData *)gzipUnpack

{

    if ([self length] == 0) return self;

 

    unsigned full_length = [self length];

    unsigned half_length = [self length] / 2;

 

    NSMutableData *decompressed = [NSMutableData dataWithLength: full_length +     half_length];

    BOOL done = NO;

    int status;

 

    z_stream strm;

    strm.next_in = (Bytef *)[self bytes];

    strm.avail_in = [self length];

    strm.total_out = 0;

    strm.zalloc = Z_NULL;

    strm.zfree = Z_NULL;

 

    if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;

    while (!done){

      if (strm.total_out >= [decompressed length])

      [decompressed increaseLengthBy: half_length];

      strm.next_out = [decompressed mutableBytes] + strm.total_out;

      strm.avail_out = [decompressed length] - strm.total_out;

 

      // Inflate another chunk.

      status = inflate (&strm, Z_SYNC_FLUSH);

      if (status == Z_STREAM_END) done = YES;

      else if (status != Z_OK) break;

    }

    if (inflateEnd (&strm) != Z_OK) return nil;

 

    // Set real length.

    if (done){

    [decompressed setLength: strm.total_out];

    return [NSData dataWithData: decompressed];

    }

    return nil;

}

并引入头文件  #import "zlib.h"

将拿到的data直接调用unPack方法就完成解压了。

如果编译出现link error,就到Target的设置,找到"Other Linker Flags"这一项,添加-lz就可以了。