TinEye is a cool reverse image search engine. It lets you take an image and search for it on the web, even finding uncropped, expanded, or unwatermarked versions of the image. Sadly, while TinEye provides plugins for both Firefox and Chrome, they don’t provide one for Safari. Because of this, I have written my own extension. Just install it, then right-click on any image and you should see “Search Image on TinEye”. You can get it here.

Comments Comments Off

If you’re like anybody else that I know, you were rather shocked and appalled to see Google follow the likes of Bing and add background images to their home page. If you’re also like anybody else that I know, you’re aware that Safari 5 was released with support for extensions. And if you’re like me, you thought that the new extensions behavior might be a great way to, erm, “fix” Google. Inspired by a tweet from @rentzsch, I decided to figure out how this might be done. I am, of course, not a JavaScript programmer, and Google’s front page code is quite obfuscated, but after playing around with it for a bit over an hour, I got something that worked. Unfortunately it also has the side-effect of blocking the fairly nice fade-in of all the text content, and it’s also a bit fragile, but if you absolutely cannot stand the background image, feel free to download the extension and try it out.

Update: I played around for a few more hours and got something much better. It’s still fragile, but not nearly so much as before, and it restores the fade effect for all the google content. Same download link as before.

Update 2: Looks like Google fixed their homepage sometime this morning, so this extension is now officially obsolete. I will continue to host the download if anybody is interested in the code.

Comments Comments Off

One of the big changes in Snow Leopard is the move to 64-bit applications system-wide. This includes Safari. Unfortunately, this change breaks all of the Safari plugins out there, including mine. There’s two reasons for this. The first is simply that these plugins are all 32-bit binaries, and a 64-bit app cannot load a 32-bit binary. The second, and significantly harder obstacle, is that the entire Input Manager mechanism has been eliminated in 64-bit apps.

Read more to find out how 1Password gets around these limitations.

Read the rest of this entry »

Comments 19 Comments »

If you’ve been following me, you’re aware that I’ve been working at Zynga for the past two weeks. Well, they’re still hiring more people (and not just iPhone developers). You can see the available positions at zynga.com/jobs. If you’re interested in any of them, please contact me and I’ll send your info along to the right person.

Update: Every now and then people keep coming to me and asking me about Zynga. To clarify, I don’t work there any more. I left at the end of 2009.

Comments Comments Off

Last week I pushed out a major rewrite of FontLabel. This new version includes a category modeled after UIStringDrawing that enables you to draw text in custom fonts in your own drawRect: methods. It also includes accurate font metrics and uses more of the built-in UILabel properties. Contributions are welcome!

Comments 2 Comments »

My last iPhone contract app, ExecTweets for iPhone, is now on the App Store. This is the project that drove the creation of FeedParser (an open source Obj-C RSS parser). Anyway, it’s free, and if you like reading about business advice from top business execs, check it out!

Comments Comments Off

This coming monday, I am going to stop being an iPhone contractor and start being a full-time employee of Zynga. While there, I will be working on developing iPhone games.

Comments 2 Comments »

DNS-SD Browser has finally been released on the iTunes AppStore.

DNS-SD Browser is the iPhone version of my popular desktop Bonjour Browser software. It enables you to view all of the Bonjour services on your local network as well as on wide-area Bonjour domains.

Comments Comments Off

In this modern day, HTML entities can reference arbitrary unicode codepoints. For example, ☃ is the entity for ☃. Not surprisingly, WebKit appears uses UTF-16 internally to represent unicode strings, or at the very least when interpreting HTML entities. One of the big benefits of using UTF-16 is every character is represented by 2 bytes (the 16 in UTF-16 means 16 bits). Contrast this with UTF-8, where a single character can be represented by anywhere from 1 to 4 bytes, or UTF-32 where every character requires 4 bytes (i.e. twice as much as UTF-16). Clearly UTF-16 seems to be useful, as it’s not too much larger than UTF-8 for ASCII strings (only double the size), and you can jump to any character with a simple index into the string. However, one of the often-ignored aspects of UTF-16 is the surrogate pair. Unicode contains more than 0xFFFF bytes, and yet a single UTF-16 “character” (or unichar) can only reference up to U+FFFF. The solution to this is to take the codepoints in Unicode planes 1-16 (U+10000 - U+10FFFF) and represent them as 2 unichars. This is a surrogate pair. You can find more information on this in the wikipedia entry for UTF-16, but to put it simply, a surrogate pair uses a range of codepoints that don’t represent real characters (U+D800 - U+DFFF) and uses them in combination to represent all the characters in the other planes.

The reason this is interesting is because it exposes an interesting quirk as to how WebKit interprets HTML entities. WebKit properly converts entities that represent characters outside of plane 0 into a surrogate pair, such as 𝍧 (𝍧). This gets converted into 0xD834DF67. The quirk is if you give it the surrogate pair codepoints directly, it doesn’t realize they’re not real characters individually and passes them through unscathed, so that same character can be written as �� (��). Now this doesn’t seem particularly harmful, except if you only write the first of these entities, WebKit will then get very confused. It will end up throwing away the entire rest of the line of rendered text. Interestingly, it starts displaying text again after a line break, even if it’s just an implicit line break.

The ideal behavior here is WebKit should just silently ignore any entities which reference a codepoint that’s part of a surrogate pair. The fact that it doesn’t really doesn’t hurt anything, but I thought it was worth documenting.

Update: A question was raised on twitter about how surrogate pairs affect indexing into a UTF-16 string. I didn’t know the answer, and strangely, I couldn’t find information on how to handle it with google either, so I tested empirically. NSString uses UTF-16 internally, so it was a great way to test. And what I found was that each half of a surrogate pair is counted as a separate character. The -length of the NSString is increased by 2 when you add a surrogate pair, and -substringFromIndex: will happily split up the surrogate pair for you. Of course, if you do split a surrogate pair, then attempting to convert the NSString into another encoding, even with the simple -UTF8String, will return NULL as such a conversion is illegal (when you generate a unicode stream it has to be well-formed, and so you cannot generate a stream with half of a surrogate pair - and half of a surrogate pair in UTF-16 will be converted into a single invalid 3-byte UTF-8 sequence).

Comments Comments Off

As a PlayStation™ 3 owner and an Apple TV owner, I can’t recommend MediaLink enough. It fills the missing link in my tv/movie-watching habits. Everything in my iTunes library I can watch on my Apple TV, but I have plenty of video files that iTunes can’t handle. Until recently, I’ve been forced to watch them on my computer. But I have an HDTV for a reason, and I’d like to watch my shows there. Nullriver’s MediaLink solves this problem. Anything that I can’t watch on my Apple TV, I can watch on my PS3, and it works flawlessly. I can fast-forward and rewind smoothly, I can jump to any point in the movie (using the PS3’s Go To feature), and it handles everything. Even when my computer lost wifi briefly (the microwave interferes with my desktop’s wifi), the video stream just paused until the wifi came back and then resumed as if nothing happened. If you own a PlayStation™ 3, you should go out and purchase MediaLink right now.

Disclaimer: I have no personal stake in Nullriver or MediaLink, I am simply a happy customer.

Comments Comments Off