Archive for January, 2010

Just to recap

Sunday, January 31st, 2010

Back in 2006, Valve Software released the trailer for Portal.

Based on that trailer, We Create Stuff created Portal: The Flash Version. The same day they released it, Valve released The Orange Box (Portal being part of it).

The next year, We Create Stuff released the Portal: The Flash Version Map Pack*, which is the levels from Portal: TFV converted to 3D levels in the real Portal.

And then, at E3 a few months later, Microsoft announced “Portal: Still Alive”, which Valve confirmed is Portal plus the Portal: The Flash Version Map Pack.

Representative screenshot.

*I prefer to call it “Portal: The Flash Version: The Portal Version”, but that’s just me.

Ship-It Saturday: Shorten URLs service

Saturday, January 30th, 2010

When posting links on Twitter, your Twitter client will automatically shorten the URLs to make them fit.

There are many, many general shorteners, including TinyURL, Notlong, Metamark, and One of the complaints about these is that they hide the true destination of the link: From the URL alone, you don’t know whether you’re going to be educated, RickRolled, or worse. (TinyURL and both offer a way to preview the link, but that’s not as easy as just looking at the URL.)

To help with this, several non-shortening-related websites have added their own shorteners that use their own domains, particularly for use on their official Twitter accounts or with a built-in post-to-Twitter feature.

The problem is that it’s not always easy to tell what the shortened link will be. Flickr is among the most difficult: Their regular links use decimal numbers, but their shortened links use base-58, which is not a trivial conversion to perform in any programming environment I know how to use. (Not so easy as, say, decimal to octal.) It’s certainly doable, but would require extensive tests to verify that your base-58 numbers match Flickr’s. There’s sample code, but it’s in PHP, so if you’re writing in anything else, that means porting it, which means (again) extensive tests.

So, rather than write my own shortener, it’s much easier to just use Flickr’s: curl the canonical long URL, then scrape the short one out of the body. (Yay for <link rev="canonical">!) I wrote a service to do this.

For Ship-It Saturday, I retooled it. No longer is it just a Flickr shortening service: It now handles YouTube, Amazon, and a few other sites as well. A single service invocation shortens all links to websites that have their own shorteners.

So, here you go: The Shorten URLs service.

Even more works of John Calhoun

Monday, January 25th, 2010

I’ve updated my shrine to the Glypha games with even more cool old stuff:

If you want to play these old games, you’ll need Mini vMac and its dependencies. The newer versions of Glypha (and possibly Glider) may require a later-generation emulator. That’s assuming, of course, that you don’t still have a real, working old Mac.

Deep thanks go to Steve White for contributing a number of the additions. The page would be only half as long without his help.

Blog posts vs. web pages

Monday, January 25th, 2010

Steve Smith says “Stop Blogging”:

I mean it. All of you people are writing fantastic, useful articles about code, methods, and technologies, but you’re putting them in blog posts — a date-based format that encourages us to leave things as they were, historically.

This got me to thinking about the difference between two of the tutorials I’ve published.

The pointers tutorial is a single web page. There’s a date stamp, but it’s way down at the bottom. The ASL series is nine blog posts.

In the three years since the previous version of the pointers tutorial, dozens of people emailed me to tell me about its major errors.

In the two years since I published the last of the ASL series (ignoring approximately a week afterward), nobody has told me of an inaccuracy in any of the posts.

There are a number of possible explanations for the ASL series receiving fewer (that is, no) corrections:

  • That its audience is narrower: Anyone who programs C has to deal with pointers. Only a very few Mac OS X programmers will ever touch ASL.
  • That it is less visible: One of these is linked from my home page and plenty of CS course reading lists (exhibits A, B, C, and D), and was linked for a while from the Wikipedia article on the C programming language; the other is practically unknown to anyone who wasn’t subscribed to my blog at the time.
  • That I’m just that good. (Ha!)
  • That ASL hasn’t changed at all since Leopard. (Ha!)

Smith writes from the perspective of the author and publisher, who must maintain a web page; he says that the author and publisher finds no (or not much of) such obligation for a blog post. I think the difference in my supply of corrections hints at a reader side to this, although, as shown above, my two examples are hardly comparable.

I have been meaning to move the ASL tutorial into a pointers-style web page at some point, although I don’t know when. I may start receiving corrections then, which means I’ll have to spend time to fix them. The flip side to that is that if I leave it as blog posts, I’ll have that time for other things, but the posts will be consigned to periodically-increasing inaccuracy.

I expect to think more about Smith’s suggestion.

There’s also the merit of the word “blog”, which is wearing thin for me.

finder, a command-line tool

Sunday, January 24th, 2010

Today’s Ship-It Saturday is a command-line interface to the Finder.

The two most useful commands are:

  • finder reveal file, which will select the file in a Finder window, and
  • finder update (or updated) file, which will tell the Finder that the file has been updated.

