@interface AQBlog : NSBlog @end

Tutorials, musings on programming and ePublishing

Squeeze Me!

Permalink

AQToolkit now contains compression support!

Having seen that some other HTTP request wrapper libraries were using the zLib APIs to compress/decompress NSData objects, I figured this would be useful— if only there weren’t the overhead of having the whole data lump in memory (that 900KB gzip data? Yeah, that gets somewhat bigger at the other end). That approach also wouldn’t work with the HTTP stream approach I’ve been using with AQXMLParser and HTTPMessage.

The result is a pair of input/output stream classes which wrap the gzip compression step. They each act as intermediaries for another stream of the same type, performing compression/decompression as you read/write. Their primary use is with HTTP streams. With CFHTTPMessageRef (and by extension HTTPMessage) you can both get a stream for reading the response data from a call as well as providing an input stream to send content data in the request.

The easiest use is when handling gzipped responses:

  1. Create your HTTPMessage
  2. Set the Accept-Encoding header to ‘gzip’.
  3. Call -inputStream on your message to get a stream.
  4. Pass that stream to AQGzipInputStream’s constructor.
  5. Now just work with the AQGzipInputStream directly (property access will refer to the HTTP stream).

You can also wait for the first data to arrive on the HTTP stream (thus being able to read the response headers) before setting up the Gzip wrapper stream. For sending gzipped data, you have a couple of choices. If you need to know the length of the compressed data beforehand (as you do with HTTP) you can’t just pass the final output stream to AQGzipOutputStream’s constructor. Instead, you’ve got two options:

  • Get a stream to a temp file and use that to initialize your zip output stream. You then an input stream from that temp file as your HTTP body stream.
  • Get a stream to memory, use that to initialize the gzip output stream, and set the resulting NSData as your HTTP request’s body directly.

Depending on the compression level you choose (and whether you’re on the desktop or the iPhone) you may want to choose the temp-file approach when dealing with source data larger than, say, 5MB. And of course, when sending uncompressed data larger than a few lines of XML on the iPhone, you’re already using the body stream support, right?

Well, okay, but you will in future, yes?

Hm. Okay, then.

Comments