Let’s avoid back-to-back Halloween postings (which means, I left this blog unattended for a year) with a little technical update on TubeSock. (To cut to the chase and download the latest TubeSock, click here.)
Almost immediately upon releasing TubeSock 3.0 beta 17 on Friday, I received reports of its total and utter failure. Beta 17 worked fantastic here, so it took me a day to figure out that the problem was only happening on Tiger (10.4), and then another day to figure out the problem.
The problem was (and I mention this primarily so that, if I Google for this same problem in the future, I’ll find the answer!) that some sites send their web pages gzipped. That is to say, when your browser asks a web server for a page, it mentions in an offhand fashion that, if the server might want to compress the page with gzip before sending it, that’s cool with the browser. All modern browsers do this (accept gzipped pages) and some sites take them up on it, because for a really busy site, it can save a boatload in bandwidth charges.
Tiger has a string method, stringWithContentsOfURL:encoding:error: that basically acts like a browser; it goes to the URL you specify and returns a string with the contents of that page. However, Tiger says “hey, gzip is cool with me,” but then when some server has the temerity to actually deliver gzip, it freaks out and returns an empty string with the error 261. At first blush this looks like some kind of encoding error, like the server was sending text in some bizarre unicode code page no one’s ever heard of. If you ask what the string’s NSStringEncoding is, you’ll get a bogus value, and if you try to dig into the error object and figure out what exactly went wrong, you’ll slowly go insane.
The solution (which we actually figured out for TubeSock 1.0 but, since it was fixed in the wondrous Leopard and Cocoa Touch, forgot about) is to grab the page using NSURLConnection. For some reason it properly un-gzips the returned page before doing anything with it, even in Tiger.
So that was the whole problem with beta 17. The solution we employed was to add a category (which is basically an override, making our code run instead of the operating system’s) to stringWithContentsOfURL: which does our little trick instead of using the operating system’s potentially buggy routine.
And that’s how I spent my weekend. How was yours?