For quite some time I ranted about not being able to use compressed network communcation out-of-the-box on the iPhone.
Despite being undocumented (or I just overlooked the hint), NSURLConnection does gzip decompression transparently!
That’s how to use it:
- ensure the webserver sends gzipped content, use e.g. wget to verify:
$ wget --header='Accept-Encoding: gzip' \ --server-response http://example.com/demo.xmlz
It should (in case of a gzipped xml document) look like
HTTP/1.1 200 OK ... Content-Type: text/xml Content-Encoding: gzip ...
- If your webserver doesn’t support transparent compression, you can still upload gzipped content and tell the server to send the correct response headers by setting up a
.htaccessfile:... AddType text/xml .xml .xmlz AddEncoding gzip .gz .xmlz # inspired by # http://betterexplained.com/articles/ # how-to-optimize-your-site-with-gzip-compression/ # compress all text & html: AddOutputFilterByType DEFLATE text/html text/plain text/xml ...
- to verify from within your app, log the response header in the NSURLConnection callbacks:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"didReceiveResponse %@: %@", [response URL], [(NSHTTPURLResponse*)response allHeaderFields]); buffer = [[NSMutableData dataWithCapacity:1024*1024] retain]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)dat { [buffer appendData:dat]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"connectionDidFinishLoading %d bytes", [buffer length]); [buffer release]; }
It should look like
2009-06-28 14:31:09.722 DemoApp[3981:20b] \ didReceiveResponse http://example.com/demo.xmlz: { ... "Content-Type" = "text/xml"; "Content-Encoding" = gzip; "Content-Length" = 123042; } ... 2009-06-28 14:31:11.619 DemoApp[3981:20b] \ connectionDidFinishLoading 602979 bytesAs you can see we received way more bytes than went over the wire.
- enjoy lightning fast network communication!
P.S.: It seems not to be necessary setting the request header yourself:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0]; // set explicitly: [request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"]; |
Comments 2
None of this is required. I just did a test, NSMutableURLRequest sets the accept gzip header automatically.
This happens somewhere deep in the framework – all responses are gzipped if the server supports it.
Since it’s set automatically by iOS, I would not set it explicitly either – after all, it’s possible older iOS versions don’t support gzip responses. Just let iOS do it.
Posted 15 Sep 2011 at 9:13 am ¶you’re absolutely right, but relying on default settings can hit you at times.
Posted 16 Sep 2011 at 10:29 am ¶Trackbacks & Pingbacks 1
[...] NSURL and then asking: [request allHTTPHeaderFields] returns an empty dictionary. But I know that for example “Accept-Encoding” is set to “gzip”. So I want to get all [...]
Post a Comment