The latter command probably is not too useful anymore, but the command-line tool should work on no less than 10.4, and could probably be recompiled for even older versions of Mac OS X, so you may still have a use for it.

The trilogy is now complete

Saturday, January 23rd, 2010

The third video of last month’s meeting is now up. Here are three easy-to-remember links:


You’ll notice that the third video is not CHLF2009Leaks3.

Unlike the other two, this one features Scott Ellsworth, our organizer, demonstrating the Web Inspector in WebKit. He starts off in Safari, then switches over to Chrome. He also talks about a profiling tool that’s part of Google Web Toolkit called Speed Tracer, although he wasn’t able to finish a demo of it in time for the meeting, so he talks about one of the examples instead.

I don’t think I’ll link these here anymore. If you want to find out about future CocoaHeads Lake Forest videos, subscribe to the CocoaHeads Lake Forest channel on Vimeo.

Lazy Finder

Tuesday, January 19th, 2010

This is an expansion of a reply I wrote to a tweet by Daniel Jalkut. He wrote:

Imagine if the iPhone home screen showed a matrix of “generic” icons before filling in real ones. Mac Finder is a disgrace.

He’s referring to behavior introduced in Snow Leopard: When you visit a folder for the first time in a session, the Finder shows every symbolic link and alias with the kUnknownFSObject icon ( this one ), every application with the generic application icon, every file with the generic document icon, and every folder with the generic folder icon, before displaying the item’s real icon and then its Quick Look thumbnail.

Compare the environment of SpringBoard (on a non-jailbroken device) to that of Finder:

iPhone Mac OS X

Every item is of one kind: Application.

Items are of any of three kinds: File, folder, and bundle. The Finder must handle each kind differently.

Everything is on one iPhone’s worth of flash memory.

Files may be distributed over any number of volumes, local and remote; however, the general case is all files on one hard disk, which is the startup disk.

Because the iPhone doesn’t allow background processes, it’s the only app running, with only a few built-in, light-on-file-system-access exceptions (the heaviest of which is probably Mail).

Any number of applications may be running, and they may be accessing files on the same volume you’re browsing.

Accessing any file in flash memory is as quick as accessing any other file (random access).

Disks are not so predictable: Accessing one file and then another can incur milliseconds of seek time. Doing this repeatedly for dozens or hundreds of files (possibly in multiple Finder windows at different scroll positions) may cause the disk to thrash. You can hope that the OS can put the requests into a favorable order, but you can’t rely on it, and there’s only so much it can do.

Flash memory is always active.

Most users aren’t using flash memory. Hard disks may be spun down to conserve power. If this is the case, the disk will need to be spun up, which can take seconds.

All files (that is, all applications) are local.

Some volumes may be on remote machines, across a local network or the internet; depending on throughput and latency, every access to such a volume can take tenths of a second.

All applications are in one place, making caching of icons or their filenames easy.

Applications aren’t the only user-visible bundles, and any bundle can be anywhere.

Compare also how SpringBoard and Finder obtain icons*:

iPhone Mac OS X

Assuming that the icons themselves aren’t cached:

  1. Look up the application’s icon filename in the bundle’s Info.plist (or a cache of icon filenames).

  2. Load the icon from the indicated file.

(All of this may happen inside NSWorkspace and/or Icon Services.)

  1. If the item is a symbolic link or alias, find the original file. If it still exists, start over with it from this step. If it does not exist, jump to step 7.

  2. Get the item’s custom-icon bit.
  3. If the custom icon bit is set, open the resource fork (or, for folders and bundles, the resource fork of the “Icon\r”** file) and search for icon resources of ID -16455. (This step probably happens in Icon Services.)

    If this step succeeds, we have the icon.

  4. If the item is a bundle, look up the application’s icon filename in the bundle’s Info.plist.

  5. Load the icon from the indicated file.

    If this step succeeds, we have the icon.

  6. Identify the item’s HFS file type (if available) or its filename extension. For bundles, the file type may be in Info.plist. For bundles and packages, the file type and creator may be in a PkgInfo file inside the item, which would be yet another file open+read.

  7. Look up the icon for the file types (probably using Icon Services). For anything but a document of an installed application, this will be a generic icon (such as the generic application icon). If the icon does come from an installed application, it will need to be read from a file inside that application bundle.

SpringBoard hasn’t much to do, it’s in a straightforward environment, and the task and environment provide a couple of obvious caching strategies. The iPhone doesn’t have as much processing power, but what it has is enough—it can just get and display the icon without being lazy about it.

In fact, SpringBoard probably doesn’t even need to be asynchronous about it; all it needs to do is keep three pages of icons (current, next, and previous) in short-term memory. When the user flips one page, drop the farthest page out of the short-term memory cache and load the next one into it.

Meanwhile, on the Mac, getting an icon is not straightforward, and the environment can throw a monkey wrench into the works at any point. Every icon can take dozens, hundreds, or thousands of milliseconds to display, and more icons mean more opportunities for a stall. The solution is to load and show the icons asynchronously and in parallel—but then, what to show in the meantime?

Thus, for the Finder, lazy loading makes sense. The Finder can show you what it has (filenames and other basic metadata) immediately. You can work with those files, scroll to other files, or move through the folder hierarchy without having to wait for icons. And while you do that, the Finder has all the time it needs to asynchronously fetch the icons and, if it’s still appropriate, display them.

It’s a feature, not a bug.

* I’m speculating, since I don’t have the source code to either. These steps are how I would implement each one if I were imitating the current stock behavior.
** “\r” here means, as it does in C, the carriage-return character (U+000D).

CocoaHeads Lake Forest videos

Monday, January 18th, 2010

It’s been in editing for over a month, but now, it’s finally done. I’ve just uploaded the second part of last month’s meeting of CocoaHeads Lake Forest. There’s one more to go from last month, and then I can start posting the video from this month.

This one’s a lot more random than the first one. Portions of my own presentation are only part of what you’ll see in this video.

More long-term, I’ve created a channel on Vimeo for all past and future CocoaHeads LF videos.

The myth of Carbon’s 64-bit unavailability

Monday, January 18th, 2010

There’s a recurring myth going around, which goes something like this:

In fact, using Carbon locks you out of 64 bit.

No, it doesn’t.

The truth is that some APIs that are part of the Carbon sub-frameworks are not available in 64-bit. Merely linking against Carbon does not mean your app suddenly stops working in the 64-bit world.

Carbon itself is just an umbrella framework. It doesn’t have any APIs that it provides immediately; everything comes from either another framework or one of its sub-frameworks.

Examples of the first category include Core Foundation, Core Services (home of Launch Services), and Application Services (home of Core Graphics). Even these are not immune to the myth, as demonstrated by the comment I linked to above: It’s on an answer suggesting a Core Foundation function. The answerer referred to it as a “Carbon function” (true in a sense), and the commenter pounced.

Many things that were once explicitly considered part of Carbon, such as the File Manager and Resource Manager, are now part of Core Services. Note that they haven’t even been consigned to the Legacy Library!

In the other category, even some APIs that remain strongly identified with Carbon, by being in a direct sub-framework of Carbon, are still at least partially around. One of these is the Carbon Event Manager, which even has the word Carbon in its name. Try registering a hot-key with it in a 64-bit-only app—it’ll work. (That one is in the Legacy Library. I should probably file a bug on that.)

What is deprecated and not available in 64-bit, as you can see in the Carbon Event Manager Reference, is anything that you would need to build your application on Carbon. That’s what’s deprecated: the concept of a Carbon application. Only Cocoa apps remain.

But some parts of “Carbon” are useful for things other than building a Carbon application. You can use them from a Cocoa application, or from a command-line tool.

Those APIs are still around. They are not deprecated, they are still useful, and they are still available in 64-bit. Use them freely.

(Oh, and before anybody mentions it: No, those NSEvent class methods introduced in Snow Leopard are not direct replacements for Carbon Event Manager hot-keys. You’d have to sift through the events yourself, whereas Carbon Event Manager filters them for you and only calls your function when your key is pressed. The correct analogue would be CGEventTap.)

Pointers tutorial 1.3

Saturday, January 16th, 2010

At long last, a new version of Everything you need to know about pointers.

The most significant changes are long-overdue corrections regarding declarations of const pointers and the difference between arrays and pointers. You can—and, if you learned how to work with pointers from this tutorial, should—read all of the changes in the delta between 1.2 and 1.3.

Cocoa and Cheesesteaks 2010-01

Wednesday, January 13th, 2010

CocoaHeads Lake Forest is today, the 13th.

I don’t have any Philly’s Best coupons this time, but I could still go for half a cheesesteak. I eat a basic cheesesteak: Provolone, no onions, no other toppings. If you’re up for the other half, raise your hand in the comments, and bring $3 (your half of the price) to the restaurant.

Anyone else will, of course, have to buy their own sandwich.

The place will be the Lake Forest location and the time will be 6 PM—an hour before CocoaHeads.

The iPod Radio Remote and Griffin Navigate

Saturday, January 9th, 2010

Some of you know that I use a second-generation iPod nano (the best iPod ever) with an iPod Radio Remote. There are two generations of iPod Remote; here they are side by side:

iPod Remote and iPod Radio Remote

The original is on the left. It was for the 2G iPod (that’s what I had, anyway) and possibly some other models. That remote didn’t have a radio tuner in it. The one on the right, the one that has a Dock connector and looks like a 2G iPod shuffle, is the iPod Radio Remote.

The iPod Radio Remote never did work with the iPhone and iPod touch. Every introduction of a new iPhone or iPod touch model (including the originals) made clearer that they’d either make a third generation or kill it. Sometime around the time when they introduced the new Apple Remote, they chose the latter.

At some point, Griffin Technology introduced their Navigate. I spotted one today at Walmart for $20 on clearance and snapped it up. Walmart normally sells it for $50, and MSRP is $60.

Not only does the Navigate work with my 1G iPod touch, it adds a display showing the current track. The iPod Radio Remote never had this! The picture on Griffin’s website doesn’t do it justice; it actually looks much better, as shown in this video:

(If you want to really see how good it looks, click through to the YouTube page and watch it there.)

Like the Radio Remote, the Navigate has a clip. Unlike the Radio Remote, it’s not a moving part; it’s just a fixed, flexible (but not too flexible, but not too stiff, either) bit of plastic. Time will tell how easy it is to break.

True to its name, you can even use it to navigate your music: It will let you pick a playlist, artist, or album to listen to, and change the shuffle setting. However, it does not let you go straight to a specific song, which makes that feature useless for me. I understand why that limitation exists, though: It would be much more difficult to scroll to it with the Navigate’s buttons than with the iPod’s own click wheel or touch screen.

Navigating the FM band isn’t exactly easy. When moving along the frequency band itself, next and previous move one frequency-stop at a time. You can set presets, but only four of them. It’s not at all obvious how to set and use them; I’ll leave it to the manual to explain it. Ameliorating this problem is that it remembers the last station you had tuned, so it’s not like you’re going to have to deal with the preset menu every time you turn on the radio.

I do have a couple of significant problems with it.

The first is that it doesn’t remember your volume setting. (The Navigate has its own volume setting, separate from the iPod’s; the iPod’s volume setting has no effect on audio through the Navigate. This is another difference from the Radio Remote, which had no volume of its own.) The Navigate doesn’t have a battery; it relies on the iPod for power, so it goes dead when you unplug it. Then, when you plug it back in or plug it into a different iPod, it’s back to the default volume, which is quite loud for me. This will probably grate on me a bit.

The other problem is that it doesn’t fit in my iPod touch’s Dock connector with its SeeThru hard case on it. My iPod nano doesn’t have a case on it, so I don’t have that problem with that iPod. If you don’t have a case on your iPhone or iPod touch (or other iPod), or you use a different case that won’t conflict with Griffin’s Dock connector, then this won’t be a problem for you.

I hope a future version of the Navigate will remember the volume setting and have a slightly thinner Dock connector so that it isn’t blocked by my iPod touch’s case. Even now, though, I consider the Navigate a worthy successor to the iPod Radio Remote, primarily because of the display, secondarily because of the iPod touch (and iPhone) compatibility.

Application Locator

Friday, January 8th, 2010

This is a little one, inspired by a Growl discussion list thread. Enter the bundle identifier or name of an application, and Application Locator will reveal it in the Finder.

Translate Text 1.0.1

Tuesday, January 5th, 2010

The new version adds a Sparkle public key, which should fix updating. Since updating was broken in all versions before 1.0.1, you’ll need to update manually from the Translate Text web page.

Ship-It Saturday: IconGrabber 2.0.1

Sunday, January 3rd, 2010

The last time I released a version of IconGrabber was only a week after Valve released Half-Life 2—way back in 2004. That game wasn’t even on my radar then, since I couldn’t run it on my PowerPC-based Mac!

Just over five years later, I’ve played all of the Half-Life 2 games and love them, and IconGrabber returns with some bug fixes and support for the new bigger icon sizes introduced in Tiger and Leopard. Version 2.0.1 is available from the IconGrabber home page.

Free music round-up 2009

Friday, January 1st, 2010

At the end of March of last year, I predicted that I would download more than 11,000 free songs in that year.

The final tallies are in.

I downloaded and added 11,466 free songs within 2009. At the stroke of midnight, I was still catching up on my backlog of Chromewaves; once I’d finished, I had a total of 11,554 free songs that had been published in 2009.

Either way, I met my prediction: I downloaded and added more than 11,000 songs, approximately doubling-and-a-half my library from its size at the start of 2009, for free. (I did buy some music as well, easing my conscience.)

I’ve refined my stable of sources over the past year. Here’s my current list of subscriptions:

Naturally, I also download all of the free songs on iTunes and free songs on Amazon every Tuesday.

For those of you who’d like to follow these sources in your feed reader:

File: Music sources.opml.bz2 Music-sources.opml.bz2

An OPML file of all of the RSS feeds of these sources (except iTunes, Amazon, and Spinner). In Vienna, choose “Import Subscriptions” from the File menu.

UPDATE 2010-01-16: Added New Weird Australia to the list.